⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chengxu.txt

📁 51单片机控制的lcd1602显示的温湿度测量
💻 TXT
字号:

//-------------------------------------------------------------------------------------
//函数声明,变量定义
//时间:2006年11月28日
//DS18B20好用程序 条件:11.0592晶振 TMDA 上拉4.7K电阻
//此程序已与2008.02.26完成
//-------------------------------------------------------------------------------------
#include <at89x52.h>
#include <stdio.h>
#include <string.h>

#define uchar unsigned char
#define uint unsigned int



sbit TMDAT=P3^0;	//18b20数据口
char up=35;
char down=10;
bit signx=0;
bit signy=0;
char dqz=10;
uint i,q,w;


#define LCM_RS P3_3 //定义引脚
#define LCM_RW P3_4
#define LCM_E  P3_5
#define LCM_Data P2
#define Busy 0x80 //用于检测LCM状态字中的Busy标识


void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);

//写数据
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
Delay5Ms(); //延时
LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0; 
LCM_E = 0;
LCM_E = 0;
LCM_E = 1; 
}

//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = 0xFF; 
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms(); 
WriteCommandLCM(0x38,0);
Delay5Ms(); 
WriteCommandLCM(0x38,0);
Delay5Ms(); 

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置


}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;

ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
 //P1口流水灯
 void liushuideng(void)
{   
    P1=0X0FD;
    for(i=0;i<=4;i++)
    {P1=P1<<1;
     Delay5Ms();
      //break;
	} 
	  
   

}



//5ms延时
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}

//400ms延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
 void Delay(void)
 { 
	unsigned char TempCycA = 25;
 	unsigned int TempCycB;
 
 	  while(TempCycA--)
	  {	 TempCycB=8000;
	  	 while(TempCycB--);
	  };
 
 }




/***************************************************************************************/

//-------------------------------------------------------------------------------------
//函数名称:dmsec
//入口参数:count
//函数功能:延时子程序
//-------------------------------------------------------------------------------------
void dmsec(uint count)
{
 uint i;

 while(count--)
 {
  for(i=0;i<125;i++){}
 }
}

//-------------------------------------------------------------------------------------
//函数名称:tmreset
//入口参数:无
//函数功能:
//-------------------------------------------------------------------------------------
void tmreset(void)
{
 uint i;

 TMDAT=0;
 i=103;while(i>0) i--;    //大约900us
 TMDAT=1;
 i=4;while(i>0) i--;

}
//-------------------------------------------------------------------------------------
//函数名称:tmpre
//入口参数:无
//函数功能:等待DS18B20应答
//-------------------------------------------------------------------------------------
void tmpre(void)
{
 uint i;

 while(TMDAT);
 while(~TMDAT);
 i=4;while(i>0) i--;
}
//-------------------------------------------------------------------------------------
//函数名称:tmrbit
//入口参数:无
//返回值: dat
//函数功能:在总线上读一位
//-------------------------------------------------------------------------------------
bit tmrbit(void)
{
 uint i;
 bit dat;

 TMDAT=0;i++;
 TMDAT=1;i++;i++;
 dat=TMDAT;
 i=8;while(i>0) i--;
 return(dat);
}
//-------------------------------------------------------------------------------------
//函数名称:tmrbyte
//入口参数:无
//返回值:  dat
//函数功能:读一个字节
//-------------------------------------------------------------------------------------
uchar tmrbyte(void)
{
 uchar i,j,dat;
 dat=0;

 for(i=1;i<=8;i++)
 {
  j=tmrbit();
  dat=(j<<7)|(dat>>1);
 }
 return(dat);
}
//-------------------------------------------------------------------------------------
//函数名称:tmwbyte
//入口参数:dat
//函数功能:写命令
//-------------------------------------------------------------------------------------
void tmwbyte(uchar dat)
{
 uint i;
 uchar j;
 bit testb;

 for(j=1;j<=8;j++)
 {
  testb=dat&0x01;
  dat=dat>>1;

  if(testb)
  {
   TMDAT=0;           //写1
   i++;i++;
   TMDAT=1;
   i=8;while(i>0) i--;
  }
  else
  {
   TMDAT=0;        //写0
   i=8;while(i>0) i--;
   TMDAT=1;
   i++;i++;
  }
 }
}
//-------------------------------------------------------------------------------------
//函数名称:tmstart
//入口参数:无
//函数功能:开始转换
//-------------------------------------------------------------------------------------
void tmstart(void)
{
 tmreset();
 tmpre();
 dmsec(1);
 tmwbyte(0xcc);
 tmwbyte(0x44);
}



