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