|
- #include<reg52.h>
- #include<math.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit lcden=P2^0;
- sbit lcdrw=P2^1;
- sbit lcdrs=P2^2;
- sbit DQ = P2^3;
- sbit s1=P1^0;
- sbit s2=P1^1;
- sbit s3=P1^2;
- sbit D1=P3^4;
- sbit D2=P3^5;
- uchar num,fig,s1num,figh,figl,t,temp_value;
- char h,l;
- void delay(uint z);
- void init();
- void write_com(uchar com);
- void write_data(uchar date);
- void keyscan();
- void write_hl(uchar add,char date);
- void write_temp_value(uchar add,char date);
- void delay_18B20(unsigned int i);
- void Init_DS18B20(void);
- unsigned char ReadOneChar(void);
- void WriteOneChar(uchar dat);
- void ReadTemp(void);
- void comp();
- void string(uchar ad,uchar *s);
- void main()
- {
- init();
- Init_DS18B20();
- while(1)
- { if(s1==0||s1num>=1)
- { keyscan();
- }
- else{ ReadTemp();
- write_temp_value(0,temp_value);
- }
- comp();
- }
- }
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void string(uchar ad,uchar *s)
- {
- write_com(ad);
- while(*s>0)
- {
- write_data(*s++);
- delay(100);
- }
- }
- void init() //LCD初始化程序
- { lcden=0;
- lcdrw=0;
- write_com(0x38); //設置16x2 顯示5x7 點陣,8 位數據接口
- write_com(0x0c); //設置開始顯示不顯示光標
- write_com(0x06); //寫一個字符后地址指針加1
- write_com(0x01); //顯示清零數據指針清零
- write_com(0x80); //將數據指針第一行第一個字處,
-
- write_com(0x89); //定義當前指針位置
- string(0x89,"H:+28.6");
- write_com(0x80+9+0x40); //定義當前指針位置
- string(0x80+9+0x40,"L:+15.3");
- h=28.6; //h=+20
- l=15.3; //l=+10
- D1=1;
- D2=1;
- figh=0; //給正確初始值,便于上電比較
- figl=1; //給正確初始值,便于上電比較
- }
- void write_com(uchar com) //寫命令程序
- { lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_data(uchar date) //寫數據程序
- { lcdrs=1; //設置為寫入數據
- P0=date; //將數據賦給P0 口
- delay(5); //延時
- lcden=1; //打開LCD使能,輸入一個高脈沖
- delay(5); //延時
- lcden=0; //置低完成高脈沖
- }
- void write_temp_value(uchar add,char date) //讀取的溫度值在LCD上顯示程序
- { uchar bai,shi,ge,min;
- bai=date*10/1000;
- shi=date*10/100%10;
- ge=date*10/10%10;
- min=date*10%10; //分離出百,十,個位數
- if((bai|shi|ge)==0) //如果百十都等于0
- shi=0x70; //十賦值0x70,以便十位寫入空字符,write_data(0x30+shi),參考1602字符圖形碼
- if(bai==0)
- bai=0x70;
- write_com(0x80+add); //設置當前光標位置,準備寫數據
-
- if(fig==0&&shi!=0x70) //如果溫度為負且十位不等于0(如果十位等于0,shi=0x70)
- { write_data('-'); //在百位寫入負號
- write_data(0x40+shi); //寫入十位數據
- }
- if(fig==0&&shi==0x70) //如果溫度為負且百十位都等于0
- { write_data(0x30+0x70); //在百位寫入一個空字符
- write_data('-'); //在十位寫入負號
- }
- if(fig==1)write_data(0x30+bai); //溫度正,寫入百位數據
- if(fig==1)write_data(0x30+shi); //溫度正,寫入十位數據
- if(fig==1)write_data(0x30+ge); //寫入個位數據
- write_data('.');
- write_data(0x30+min); //寫小數點
- write_data(0xdf); //寫入°
- write_data('C'); //寫入C
-
- }
- void write_hl(uchar add,char date) //設置的高低溫度值在LCD上顯示程序
- { uchar bai,shi,ge,min;
- bai=date/1000;
- shi=date/100%10;
- ge=date/10%10;
- min=date%10; //分離出百,十,個位數
- write_com(0x80+add); //設置當前光標位置,準備寫數據
-
- if(t==1&&shi!=0) //如果溫度為負且十位不等于0(如果十位等于0,shi=0x70) 負數:百位第1種情況,寫-
- { write_data('-');} //在百位寫入負號
- if(t==1&&shi==0) //如果溫度為負且百十位都等于0 負數:百位第2種情況,寫空
- { write_data(0x30+0x70); //在百位寫入一個空字符
- write_data('-'); //在十位寫入負號 負數:十位第1種情況,寫-
- }
- if(t==1&&shi!=0) //如果溫度為負且十不等于0 負數:十位第2種情況,寫數
- {write_data(0x30+shi);} //在十位寫入數據
- if(t==0&&bai==0&&shi!=0) //否則溫度為正,如果bai=0且shi!=0 正數:百位第1種情況,寫+
- {write_data('+');} //在百位寫入+
- if(t==0&&bai==0&&shi==0) //否則溫度為正,如果bai=0且shi=0 正數:百位第2種情況,寫空
- {write_data(0x30+0x70);} //在百位寫入一個空字符
- if(t==0&&bai!=0)
- {write_data(0x30+bai);} //否則百位為正不等于0,寫入百位數 正數:百位第3種情況,寫數
- if(t==0&&bai==0&&shi==0&&ge!=0) //如果百十等于0,個不等于0 正數:十位第1種情況,寫+
- {write_data('+');} //在十位寫入+
- if(t==0&&bai==0&&shi==0&&ge==0) //如果百十個都等于0
- {write_data(' ');} //在十位寫入空字符 正數:十位第2種情況,寫空
- if(t==0&&shi!=0)
- {write_data(0x30+shi);}
- write_data(0x30+min); //在十位寫入數 正數:十位第3種情況,寫數
- write_data(0x30+ge); //寫入個位數據
- }
- /***********ds18b20子程序*************************/
- /***********ds18b20延遲子函數(晶振12MHz )*******/
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- void Init_DS18B20(void) //ds18b20初始化函數
- {
- unsigned char x=0;
- DQ = 1;
- delay_18B20(8);
- DQ = 0;
- delay_18B20(80);
- DQ = 1;
- delay_18B20(14);
- x=DQ;
- delay_18B20(20);
- }
- unsigned char ReadOneChar(void) // ds18b20讀一個字節
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- void WriteOneChar(uchar dat) //ds18b20寫一個字節
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- void ReadTemp(void) //讀取ds18b20當前溫度
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned char t=0;
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0x44);
- delay_18B20(100);
- Init_DS18B20();
- WriteOneChar(0xCC);
- WriteOneChar(0xBE);
- delay_18B20(100);
- a=ReadOneChar();
- b=ReadOneChar();
- // a=0xff;
- // b=0xfe;
- temp_value=b<<4;
- temp_value+=(a&0xf0)>>4;
- fig=0x01;
- if(temp_value>0x7f)
- {fig=0;
- a=~a+1;
- b=~b;
- temp_value=b<<4;
- temp_value+=(a&0xf0)>>4;
- temp_value*=0.625;
- }
- }
- void keyscan() //按鍵掃描
- { if(s1==0) //如果s1按下,執行下面程序
- { delay(5); // 延時一會
- if(s1==0) //如果s1確實按下,執行下面程序
- { s1num++; //s1num自加1
- while(!s1); //如果s1松開,執行下面程序,否則一直停在這
- if(s1num==1) //如果s1只按一次,執行下面
- {
- write_com(0x80+13); //設置當前指針位置
- write_com(0x0f); //寫入光標閃爍命令
- }
- if(s1num==2) //如果s1按2次,執行下面
- {
- write_com(0x80+0x40+13); //設置當前指針位置,光標閃
- }
- if(s1num==3) //如果s1按3次,執行下面
- { s1num=0; //s1num清0
- write_com(0x0c); //寫入光標不閃爍命令
- }
- }
- }
-
- if(s2==0) //如果s2按下,執行下面程序
- { delay(5); //延時
- if(s2==0); //如果s2按下,執行下面程序
- {
- while(!s2); //如果s2松開,執行下面程序,否則一直停在這
- if(s1num==1) //如果光標在h的位置閃爍,執行下面程序
- { h++; //h加1
- if(h==127) //=127清0
- h=0;
- figh=0; //設置figh=0,符號為正
- t=figh; //賦值給t,以便液晶顯示
- if(h<=-1) //如果h為負數
- {figh=1; //設置figh=0
- t=figh; //賦值給t,以便液晶顯示
- h=abs(h); //h取絕對值
- write_hl(11,h); //h寫入LCD
- h=0-h; //把h變回原來的負數
- }
- else{write_hl(11,h);} //否則h寫入LCD
- write_com(0x80+13); //光標在溫度值位置閃爍
- }
- if(s1num==2) //如果光標在l的位置閃爍,執行下面程序
- { l++;
- if(l==127)
- l=0;
- figl=0;
- t=figl;
- if(l<=-1)
- {figl=1;
- t=figl;
- l=abs(l);
- write_hl(0x40+11,l);
- l=0-l;
- }
- else{write_hl(0x40+11,l);}
- write_com(0x80+0x40+13);
- }
- }
- }
- if(s3==0) //如果s3按下,執行下面程序
- { delay(5); //延時
- if(s3==0);
- {
- while(!s3); //s3松開后,執行下面程序
- if(s1num==1) //如果光標在h的位置閃爍,執行下面程序
- { h--; //h自減1
- if(h==-55) //如果h=-55清0
- h=0;
- figh=0; //設置figh=0,溫度值為正
- t=figh; //賦值給t,以便液晶顯示
- if(h<=-1) //如果h溫度值為負數
- {figh=1; //設置figh=1
- t=figh; //賦值給t,以便液晶顯示
- h=abs(h); //h取絕對值
- write_hl(11,h); //h寫入LCD
- h=0-h; //把h變回原來的負數
- }
- else{write_hl(11,h);} //否則h寫入LCD
- write_com(0x80+13); //光標在溫度值位置閃爍
- }
- if(s1num==2)
- { l--;
- if(l==-55)
- h=0;
- figl=0;
- t=figl;
- if(l<=-1)
- {figl=1;
- t=figl;
- l=abs(l);
- write_hl(0x40+11,l);
- l=0-l;
- }
- else{write_hl(0x40+11,l);}
- write_com(0x80+0x40+13);
- }
- }
- }
- }
- void comp() //溫度值報警程序
- {if(fig==1&&temp_value>=h)
- D1=0;
- if(fig==1&&temp_value<=h)
- D1=1;
- if(fig==0) //如果讀取溫度值為負
- { if(figh==0) //如果設置最高值溫度值為正
- D1=1;
- if(figh==1) //如果設置最高值溫度值為負
- {h=abs(h);
- if(temp_value<=h)
- D1=0;
- if(temp_value>=h)
- D1=1;
- h=-h;
- }
- }
- if(fig==1&&temp_value<=l)
- D2=0;
- if(fig==1&&temp_value>=l)
- D2=1;
- if(fig==0)
- { if(figl==0)
- D2=0;
- if(figl==1)
- {l=abs(l);
- if(temp_value>=l)
- D2=0;
- if(temp_value<=l)
- D2=1;
- l=-l;
- }
- }
- }
復制代碼 |
|