bit  xiaoshudian=0;
//-------------------------------------------------------------------------------------
//函数名称:tmrbyte
//入口参数:无
//函数功能:读取温度值
//-------------------------------------------------------------------------------------
uchar tmrtemp(void)
{
  uchar a,b,y1,y2,y3;

  tmreset();
  tmpre();
  dmsec(1);
  tmwbyte(0xcc);
  tmwbyte(0xbe);
  a=tmrbyte();
  b=tmrbyte();
  
  if( (a & 0x08)==0x08)
     xiaoshudian=1;
  else
     xiaoshudian=0;
  
  y1=a>>4;
  y2=b<<4;

  y3=y1|y2;
  return(y3);
}

void  delay_1ms(unsigned  int i)
{
 unsigned  char   he;
 while(i--)
 {
 for(he=0;he<125;he++);
 }

}

/*********          串口设置部分   *******/
uchar   get_data=0;

/*******************************
函数名称:seriel_ino()
函数功能:串口初始化
具体设置:使用定时器T1,方式二,自动装载,
          串口方式三,波特率9600;不倍频
参数使用:无
********************************/
void  seriel_init()
{
   TMOD=0x20;	   //定时器1方式二,自动装载
   TH1=0XFD;
   TL0=0XFD;	   //波特率9600
   TR1=0;          //发送的时候执1 ,开始启动定时器1
   SCON=0X50;      //方式1
//接受初始化
   EA=1;
   TR1=1;
   ES=1;//允许接受中断

}


/*******************************
函数名称:send(uchar  hh)
函数功能:串口发送
具体设置:

入口参数: 要发送的数据
参数使用:无
********************************/

void send(unsigned char one_shuju)
{
  TR1=1;  //打开定时器1,准备发送数据
  SCON=0x40;//串口不允许接收,发送过程禁止中断
  ES=0;     //关串口中断
  SBUF=one_shuju;
  while(!TI)//等待发送完成
  {}
  TI=0;
  SCON=0x50;//每次发送串口完成后就回到可以接收状态
  ES=1;	 //开串口中断,允许接收中断
}
	
/*********-------------以上是串口发送和接收, 系统计时-----------------------********/

//参数设置
  uchar last=0;	  //存储温度



/******************************************************************** 

 函 数 名:bcd_8bit(unsigned  char  k)
 功    能:当前时间,温度
 说    明:
 调    用:
 调用参数:
 返 回 值:无
 设    计:loushaofeng          日    期:2008-02-26
 修    改:                     日    期: 
**************************************************************/
void   bcd_8bit(unsigned  char last)
{
  send((last/10)*16+last%10);
}



uchar  kao=0;
/******************************************************************** 

 函 数 名:chuankou_disp()
 功    能:当前温度
 说    明:
 调    用:send_one(realy_time[i]); 
***********************************************************************/
void  chuankou_disp()
{
	 uchar gao=0,di=0;
      //获取温度值

	 kao++;
     tmstart();
     last=tmrtemp();
	 if(kao>10)
	 {
        if((last>up)||(last==up&&xiaoshudian==1))
	      P1_6=0;
	    else
	      P1_6=1;
	    if(last<down)
	      P1_7=0;
	    else
	      P1_7=1;

        bcd_8bit(last);
	    gao=last/10;
	    di=last%10;
        DisplayOneChar(3, 0, gao+'0');
        DisplayOneChar(4, 0, di+'0');

		if(xiaoshudian==1)
		{
        DisplayOneChar(5, 0, '.');
		DisplayOneChar(6, 0, '5');		
		}   
		else
		{
        DisplayOneChar(5, 0, '.');
		DisplayOneChar(6, 0, '0');			
		}    


	 }
	 if(kao==200)
	   kao=20;
}




/***************************  18b20+串口结束      ********************************************/

