|
- #include<reg52.h> //包含頭文件
- #include<math.h>
- #define ui unsigned int
- #define uc unsigned char //宏定義
- sbit DQ =P3^7; //定義DS18B20總線I/O
- sbit LEDR=P1^2;
- sbit LEDG=P1^1;
- sbit LEDB=P1^0;
- bit bdata fuhao; //符號
- uc qian,bai,shi,ge; //讀取溫度值的千、百、十和個(gè)位(例如實(shí)際溫度是123.4攝氏度,在程序里處理數(shù)據(jù)時(shí)會放大10倍,就是小數(shù)點(diǎn)右移一位,方便處理,就是處理的是1234)
- uc code led[] = {0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7}; //數(shù)碼管對應(yīng)的數(shù)字的段碼
- uc code led_dian[] = {0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x67,0xff,0xf7}; //有小數(shù)點(diǎn)的數(shù)字段碼表
- uc m;
- uc NUM_R=0,NUM_G=0,NUM_B=0;
- uc DIS;
- ui zan=25;
- //============================================================================================
- //====================================DS18B20=================================================
- //============================================================================================
- /*****延時(shí)子程序*****/
- void Delay(int num)
- {
- while(num--) ; //num減占用系統(tǒng)資源,用于延時(shí)
- }
- /*****初始化DS18B20*****/
- void Init_DS18B20()
- {
- DQ = 1; //DQ復(fù)位,就是拉高電平
- Delay(8); //稍做延時(shí)
- DQ = 0; //單片機(jī)將DQ拉低
- Delay(80); //精確延時(shí),大于480us
- DQ = 1; //拉高總線
- Delay(40); //延時(shí)
- }
- /*****讀一個(gè)字節(jié)*****/
- uc ReadOneChar()
- {
- uc i=0;
- uc dat = 0; //定義變量用于循環(huán)和讀取數(shù)據(jù)
- for (i=8;i>0;i--) //循環(huán)8次
- {
- DQ = 0; //拉低
- dat>>=1; //數(shù)據(jù)右移一位
- DQ = 1; //拉高
- if(DQ) //判斷是否是高電平
- dat|=0x80; //是高電平的話,就讓dat的最好為為1
- Delay(4); //延時(shí)
- }
- return(dat); //返回讀取到的數(shù)據(jù)
- }
- /*****寫一個(gè)字節(jié)*****/
- void WriteOneChar(uc dat)
- {
- uc i=0; //定義變量用于循環(huán)
- for (i=8; i>0; i--) //循環(huán)八次
- {
- DQ = 0; //低電平
- DQ = dat&0x01; //最低位是0的話,DQ就等于0;最低位是1的話,DQ就等于1
- Delay(5); //延時(shí)
- DQ = 1; //拉高
- dat>>=1; //右移一位
- }
- }
- /*****讀取溫度*****/
- ui ReadTemperature()
- {
- ui a=0,b=0,t=0;
- float tt=0; //定義讀取溫度變量
- Init_DS18B20(); //初始化18B20
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0x44); //啟動溫度轉(zhuǎn)換
- Init_DS18B20(); //初始化18B20
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器
- a=ReadOneChar(); //讀低8位
- b=ReadOneChar(); //讀高8位
- t=b; //高八位的數(shù)據(jù)提取到t
- t<<=8; //高八位數(shù)據(jù)左移八位
- t=t|a; //高位和低八位數(shù)據(jù)組成一個(gè)數(shù)據(jù)
- if(t&0xf800) //判斷是否是負(fù)溫度
- {
- t=~t+1; //將負(fù)溫度值取反加一得到實(shí)際溫度值
- fuhao=1; //符號位為負(fù)
- }
- else //如果是正溫度
- fuhao=0; //符號位為正
- tt=t*0.0625; //乘以0.0625得到實(shí)際溫度
- t=tt*10+0.5; //放大10倍輸出并四舍五入
- return(t); //返回溫度數(shù)據(jù)
- }
- /*****讀取溫度*****/
- void check_wendu()
- {
- ui f;
- // TR0=0;
- // zan=f;
- f=ReadTemperature(); //獲取溫度值并減去DS18B20的溫漂誤差
- // TR0=1;
- // if(abs(f-zan)>50) f=zan;
- qian=f/1000; //計(jì)算得到實(shí)際的百位數(shù)字
- bai=(f%1000)/100; //計(jì)算得到實(shí)際的十位數(shù)字
- shi=((f%1000)%100)/10; //計(jì)算得到實(shí)際的個(gè)位數(shù)字
- ge=((f%1000)%100)%10; //計(jì)算得到實(shí)際的小數(shù)位
- }
- /*****顯示開機(jī)初始化等待畫面*****/
- void Disp_init()
- {
- P0 = 0x7f; //顯示----
- P2 = 0x7f;
- Delay(100);
- P2 = 0xdf;
- Delay(100);
- P2 = 0xf7;
- Delay(100);
- P2 = 0xfd;
- Delay(100);
- P2 = 0xff; //關(guān)閉顯示
- }
- /*****顯示溫度子程序*****/
- void Disp_Temperature() //顯示溫度
- {
- if(qian==0) //千位等于0
- {
- if(fuhao==1) //是負(fù)溫度
- P0=0x7f; //顯示-
- else //是正溫度
- P0=0xff; //不顯示
- }
- else if(qian!=0) //千位不等于0
- P0 =~led[qian]; //顯示千位數(shù)據(jù)
- P2 = 0xfd; //打開第一位位選
- Delay(10);
- P2 = 0xff; //關(guān)閉位選
- if((bai==0)&&(qian==0))//百位千位都是0
- P0=0xff; //不顯示
- else if((bai!=0)||(qian!=0))//千位或者百位不等于0
- P0=~led[bai]; //正常顯示百位數(shù)據(jù)
- P2=0xf7; //打開第二位
- Delay(10);
- P2 = 0xff; //關(guān)閉位選
- P0=~led_dian[shi]; //顯示十位數(shù)據(jù)
- P2=0xdf; //打開第三位
- Delay(10);
- P2 = 0xff; //關(guān)閉位選
- P0=~led[ge]; //顯示個(gè)位數(shù)據(jù)
- P2=0x7f; //打開第四位
- Delay(10);
- P2 = 0xff; //關(guān)閉位選
- }
- /*****主函數(shù)*****/
- void main()
- {
- uc z; //定義變量用于for循環(huán)
- for(z=0;z<100;z++) //循環(huán)100次讀取溫度并顯示開機(jī)畫面,防止開機(jī)顯示85
- {
- Disp_init(); //開機(jī)初始化顯示
- ReadTemperature();
- }
- while(1) //進(jìn)入while循環(huán)
- {
- check_wendu(); //讀取溫度
- // Delay(20000);
- if(fuhao==0)
- {
- if((qian*100+bai*10+shi)>=0&&(qian*100+bai*10+shi)<10) {NUM_R=0; NUM_G=2; NUM_B=8;} //溫度在0-10度之間,顏色:青色偏藍(lán),狀態(tài):寒冷
- else if((qian*100+bai*10+shi)>=10&&(qian*100+bai*10+shi)<20) {NUM_R=0; NUM_G=3; NUM_B=5;} //溫度在10-20度之間,顏色:青色,狀態(tài):冷
- else if((qian*100+bai*10+shi)>=20&&(qian*100+bai*10+shi)<30) {NUM_R=0; NUM_G=5; NUM_B=0;} //溫度在20-30度之間,顏色:綠色,狀態(tài):舒適
- else if((qian*100+bai*10+shi)>=30&&(qian*100+bai*10+shi)<35) {NUM_R=7; NUM_G=2; NUM_B=0;} //溫度在30-35度之間,顏色:黃色,狀態(tài):熱
- else if((qian*100+bai*10+shi)>=35) {NUM_R=10; NUM_G=0; NUM_B=0;} //溫度在35度以上,顏色:紅色,狀態(tài):炎熱
- // if((qian*100+bai*10+shi)>=24&&(qian*100+bai*10+shi)<25) {NUM_R=0; NUM_G=2; NUM_B=8;} //溫度在0-10度之間,顏色:青色偏藍(lán),狀態(tài):寒冷
- // else if((qian*100+bai*10+shi)>=25&&(qian*100+bai*10+shi)<26) {NUM_R=0; NUM_G=3; NUM_B=5;} //溫度在10-20度之間,顏色:青色,狀態(tài):冷
- // else if((qian*100+bai*10+shi)>=26&&(qian*100+bai*10+shi)<27) {NUM_R=0; NUM_G=5; NUM_B=0;} //溫度在20-30度之間,顏色:綠色,狀態(tài):舒適
- // else if((qian*100+bai*10+shi)>=27&&(qian*100+bai*10+shi)<28) {NUM_R=7; NUM_G=2; NUM_B=0;} //溫度在30-35度之間,顏色:黃色,狀態(tài):熱
- // else if((qian*100+bai*10+shi)>=28) {NUM_R=10; NUM_G=0; NUM_B=0;} //溫度在35度以上,顏色:紅色,狀態(tài):炎熱
- // else if((qian*100+bai*10+shi)<24) {NUM_R=0;NUM_G=0;NUM_B=10;}
- }
- else //溫度為負(fù)值,零下,顏色:藍(lán)色,狀態(tài):冰凍
- {
- NUM_R=0;NUM_G=0;NUM_B=10;
- }
- for(z=0;z<10;z++) //顯示10次
- {
- Disp_Temperature(); //調(diào)用顯示函數(shù)
- m++;
- if(m<NUM_R) LEDR=0;
- else LEDR=1;
- if(m<NUM_G) LEDG=0;
- else LEDG=1;
- if(m<NUM_B) LEDB=0;
- else LEDB=1;
- if(m>=10) m=0;
- }
- }
- }
復(fù)制代碼
|
|