|
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar temp,num,klnum;
- uchar code table[]={"18B20 OKTL"};
- char shangxiaxian[2]={-10,10};
- char a;
- sbit k1=P1^0;
- sbit k2=P1^1;
- sbit k3=P1^2;
- sbit k4=P1^3;
- sbit LCD_RW=P2^5;
- sbit lcdrs=P2^6;
- sbit lcden=P2^7;
- sbit Beep=P3^0;
- sbit led=P3^1;
- sbit DQ=P3^7; /*液晶顯示屏的延時程序*/
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- } /*溫度傳感器的延時程序*/
- void Delay1(uint y)
- {
- uint x;
- for( ;y>0; y--)
- {
- for(x=110;x>0;x--);
- }
- } /*蜂鳴器,18B20寫數據函數的延時程序*/
- void delay2(uint a)
- {
- while(--a);
- } /*溫度傳感器初始化函數*/
- void init_18B20()
- {
- DQ=1;
- delay2(8);
- DQ=0;
- delay2(90);
- DQ=1;
- _nop_();
- _nop_();
- delay2(100);
- DQ=1;
- } /*溫度傳感器寫字節命令函數*/
- void DS18B20xiezijie(uchar date)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0; //在寫入一位數據之前先把總線拉低
- DQ=date&0x01; //寫入一個數據,從最低位開始寫
- delay2(5); //延時
- DQ=1; //將總線拉高,等待第二位數據寫入
- date>>=1; //右移一位,寫入第二位數據
- }
- } /*溫度傳感器讀字節命令函數*/
- uchar DS18B20duzijie()
- {
- uchar i,dat=0;
- DQ=1;
- _nop_();
- for(i=0;i<8;i++)
- {
- DQ=0; //先將總線拉低
- _nop_();
- _nop_();
- dat>>=1;
- DQ=1; //然后釋放總線
- _nop_(); //延時一下等待數據穩定
- _nop_();
- if(DQ)
- dat|=0x80; //讀取數據,從最低位開始讀取
- delay2(30); //讀取完之后等待一下,再接著讀取下一個數
- DQ=1;
- }
- return dat; //返回所讀到的溫度
- } /*寫溫度轉換命令函數*/
- void DS18B20ChangTemp()
- {
- init_18B20();
- Delay1(1);
- DS18B20xiezijie(0xcc); //跳過ROM操作命令
- DS18B20xiezijie(0x44); //溫度轉換命令
- } /*讀溫度命令函數*/
- void DS18B20ReadTempCom()
- {
- init_18B20();
- Delay1(1);
- DS18B20xiezijie(0xcc); //跳過ROM操作命令
- DS18B20xiezijie(0xbe); //發送讀取溫度命令
- } /*讀溫度函數*/
- int DS18B20ReadTemp()
- {
- inttemp=0;
- uchartmh,tml;
- DS18B20ChangTemp(); //先寫入轉換命令
- DS18B20ReadTempCom(); //然后等待轉換完成后發送讀取溫度命令
- tml=DS18B20duzijie(); //讀取溫度值共16位,先讀低字節
- tmh=DS18B20duzijie(); //再讀高字節
- temp=tmh;
- temp<<=8;
- temp|=tml;
- return temp; /*液晶屏寫指令函數*/
- }
- void write_com(uchar com)
- {
- lcdrs=0;
- lcden=0;
- LCD_RW=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏寫指令函數*/
- void write_com2(int com)
- {
- lcdrs=0;
- LCD_RW=0;
- lcden=0;
- delay(5);
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- P0=(com&0x0f)<<4;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏寫數據命令函數*/
- void write_data(char date)
- {
- lcdrs=1;
- LCD_RW=0;
- lcden=0;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- lcdrs=1;
- LCD_RW=0;
- lcden=0;
- P0=(date&0x0f)<<4; //一次寫入4位
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- } /*液晶屏初始化函數*/
- void init()
- {
- lcden=0;
- write_com(0x28);
- write_com2(0x28);
- write_com2(0x0c);
- write_com2(0x06);
- write_com2(0x01);
- write_com2(0x80);
- } /*報警上下線處理函數*/
- void write_hl(uchar add,char date)
- {
- uchar bai,shi,ge;
- if(date<0){date=-date;}
- bai=date/100;
- shi=date%100/10;
- ge=date%100%10;
- write_com2(0x80+0x40+add);
- write_date(0x30+bai);
- write_date(0x30+shi);
- write_date(0x30+ge);
- } /*報警上下線處理函數*/
- void write_hl1(uchar add,char date)
- {
- uchar bai,shi,ge;
- if(date<0){date=-date;}
- bai=date/100;
- shi=date%100/10;
- ge=date%100%10;
- write_com2(0x80+add);
- write_date(0x30+bai);
- write_date(0x30+shi);
- write_date(0x30+ge);
- } /*液晶屏顯示函數,顯示溫度值*/
- void Lcdxianshi(int temp)
- {
- uchar sz[4]={0,0,0,0};
- unsigned char datas[]={0,0,0,0,0}; //定義數組
- float tp;
- if(temp<0) //當溫度值為負數
- {
- write_com2(0x80+0x40); //寫地址80表示初始地址
- write_data('-'); //顯示負
- temp=temp-1; //因為讀取的溫度是實際溫度的補碼,所以減一,再取反求出原碼
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5
- }
- else
- {
- write_com2(0x80+0x40); //寫地址80表示初始地址
- write_data('+'); //顯示正
- tp=temp; //因為數據處理有小數點,所以將溫度賦給一個浮點型變量,如果溫度是正,那么正數的原碼就是補碼本身
- temp=tp*0.0625*100+0.5;
- }
- datas[0]=temp/1000; //百位
- datas[1]=tem%10000/1000; //十位
- datas[2]=temp%1000/100; //個位
- datas[3]=temp%100/10; //小數
- write_com2(0x80+0x40+1);
- write_data('0'+datas[0]);
- write_com2(0x80+0x40+2);
- write_data('0'+datas[1]);
- write_com2(0x80+0x40+3);
- write_data('0'+datas[2]);
- write_com2(0x80+0x40+4);
- write_data('.');
- write_com2(0x80+0x40+5);
- write_data('0'+datas[3]);
- a=(datas[0]*100+datas[1]*10+datas[2]); //用于溫度的比較值
- write_hl(13,shangxiaxian[1]); //顯示報警上限
- write_hl1(13,shangxiaxian[0]); //顯示報警下限
- } /*按鍵處理函數,用于設置溫度報警值*/
- void key()
- {
- if(k1==0)
- {
- delay(5);
- if(k1==0) //溫度報警下限加
- {
- shangxiaxian[0]++;
- if(shangxiaxian[0]==127)
- shangxiaxian[0]=126;
- write_hl1(13,shangxiaxian[0]);
- }
- }
- if(k2==0) //溫度報警下限減
- {
- delay(5);
- if(k2==0)
- {
- shangxiaxian[0]--;
- if(shangxiaxian[0]==-56)
- shangxiaxian[0]=-55;
- write_hl1(13,shangxiaxian[0]);
- }
- }
- if(k3==0) //溫度報警上限加
- {
- delay(5);
- if(k3==0)
- {
- shangxiaxian[1]++;
- if(shangxiaxian[1]==127)
- shangxiaxian[1]=126;
- write_hl(13,shangxiaxian[1]);
- }
- }
- if(k4==0) //溫度報警上限減
- {
- delay(5);
- if(k4==0)
- {
- shangxiaxian[1]--;
- if(shangxiaxian[1]==-56)
- shangxiaxian[1]=-55;
- write_hl(13,shangxiaxian[1]);
- }
- }
- }
- void main()
- {
- intb;
- init();
- led=0;
- for(num=0;num<11;num++) //讓液晶屏顯示“18B20 OK TL”
- {
- write_data(table[num]);
- delay(20);
- }
- write_com2(0x80+0x40+9);
- write_data('T');
- write_com2(0x80+0x40+10);
- write_data('H');
- while(1)
- {
- key();
- Lcdxianshi(Ds18B20ReadTemp());
- delay(100);
- if(shangxiaxian[0]<0)
- {
- write_com2(0x80+12);
- write_data('-');
- }
- else
- {
- write_com2(0x80+12);
- write_data('+');
- }
- if(shangxiaxian[1]<0)
- {
- write_com2(0x80+0x40+12);
- write_data('-');
- }
- else
- {
- write_com2(0x80+0x40+12);
- write_data('+');
- }
- if(a>shangxiaxian[1]) //判斷溫度值與報警值的大小
- {
- write_com2(0x80+0x40+6);
- write_data('<');
- write_com2(0x80+0x40+7);
- write_data('L');
- }
- if(a>=shangxiaxian[0]&&a<=shangxiaxian[1]) //判斷溫度值與報警值的大小
- {
- write_com2(0x80+0x40+6);
- write_data('');
- write_com2(0x80+0x40+7);
- write_data('!');
- }
- if(a>shangxiaxian[0]||a>shangxiaxian[1]) //如果溫度值在報警值之外,蜂鳴器響
- {
- for(b=0;b<1000;b++)
- {Beep=1;led=1;
- delay2(20);
- Beep=0;led=0;
- delay0(20);
- }
- }
- }
- }
復制代碼
|
-
1.png
(118.67 KB, 下載次數: 58)
下載附件
2020-6-25 19:36 上傳
-
0.png
(120.94 KB, 下載次數: 38)
下載附件
2020-6-25 19:36 上傳
|