#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忙狀態(tài) */ /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數(shù)據(jù) */ /* */ /*************************************************************/ bit lcd_busy() { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN = 0; return(result); } /*******************************************************************/ /* */ /*寫指令數(shù)據(jù)到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; } /*******************************************************************/ /* */ /*寫顯示數(shù)據(jù)到LCD */ /*RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。 */ /* */ /*******************************************************************/ 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初始化設(shè)定 */ /* */ /*************************************************************/ void lcd_init() { delay(15); lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數(shù)據(jù) delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x0C); //顯示開,關(guān)光標 delay(5); lcd_wcmd(0x06); //移動光標 delay(5); lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容 delay(5); } /*************************************************************/ /* */ /* 設(shè)定顯示位置 */ /* */ /*************************************************************/ void lcd_pos(uchar pos) { lcd_wcmd(pos | 0x80); //數(shù)據(jù)指針=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) //轉(zhuǎn)換為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()/*讀數(shù)據(jù)*/ { 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)/*寫數(shù)據(jù)*/ {unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; } } read_temp()/*讀取溫度值并轉(zhuǎn)換*/ {uchar a,b; ds1820rst(); ds1820wr(0xcc);//*跳過讀序列號*/ ds1820wr(0x44);//*啟動溫度轉(zhuǎn)換*/ 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位小數(shù) return(tvalue); } /*******************************************************************/ void ds1820disp()//溫度值顯示 { uchar flagdat; disdata[0]=tvalue/1000+0x30;//百位數(shù) disdata[1]=tvalue%1000/100+0x30;//十位數(shù) disdata[2]=tvalue%100/10+0x30;//個位數(shù) disdata[3]=tvalue%10+0x30;//小數(shù)位 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);//顯示小數(shù)點 lcd_pos(9); lcd_wdat(disdata[3]);//顯示小數(shù)位 } /*************蜂鳴器*********************************/ 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); //設(shè)置顯示位置為第一行的第1個字符 m = 0; while(cdis1[m] != '\0') { //顯示字符 lcd_wdat(cdis1[m]); m++; } lcd_pos(0x40); //設(shè)置顯示位置為第二行第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); } } } }
|