uchar  xx=0;
uchar  yy=0;
/****************** 键y盘部分 ********************/
void  jianpan()
{
	// begin:
   if((!P0_0) | (!P0_1) | (!P0_2) | (!P0_3) | (!P0_4))
   {
      delay_1ms(20);	//防止键盘抖动
      if((!P0_0) | (!P0_1) | (!P0_2) | (!P0_3) | (!P0_4))
	  {
	  	  if(!P0_0)
          {	  
		      xx=xx+1;
			  if(xx==1)
			     signx=1;
				 P1_0=0;
			  if(xx==2)
			  {  signx=0;
			     xx=0;
			  	P1_0=1;
			   }
		 	 
		  }
		  if(signx)
		  {
		     if(!P0_1)
			 {	
			    up++;
				 P1_1=0;
				if(up>125)
				  up=125;
				DisplayOneChar(3, 1, (up/10)+'0');
				DisplayOneChar(4, 1, (up%10)+'0');
			 }
			  P1_1=1;
			 
		     if(!P0_2)
			 {
			    up--;
				P1_2=0;
				if(up<-55)
				  up=-55;
				DisplayOneChar(3, 1, (up/10)+'0');
				DisplayOneChar(4, 1, (up%10)+'0');
			 }	
			   P1_2=1;	  
		     if(!P0_3)
			 {
			    down++;
				 P1_3=0;
				if(down>125)
				  down=125;
				DisplayOneChar(12, 1, (down/10)+'0');
				DisplayOneChar(13, 1, (down%10)+'0');
			 }	
			    P1_3=1;	  
		     if(!P0_4)
			 {
			 	down--;
				 P1_4=0;
				if(down<-55)
				  down=-55;
				DisplayOneChar(12, 1, (down/10)+'0');
				DisplayOneChar(13, 1, (down%10)+'0');
			 
			 }	 P1_4=1;
		 	

			
			
           }	 		   
//

	  
if(!P0_4)
 {//if(!P0_3)
   yy=yy+1 ;
   if(yy==1)
    signy=1;
    P1_4=0;
    if(yy==2)
       {signy=0;
        yy=0;
        P1_4=1;
       }
 }
  if(signy)
   {
  if(!P0_3)
   {dqz++;
    P1_3=0;
   DisplayOneChar(12, 0, (dqz/10)+'0');
   DisplayOneChar(13, 0, (dqz%10)+'0');
	


   }P1_3=1;
if(!P0_2)
{dqz--;
 P1_2=0;
 DisplayOneChar(12, 0, (dqz/10)+'0');
 DisplayOneChar(13, 0, (dqz%10)+'0');
}P1_2=1;
 
 if(!P0_1)
 	{ 
	  if(dqz>15)
	    {  for(q=0;q<12;q++)
	           {dqz--;
		       DisplayOneChar(12, 0, (dqz/10)+'0');
	           DisplayOneChar(13, 0, (dqz%10)+'0');
		       liushuideng();
		       Delay5Ms();
			  
			   }
		      P1=0X0FF; 
		} 

	  
	  if(dqz<5)
	   {   for(w=0;w<13;w++)
	      {   dqz++;
	   	      DisplayOneChar(12, 0, (dqz/10)+'0');
	          DisplayOneChar(13, 0, (dqz%10)+'0');
	          liushuideng();
	           Delay5Ms();
			   
	   		  }
	   }   P1=0x0FF;
	   if(5<dqz<15)
		{ DisplayOneChar(12, 0, (dqz/10)+'0');
	      DisplayOneChar(13, 0, (dqz%10)+'0');
		} P1_0=1;
	
	}  //goto begin;
 
 
 
 	}
 
 
 
 
 
 
 
  
	  }  
   }
}


 





/****************** 键盘部分END ********************/

/***************************************************************************************/


unsigned char code bysj_net[] = {"BIYESHEJI"};
unsigned char code chushihua_net[] = {"louyukongzhiqisj"};
unsigned char code wd_net[] = {"wd:"};	//从第三个开始显示温度值
unsigned char code sd_net[] = {"sd:"};
unsigned char code up_level[] = {"up:"};
unsigned char code down_level[] = {"down:"};

void main(void)
{ 
Delay400Ms(); //启动等待,等LCM讲入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻(可不要)

DisplayListChar(3,0,bysj_net);
DisplayListChar(0,1,chushihua_net);
Delay();
//WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏

//LCMInit();

DisplayListChar(0, 0, wd_net);
DisplayListChar(9, 0, sd_net);
DisplayListChar(0, 1, up_level);
DisplayListChar(7, 1, down_level);


DisplayOneChar(3, 1, (up/10)+'0');
DisplayOneChar(4, 1, (up%10)+'0');
DisplayOneChar(12, 1, (down/10)+'0');
DisplayOneChar(13, 1, (down%10)+'0');



DisplayOneChar(12, 0, (dqz/10)+'0');
DisplayOneChar(13, 0, (dqz%10)+'0');
DisplayOneChar(14, 0,'%' );
seriel_init();


  while(1)
  {
//串口显示 
   chuankou_disp();
   jianpan();
   delay_1ms(80);

  }
}



 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -