#include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int uchar buf1; uchar buf2; uchar buf3; uchar tt; uchar n=0; //键顺序吗 uchar dis_buf; //显示缓存 uchar temp; uchar key; uchar enter; void delay0(uchar x); //x*0.14MS sbit LCD_RW = P2^5; sbit LCD_RS = P2^6; sbit LCD_EN = P2^7; sbit DQ=P3^7; sbit RQ=P1^5; uchar data disdata[5]; uint tvalue;//温度值 uchar tflag;//温度正负标志 uchar cdis1[16] = {"T: C "}; uchar cdis2[16] = {"H: C L: C "}; uchar cdis3[16]; #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; /*************************************************************/ /* */ /* 延时子程序 */ /* */ /*************************************************************/ void delay(uchar x) { uchar j; while((x--)!=0) { for(j=0;j<125;j++) {;} } } /*************************************************************/ /* */ /*检查LCD忙状态 */ /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据 */ /* */ /*************************************************************/ bit lcd_busy() { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN = 0; return(result); } /*******************************************************************/ /* */ /*写指令数据到LCD */ /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ /* */ /*******************************************************************/ void lcd_wcmd(uchar cmd) { while(lcd_busy()); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /*******************************************************************/ /* */ /*写显示数据到LCD */ /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ /* */ /*******************************************************************/ void lcd_wdat(uchar dat) { while(lcd_busy()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /*************************************************************/ /* */ /* LCD初始化设定 */ /* */ /*************************************************************/ void lcd_init() { delay(15); lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x0C); //显示开,关光标 delay(5); lcd_wcmd(0x06); //移动光标 delay(5); lcd_wcmd(0x01); //清除LCD的显示内容 delay(5); } /*************************************************************/ /* */ /* 设定显示位置 */ /* */ /*************************************************************/ void lcd_pos(uchar pos) { lcd_wcmd(pos | 0x80); //数据指针=80+地址变量 } /*************************************************************/ /* */ /* 键扫描子程序 (4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行 */ /* P1.1 P1.2 P1.3为列 */ /* */ /*************************************************************/ void keyscan(void) { P1=0xF0; //高四位输入 行为高电平 列为低电平 delay(1); temp=P1; //读P1口 temp=temp&0xF0; //屏蔽低四位 temp=~((temp>>4)|0xF0); if(temp==1) // p1.4 被拉低 key=0; else if(temp==2) // p1.5 被拉低 key=1; else if(temp==4) // p1.6 被拉低 key=2; else if(temp==8) key=0; P1=0x0F; //低四位输入 列为高电平 行为低电平 delay(1); temp=P1; //读P1口 temp=temp&0x0F; temp=~(temp|0xF0); if(temp==1) // p1.1 被拉低 key=key+0; else if(temp==2) // p1.2 被拉低 key=key+2; else if(temp==4) // p1.3 被拉低 key=key+4; else if(temp==8) key=key+8; dis_buf = key; //键值入显示缓存 if(dis_buf>9) //转换为ASCII码 dis_buf = dis_buf+0x37; else dis_buf = dis_buf+0x30; } /*************************************************************/ /* */ /*判断键是否按下 */ /* */ /*************************************************************/ void keydown(void) { P1=0xF0; if(P1!=0xF0) //判断按键是否按下 如果按钮按下 会拉低P1其中的一个端口 { delay(10); if(P1!=0xF0) { keyscan(); P1=0xF0; while(P1!=0xF0); if(dis_buf=='A') enter=1; if(enter==0) { if(n==4) n=0; if(dis_buf!='B') { cdis3[n]=dis_buf; n++; } } if(dis_buf=='B') enter=0; } } } /******************************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; 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(); 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 {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;//正温度不显示符号 else flagdat=0x2d;//负温度显示负号:- if(disdata[0]==0x30) {disdata[0]=0x20;//如果百位为0,不显示 if(disdata[1]==0x30) {disdata[1]=0x20;//如果百位为0,十位为0也不显示 } } lcd_pos(5); lcd_wdat(flagdat);//显示符号位 lcd_pos(6); lcd_wdat(disdata[1]);//显示十位 lcd_pos(7); lcd_wdat(disdata[2]);//显示个位 lcd_pos(8); lcd_wdat(0x2e);//显示小数点 lcd_pos(9); lcd_wdat(disdata[3]);//显示小数位 } /*************蜂鸣器*********************************/ void fengming1(uchar tt) { if(tt!=1) { tt--; RQ=1; delay(100); RQ=0; delay(100); } } void fengming2(uchar tt) { if(tt!=1) { tt--; RQ=1; delay(1000); RQ=0; delay(1000); } } /*************************************************************/ /* */ /* 主程序 */ /* */ /*************************************************************/ main() { uchar m; enter=0; P0=0xFF; //置P0口 P1=0xFF; //置P1口 delay(10); //延时 lcd_init(); //初始化LCD lcd_pos(0); //设置显示位置为第一行的第1个字符 m = 0; while(cdis1[m] != '\0') { //显示字符 lcd_wdat(cdis1[m]); m++; } lcd_pos(0x40); //设置显示位置为第二行第1个字符 m = 0; while(cdis2[m] != '\0') { lcd_wdat(cdis2[m]); //显示字符 m++; } dis_buf = 0x2d; //显示字符"-" while(1) { read_temp();//读取温度 ds1820disp();//显示 keydown(); lcd_pos(0x43); for(m=0;m<2;m++) { lcd_wdat(cdis3[m]); } lcd_pos(0x4d); for(m=2;m<4;m++) { lcd_wdat(cdis3[m]); } if(enter==1) { buf1=cdis3[0]*10+cdis3[1]; buf2=cdis3[2]*10+cdis3[3]; buf3=disdata[1]*10+disdata[2]; if(buf1 < buf3) {fengming1(100); } if(buf2 > buf3) {fengming2(100); } } } }
|