|
使用模塊:STC89C51,DS18B20溫度傳感器模塊,LCD1602
仿真
實(shí)物圖片
單片機(jī)源程序如下:
- #include<reg51.h> //包含reg52.h庫(kù)文件
- #include<math.h> //包含絕對(duì)值函數(shù)
- #define uint unsigned int //宏定義uint
- #define uchar unsigned char //宏定義uchar
- sbit lcden=P2^7; //液晶使能端
- sbit lcdrw=P2^6;
- sbit lcdrs=P2^5; //液晶數(shù)據(jù)命令選擇端選擇寫(xiě)數(shù)據(jù)還是寫(xiě)命令
- sbit DQ = P3^4; //通過(guò)DQ口讀取溫度值
- uchar temp_value,num,fig,s1num,figh,figl,t; //設(shè)置全局無(wú)符號(hào)字符型變量
- char h,l; //設(shè)置全局有符號(hào)字符型變量
- void delay(uint z); //申明延時(shí)程序
- void init(); //申明LCD初始化程序
- void write_com(uchar com); //申明寫(xiě)命令程序
- void write_data(uchar date); //申明寫(xiě)數(shù)據(jù)程序
- //void keyscan(); //申明按鍵掃描程序
- void write_hl(uchar add,char date); //申明設(shè)置的最高低溫度值在LCD上顯示程序
- void write_temp_value(uchar add,char date); //申明溫度值在LCD上顯示程序
- void delay_18B20(unsigned int i); //申明延時(shí)程序
- void Init_DS18B20(void); //申明DS18B20初始化程序
- unsigned char ReadOneChar(void); //申明ds18b20讀一個(gè)字節(jié)
- void WriteOneChar(uchar dat); //申明ds18b20讀一個(gè)字節(jié)
- void ReadTemp(void); //申明讀取ds18b20當(dāng)前溫度
- void comp();
- void main()
- {
- init(); //LCD初始化
- Init_DS18B20(); //DS18B20初始化
- while(1) //大循環(huán)
- {
- // if(s1==0||s1num>=1)
- // { keyscan(); //按鍵掃描
- // }
- // else{
- ReadTemp(); //讀取溫度值
- write_temp_value(0,temp_value); //LCD顯示溫度值
- }
- comp();
- }
- //}
- void delay(uint z) //延時(shí)程序
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void init() //LCD初始化程序
- {
- lcden=0;
- lcdrw=0;
- write_com(0x38); //設(shè)置16x2 顯示5x7 點(diǎn)陣,8 位數(shù)據(jù)接口
- write_com(0x0c); //設(shè)置開(kāi)始顯示不顯示光標(biāo)
- write_com(0x06); //寫(xiě)一個(gè)字符后地址指針加1
- write_com(0x01); //顯示清零數(shù)據(jù)指針清零
- write_com(0x80); //將數(shù)據(jù)指針第一行第一個(gè)字處,
-
- write_com(0x80+9); //定義當(dāng)前指針位置
- write_data('H'); //寫(xiě)入
- write_data(':'); //寫(xiě)入
- write_data('+'); //寫(xiě)入
- write_data('2'); //寫(xiě)入
- write_data('0'); //寫(xiě)入
- write_data(0xdf); //寫(xiě)入°
- write_data('C'); //寫(xiě)入C
- write_com(0x80+9+0x40); //定義當(dāng)前指針位置
- write_data('L'); //寫(xiě)入
- write_data(':'); //寫(xiě)入
- write_data('+'); //寫(xiě)入
- write_data('1'); //寫(xiě)入
- write_data('0'); //寫(xiě)入
- write_data(0xdf); //寫(xiě)入°
- write_data('C'); //寫(xiě)入C
- h=0x14; //h=+20
- l=0+0x0a; //l=+10
- // D1=1;
- // D2=1;
- figh=0; //給正確初始值,便于上電比較
- figl=1; //給正確初始值,便于上電比較
- }
- void write_com(uchar com) //寫(xiě)命令程序
- { lcdrs=0; //設(shè)置為寫(xiě)入命令
- P0=com; //將命令賦給P0 口
- delay(5); //延時(shí)
- lcden=1; //打開(kāi)LCD使能,輸入一個(gè)高脈沖
- delay(5); //延時(shí)
- lcden=0; //置低完成高脈沖
- }
- void write_data(uchar date) //寫(xiě)數(shù)據(jù)程序
- { lcdrs=1; //設(shè)置為寫(xiě)入數(shù)據(jù)
- P0=date; //將數(shù)據(jù)賦給P0 口
- delay(5); //延時(shí)
- lcden=1; //打開(kāi)LCD使能,輸入一個(gè)高脈沖
- delay(5); //延時(shí)
- lcden=0; //置低完成高脈沖
- }
- void write_temp_value(uchar add,char date) //讀取的溫度值在LCD上顯示程序
- { uchar bai,shi,ge;
- bai=date/100;
- shi=date%100/10;
- ge=date%10; //分離出百,十,個(gè)位數(shù)
- if((bai|shi)==0) //如果百十都等于0
- shi=0x70; //十賦值0x70,以便十位寫(xiě)入空字符,write_data(0x30+shi),參考1602字符圖形碼
- if(bai==0)
- bai=0x70;
- write_com(0x80+add); //設(shè)置當(dāng)前光標(biāo)位置,準(zhǔn)備寫(xiě)數(shù)據(jù)
-
- if(fig==0&&shi!=0x70) //如果溫度為負(fù)且十位不等于0(如果十位等于0,shi=0x70)
- { write_data('-'); //在百位寫(xiě)入負(fù)號(hào)
- write_data(0x30+shi); //寫(xiě)入十位數(shù)據(jù)
- }
- if(fig==0&&shi==0x70) //如果溫度為負(fù)且百十位都等于0
- { write_data(0x30+0x70); //在百位寫(xiě)入一個(gè)空字符
- write_data('-'); //在十位寫(xiě)入負(fù)號(hào)
- }
- if(fig==1)write_data(0x30+bai); //溫度正,寫(xiě)入百位數(shù)據(jù)
- if(fig==1)write_data(0x30+shi); //溫度正,寫(xiě)入十位數(shù)據(jù)
- write_data(0x30+ge); //寫(xiě)入個(gè)位數(shù)據(jù)
- write_data(0xdf); //寫(xiě)入°
- write_data('C'); //寫(xiě)入C
-
- }
- void write_hl(uchar add,char date) //設(shè)置的高低溫度值在LCD上顯示程序
- { uchar bai,shi,ge;
- bai=date/100;
- shi=date%100/10;
- ge=date%10; //分離出百,十,個(gè)位數(shù)
- write_com(0x80+add); //設(shè)置當(dāng)前光標(biāo)位置,準(zhǔn)備寫(xiě)數(shù)據(jù)
-
- if(t==1&&shi!=0) //如果溫度為負(fù)且十位不等于0(如果十位等于0,shi=0x70) 負(fù)數(shù):百位第1種情況,寫(xiě)-
- { write_data('-');} //在百位寫(xiě)入負(fù)號(hào)
- if(t==1&&shi==0) //如果溫度為負(fù)且百十位都等于0 負(fù)數(shù):百位第2種情況,寫(xiě)空
- { write_data(0x30+0x70); //在百位寫(xiě)入一個(gè)空字符
- write_data('-'); //在十位寫(xiě)入負(fù)號(hào) 負(fù)數(shù):十位第1種情況,寫(xiě)-
- }
- if(t==1&&shi!=0) //如果溫度為負(fù)且十不等于0 負(fù)數(shù):十位第2種情況,寫(xiě)數(shù)
- {write_data(0x30+shi);} //在十位寫(xiě)入數(shù)據(jù)
- if(t==0&&bai==0&&shi!=0) //否則溫度為正,如果bai=0且shi!=0 正數(shù):百位第1種情況,寫(xiě)+
- {write_data('+');} //在百位寫(xiě)入+
- if(t==0&&bai==0&&shi==0) //否則溫度為正,如果bai=0且shi=0 正數(shù):百位第2種情況,寫(xiě)空
- {write_data(0x30+0x70);} //在百位寫(xiě)入一個(gè)空字符
- if(t==0&&bai!=0)
- {write_data(0x30+bai);} //否則百位為正不等于0,寫(xiě)入百位數(shù) 正數(shù):百位第3種情況,寫(xiě)數(shù)
- if(t==0&&bai==0&&shi==0&&ge!=0) //如果百十等于0,個(gè)不等于0 正數(shù):十位第1種情況,寫(xiě)+
- {write_data('+');} //在十位寫(xiě)入+
- if(t==0&&bai==0&&shi==0&&ge==0) //如果百十個(gè)都等于0
- {write_data(' ');} //在十位寫(xiě)入空字符 正數(shù):十位第2種情況,寫(xiě)空
- if(t==0&&shi!=0)
- {write_data(0x30+shi);} //在十位寫(xiě)入數(shù) 正數(shù):十位第3種情況,寫(xiě)數(shù)
- write_data(0x30+ge); //寫(xiě)入個(gè)位數(shù)據(jù)
- }
- /***********ds18b20子程序*************************/
- /***********ds18b20延遲子函數(shù)(晶振12MHz )*******/
- void delay_18B20(unsigned int i)
- {
- while(i--);
- }
- /**********ds18b20初始化函數(shù)**********************/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ復(fù)位
- delay_18B20(8); //稍做延時(shí)
- DQ = 0; //單片機(jī)將DQ拉低
- delay_18B20(80); //精確延時(shí) 大于 480us
- DQ = 1; //拉高總線
- delay_18B20(14);
- x=DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
- delay_18B20(20);
- }
- /***********ds18b20讀一個(gè)字節(jié)**************/
- unsigned char ReadOneChar(void)
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號(hào)
- dat>>=1;
- DQ = 1; // 給脈沖信號(hào)
- if(DQ)
- dat|=0x80;
- delay_18B20(4);
- }
- return(dat);
- }
- /*************ds18b20寫(xiě)一個(gè)字節(jié)****************/
- void WriteOneChar(uchar dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay_18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- /**************讀取ds18b20當(dāng)前溫度************/
- void ReadTemp(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned char t=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過(guò)讀序號(hào)列號(hào)的操作
- WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
- delay_18B20(100); // this message is very important
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
- delay_18B20(100);
- a=ReadOneChar(); //讀取溫度值低位
- b=ReadOneChar(); //讀取溫度值高位
- // a=0xff; //測(cè)試無(wú)法讀取-16度的問(wèn)題
- // b=0xfe;
- temp_value=b<<4; //temp_value=b左移動(dòng)4位 , 轉(zhuǎn)換成10進(jìn)制
- temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 轉(zhuǎn)換成10進(jìn)制
- fig=0x01; //設(shè)置fig=1溫度正
- if(temp_value>0x7f) //如果temp_value大于0x7f,即為負(fù)數(shù)區(qū),參考DS18B20datasheet
- {fig=0; //設(shè)置fig=0溫度負(fù),以便判斷顯示
- a=~a+1; //將讀取的溫度轉(zhuǎn)換成10進(jìn)制數(shù)
- b=~b;
- temp_value=b<<4; //temp_value=b左移動(dòng)4位 , 轉(zhuǎn)換成10進(jìn)制
- temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 轉(zhuǎn)換成10進(jìn)制
- }
- }
-
復(fù)制代碼
所有代碼51hei下載(由于怕有人照搬此例,所以仿真工程不分享出來(lái),要學(xué)習(xí)的可以自己按圖畫(huà)):
程序1.7z
(26.53 KB, 下載次數(shù): 44)
2020-12-23 22:22 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|