请下载支持!
莈羈虿芄蚆薇蕿//液晶显示温度
蝿膃肆螅荿肃羃#include \
#define Ddata P0
sbit RS=P2^7; //命令数据控制端 sbit RW=P2^6; //读写选择端 sbit LCDE=P2^5; //液晶使能端
sbit DQ=P2^0; //ds18b20与单片机连接口
芃薃羅膀膃螄蒇#define uchar unsigned char
#define uint unsigned int 莅膅蚈莂莂蚇芇unsigned char hour=0,min=0,sec=0; //定义初值
unsigned int count=0;
unsigned char line1[16]={\\ //16个字符 unsigned char line2[16]={\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 请下载支持! 薆螈膁肄肈莇肁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=0 肀芄莅艿羀薅羇RW=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); delay5ms(); busycheck(); delay50us(); wr_com(0x38); delay50us(); busycheck(); delay50us(); wr_com(0x0c); delay50us(); busycheck(); delay50us(); ///***清屏**** ///****光标移动设置,写一个字符后地址指针加1*** ////***显示模式设置**** /////***显示开,不显示光标*** 请下载支持! wr_com(0x40); //set cgram address delay50us(); delay50us(); //***这些延时可用可不用***// } 莀蕿莂蒆罿葿蚃 void display() { unsigned char i; wr_com(0x80); //set ram address delay50us(); 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]); //display delay50us(); 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); //精确延时大于480us DQ = 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]=tvalue00/100+0x30;//十位数 disdata[2]=tvalue0/10+0x30;//个位数 disdata[3]=tvalue+0x30;//小数位 if(tflag==0) flagdat=0x20;//正温度不显示符号 else flagdat=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)%6; init(); 请下载支持! while(1) { read_temp();//读取温度 ds1820disp();//显示 time(); //时间程序 display();//时间显示程序 } } void t0(void)interrupt 1 using 0 { TH0=(65536-4995)/256; TL0=(65536-4995)%6; 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];line2[14]=tab[sec/10]; line2[12]=tab[min];line2[11]=tab[min/10]; line2[9]=tab[hour];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;}}} }
基于51单片机的1602液晶显示温度和时间的C程序



