單片機(jī)溫度檢測報警程序(ds18b20)
程序采用數(shù)字溫度采集芯片 ds18b20 獲取溫度 分辨率為12位 可以由此程序獲的更低分辨率溫度
ds18b20 只有三個i/o接口 其中兩個為電源引腳 一個為數(shù)據(jù)總線
只需要一條口線通信 簡化了分布式溫度傳感應(yīng)用 無需外部元件 可用數(shù)據(jù)總線供電
電壓范圍為3.0 V至5.5 V 無需備用電源 測量溫度范圍為-55 ° C至+125 ℃
ds18b20 相關(guān)介紹:ds18b20 百度百科
Proteus 仿真:
Code:
#include#include #defineucharunsignedchar//宏定義uchar為無符號字符#defineuintunsignedintsbitDQ=P2^3;sbitalarm=P3^4;//溫度告警標(biāo)志位sbittest=P1^0;unsignedlongtemp;//溫度值uchartempH,tempL,tempSign;//ds18b20讀取的溫度高位和低8位,最高上限溫度和最低下限溫度,溫度符號signedlongsetMax=10;signedlongsetMin=-10;floatprecision=0.0625;//溫度精度(默認(rèn)12位)ucharseg[8]={0};//eg.-100.0625//延時函數(shù)voiddelay(uintt)//最大65ms2^16{/*TMOD=0x01;//啟用T0計時器工作方式1TH0=(65536-t)/256;TL0=(65536-t)%256;EA=0;//禁止中斷TR0=1;//開始T0計數(shù)while(TF0==0);TF0=0;//清除T0溢出標(biāo)志位TR0=0;//關(guān)閉T0計數(shù)*/while(t--);}//ds18b20初始化函數(shù)ucharinit(void){ucharfeedback;DQ=0;delay(100);DQ=1;/*while(DQ);//用于獲取反饋信號,返回0為成功,返回1為初始化失敗feedback=DQ;*/delay(25);//returnfeedback;//返回0復(fù)位成功,返回1復(fù)位失敗}//寫函數(shù)voidwrite(ucharvar)//先輸出低位,再輸出高位{uchari;for(i=8;i>0;i--){DQ=0;DQ=var&0x01;//獲取最后一位數(shù)據(jù)寫入數(shù)據(jù)線delay(5);//(DQ==1)?delay(10):delay(70);//延時保證ds18b20采樣。寫入為115us內(nèi)需釋放數(shù)據(jù)線;寫入為0至少延時60us;DQ=1;var>>=1;//右移一位}//delay(5);}//讀函數(shù)ucharread(void){//先讀取低位,再讀取高位ucharfeedback=0;uchari;for(i=8;i>0;i--){DQ=0;feedback>>=1;//右移DQ=1;//數(shù)據(jù)線拉低15us內(nèi)釋放數(shù)據(jù)線//delay(1);if(DQ){feedback|=0x80;}//在feedback在高位寫入1等待右移處理delay(5);}returnfeedback;}//配置ds18b20參數(shù)說明:(最高溫度,最低溫度)//暫不可用voidsetConfig(charth,chartl){ucharprecision;init();write(0xcc);write(0x4e);write(th);//默認(rèn)最高溫度為+125write(tl);//默認(rèn)最低溫度為-55}//溫度超限報警處理voidwarning(){ucharmaxSign=0,minSign=0;//最高溫度和最低溫度符號if(setMax>0){maxSign=1;}if(setMin>0){minSign=1;}if(temp setMax*10000&&tempSign>=maxSign)//大于上限溫度{alarm=0;delay(100);alarm=1;delay(100);}else{alarm=0;}}//溫度顯示處理,轉(zhuǎn)換tampH和tempL,寫入數(shù)組seg[8],得出十進(jìn)制溫度tempvoidconvert(){uinttempC;//補(bǔ)碼溫度ucharseg7;//溫度符號位tempC=tempH*256.0+tempL;//tempC=tempH<<8;//tempC|=tempL;if(tempC>0x0800){seg7=0x40;//溫度為負(fù)溫度tempSign=0;temp=(~tempC+1);//補(bǔ)碼求原碼,取反加一temp=temp*precision;}else{tempSign=1;seg7=0x00;//溫度為正temp=tempC;temp=temp*precision*10000;//放大10000倍,用于取余獲取各位數(shù)值}//temp=1234567;seg[7]=seg7;seg[6]=temp/1000000;seg[5]=temp%1000000/100000;seg[4]=temp%1000000%100000/10000;seg[3]=temp%1000000%100000%10000/1000;seg[2]=temp%1000000%100000%10000%1000/100;seg[1]=temp%1000000%100000%10000%1000%100/10;seg[0]=temp%1000000%100000%10000%1000%100%10;}//數(shù)碼管動態(tài)顯示,讀取數(shù)組seg[8]voidledShow(){uchari=0,m,led;uchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共陰數(shù)碼管0-9uchartabPoint[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//共陰數(shù)碼管0-9帶小數(shù)點do{m=seg[i];if(i==4)//數(shù)碼管第四位包含小數(shù)點單片機(jī)開發(fā)板數(shù)碼管和proteus仿真不同{led=tabPoint[m];}elseif(i==7){//符號位跳過譯碼led=seg[7];}else{led=tab[m];}P2=i;//送位碼單片機(jī)開發(fā)板數(shù)碼管和proteus仿真不同P0=led;//送段碼delay(100);i++;warning();}while(i<8);}//從ds18b20獲取溫度,獲取tempH和tempLvoidgetTemp(){init();write(0xCC);//跳過rom搜索write(0x44);//啟動溫度轉(zhuǎn)換delay(100);//溫度轉(zhuǎn)換最多750msinit();write(0xCC);write(0xBE);//讀出ds18b20內(nèi)部RAM9直接內(nèi)容delay(100);tempL=read();//讀出溫度低字節(jié)tempH=read();//讀出溫度高字節(jié)//tempMax=read();//讀取高溫觸發(fā)器//tempMin=read();//讀取低溫觸發(fā)器}voidmain(){while(1){getTemp();convert();ledShow();}}