当前位置:文档之家› 基于51单片机的1602液晶显示温度和时间的C程序

基于51单片机的1602液晶显示温度和时间的C程序

//液晶显示温度#include "AT89X52.H"#define Ddata P0sbit RS=P2^7; //命令数据控制端sbit RW=P2^6; //读写选择端sbit LCDE=P2^5; //液晶使能端sbit DQ=P2^0; //ds18b20与单片机连接口#define uchar unsigned char#define uint unsigned intunsigned char hour=0,min=0,sec=0; //定义初值unsigned int count=0;unsigned char line1[16]={" temp: "}; //16个字符unsigned char line2[16]={" time: 00:00:00"}; //16个字符unsigned char tab[]={'0','1','2','3','4','5','6','7','8','9'}; //数组uchar data disdata[5];uint tvalue; //温度值uchar tflag; //温度正负标志void time();/*************************lcd1602程序**************************/ void delay1ms(unsigned int ms)//延时1毫秒(不够精确的){unsigned int i,j;for(i=0;i<ms;i++)for(j=0;j<110;j++);}void delay5ms()//延时5毫秒(不够精确的){unsigned int i;for (i=0;i<1000;i++);}void delay50us(){register int i;for (i=0;i<20;i++);}void delay(){unsigned char m,n;for(m=255;m>0;m--)for(n=255;n>0;n--);}void wr_com(unsigned char comm) //********写控制字符程序E=1 RS=0RW=0 **********//{LCDE=0; //使能端RS=0; //********RS寄存器选择输入端,当RS=0;当进行写模块操作,指向指令寄存器。

RW=0; //********当RS=1,无论是读操作还是写操作,都是指向数据寄存器。

LCDE=1;Ddata=comm;RS=0;RW=0;LCDE=0;void wr_data(unsigned char dat)//*****当前位置写字符子程序:E=1 RS=1 RW=0{LCDE=0;RS=0; //********RS寄存器选择输入端,当RS=0;当进行写模块操作,指向指令寄存器。

RW=0; //********当RS=1,无论是读操作还是写操作,都是指向数据寄存器。

RS=1;RW=0;LCDE=1;Ddata=dat; //将dat赋给P0口LCDE=0;RS=0;RW=0;}unsigned char busycheck()//*****忙状态检查*******//{unsigned char i;LCDE=0;RS=0;RW=0;RS=0;RW=1;LCDE=1;i=Ddata;LCDE=0;return(i);}void init()//**********初始化程序,必须按照产品的资料介绍的过程进行********// {wr_com(0x38); //*****显示模式设置必须三次,不用检测忙信号delay5ms();wr_com(0x38);delay5ms();wr_com(0x38);delay5ms();wr_com(0x01); ///***清屏****delay5ms();busycheck();wr_com(0x08);delay5ms();busycheck();delay5ms();wr_com(0x06); ///****光标移动设置,写一个字符后地址指针加1***delay5ms();busycheck();delay50us();wr_com(0x38); ////***显示模式设置****delay50us();busycheck();delay50us();wr_com(0x0c); /////***显示开,不显示光标***delay50us();busycheck();delay50us();wr_com(0x40); //set cgram addressdelay50us();delay50us(); //***这些延时可用可不用***// }void display(){ unsigned char i;wr_com(0x80); //set ram addressdelay50us();busycheck();delay50us();for(i=0;i<6;i++){wr_data(line1[i]); //display(6个字符)delay50us();busycheck();}busycheck();delay50us();wr_com(0xc0); //0xc0=0x80+0x40 delay50us();busycheck();delay50us();for(i=0;i<16;i++){wr_data(line2[i]); //displaydelay50us();busycheck();}}/******************************温度传感器ds1820程序***************************************/void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst()/*ds1820复位*/{ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd()/*读数据*/{ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--) //读一个字节的数据函数{ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80; //等价于 dat = dat | 0x80,dat和0x80做“或”的运算,结果是最高位置1,其它位保持不变。

delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata)/*写数据*/{unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1; //右移一位}}read_temp()/*读取温度值并转换*/{uchar a,b;ds1820rst(); //ds1802/初始化程序ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0x44);//*启动温度转换*/ds1820rst();ds1820wr(0xcc);//*跳过读序列号*/ds1820wr(0xbe);//*读取温度*/a=ds1820rd(); //读低八位b=ds1820rd(); //读高八位tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else //“&” 是逻辑与“|” 是逻辑或if(dat & 0x01):不管dat是什么数和0x01(00000001)做了“与”的运算后,最低位保持不变,其它位均为0.如果dat的最低位为1,则表达式为真,就会执行if语句中的内容。

如果dat最低位为0,则表达式为假,不执行if语句,执行if语句后的下一条语句。

dat |= 0x80:等价于dat = dat | 0x80,dat和0x80做“或”的运算,意思是最高位置1,其它位保持不变。

具体的可以去参考一下C语言的相关语法。

{tvalue=~tvalue+1;tflag=1;}tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数return(tvalue);}/***************************************************** **************/void ds1820disp()//温度值显示{ uchar flagdat;disdata[0]=tvalue/1000+0x30;//百位数disdata[1]=tvalue%1000/100+0x30;//十位数disdata[2]=tvalue%100/10+0x30;//个位数disdata[3]=tvalue%10+0x30;//小数位if(tflag==0)flagdat=0x20;//正温度不显示符号elseflagdat=0x2d;//负温度显示负号:-if(disdata[0]==0x30){disdata[0]=0x20;//如果百位为0,不显示if(disdata[1]==0x30){disdata[1]=0x20;//如果百位为0,十位为0也不显示}}wr_com(0x88);wr_data(flagdat);//显示符号位wr_com(0x89);wr_data(disdata[0]);//显示百位wr_com(0x8a);wr_data(disdata[1]);//显示十位wr_com(0x8b);wr_data(disdata[2]);//显示个位wr_com(0x8c);wr_data(0x2e);//显示小数点wr_com(0x8d);wr_data(disdata[3]);//显示小数位}void main(){TMOD=0X01;EA=1;ET0=1;TR0=1;TH0=(65536-4995)/256;TL0=(65536-4995)%256;init();while(1){read_temp();//读取温度ds1820disp();//显示time(); //时间程序display();//时间显示程序}}void t0(void)interrupt 1 using 0{TH0=(65536-4995)/256;TL0=(65536-4995)%256;count++;if(count==200){count=0;sec++;}if(sec==60){sec=0;min++;}if(min==60){min=0;hour++;}if(hour==24){hour=0;}}void time(){line2[15]=tab[sec%10];line2[14]=tab[sec/10];line2[12]=tab[min%10];line2[11]=tab[min/10];line2[9]=tab[hour%10];line2[8]=tab[hour/10];if(!P1_2){delay();if(!P1_2){delay();sec++;if(sec==60){sec=0;}}}if(!P1_1){delay();if(!P1_1){delay();min++;if(min==60){min=0;}}}if(!P1_0){delay();if(!P1_0){delay();hour++;if(hour==24){hour=0;}}} }。

相关主题