最佳答案
//這是我曾經做的一個溫度控制系統,可以調節上下限溫度,低于下限溫度啟動加熱,高于上限停止加熱。//溫控系統控制程序//版本號:V1.0;2015.6.19//溫度傳感器:DS18B20//顯示方式:LED#include #define uchar unsigned charsbit keyup=P1^0;sbit keydn=P1^1;sbit keymd=P1^2;sbit out=P3^7;//接控制繼電器sbit DQ = P3^4;//接溫度傳感器18B20uchar t[2],number=0,*pt;//溫度值uchar TempBuffer1[4]={0,0,0,0};uchar Tmax=18,Tmin=8;uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0xfe,0xf7};uchar dismod=0,xiaodou1=0,xiaodou2=0,currtemp;bit flag;void t0isr() interrupt 1{TH0=(65536-5000)/256;TL0=(65536-5000)%256;switch(number){case 0: P2=0x08; P0=distab[TempBuffer1[0]]; break;case 1: P2=0x04; P0=distab[TempBuffer1[1]]; break;case 2: P2=0x02; P0=distab[TempBuffer1[2]]&0x7f; break;case 3: P2=0x01; P0=distab[TempBuffer1[3]]; break;default: break;}number++;if(number>3)number=0;}void delay_18B20(unsigned int i){while(i--);}/**********ds18b20初始化函數**********************/void Init_DS18B20(void) { bit x=0;do{ DQ=1; delay_18B20(8); DQ = 0; //單片機將DQ拉低 delay_18B20(90); //精確延時 大于 480us DQ = 1; //拉高總線 delay_18B20(14); x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗,繼續初始化}while(x); delay_18B20(20);}/***********ds18b20讀一個字節**************/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--) { DQ = 0; // 給脈沖信號 dat>>=1; DQ = 1; // 給脈沖信號 if(DQ) dat|=0x80; delay_18B20(4); }return(dat);}/*************ds18b20寫一個字節****************/void WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){ DQ = 0;DQ = dat&0x01; delay_18B20(5);DQ = 1; dat>>=1;}}/**************讀取ds18b20當前溫度************/unsigned char *ReadTemperature(unsigned char rs){unsigned char tt[2]; delay_18B20(80); Init_DS18B20();WriteOneChar(0xCC); //跳過讀序號列號的操作WriteOneChar(0x44); //啟動溫度轉換 delay_18B20(80); Init_DS18B20();WriteOneChar(0xCC); //跳過讀序號列號的操作WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器)前兩個就是溫度tt[0]=ReadOneChar(); //讀取溫度值低位tt[1]=ReadOneChar(); //讀取溫度值高位return(tt);}void covert1(void)//將溫度轉換為LED顯示的數據{ uchar x=0x00,y=0x00; t[0]=*pt; pt++; t[1]=*pt; if(t[1]&0x080) //判斷正負溫度 { TempBuffer1[0]=0x0c; //c代表負t[1]=~t[1]; /*下面幾句把負數的補碼*/t[0]=~t[0]; /*換算成絕對值*********/x=t[0]+1;t[0]=x;if(x==0x00)t[1]++; } else TempBuffer1[0]=0x0a;//A代表正 t[1]<<=4;//將高字節左移4位 t[1]=t[1]&0xf0; x=t[0];//將t[0]暫存到X,因為取小數部分還要用到它 x>>=4;//右移4位 x=x&0x0f;//和前面兩句就是取出t[0]的高四位 y=t[1]|x;//將高低字節的有效值的整數部分拼成一個字節 TempBuffer1[1]=(y%100)/10; TempBuffer1[2]=(y%100)%10; t[0]=t[0]&0x0f;//小數部分 TempBuffer1[3]=t[0]*10/16; //以下程序段消去隨機誤檢查造成的誤判,只有連續12次檢測到溫度超出限制才切換加熱裝置if(currtemp>Tmin)xiaodou1=0;if(y12){out=0;flag=1;xiaodou1=0;}if(currtempTmax){xiaodou2++;currtemp=y;xiaodou1=0;}if(xiaodou2>12){out=1;flag=0;xiaodou2=0;}out=flag;}void convert(char tmp){uchar a;if(tmp<0){TempBuffer1[0]=0x0c;a=~tmp+1;}else {TempBuffer1[0]=0x0a;a=tmp;}TempBuffer1[1]=(a%100)/10;TempBuffer1[2]=(a%100)%10;}void keyscan( ){uchar keyin;keyin=P1&0x07;if(keyin==0x07)return;else if(keymd==0){dismod++;dismod%=3;while(keymd==0);switch(dismod){case 1: convert(Tmax); TempBuffer1[3]=0x11; break;case 2: convert(Tmin); TempBuffer1[3]=0x12; break;default: break;}}else if((keyup==0)&&(dismod==1)){Tmax++;convert(Tmax);while(keyup==0);}else if((keydn==0)&&(dismod==1)){Tmax--;convert(Tmax);while(keydn==0);}else if((keyup==0)&&(dismod==2)){Tmin++;convert(Tmin);while(keyup==0);}else if((keydn==0)&&(dismod==2)){Tmin--;convert(Tmin);while(keydn==0);}xiaodou1=0;xiaodou2=0;}main(){TMOD=0x01;TH0=(65536-5000)/256;TL0=(65536-5000)%256;TR0=1;ET0=1;EA=1;out=1;flag=0;ReadTemperature(0x3f); delay_18B20(50000);//延時等待18B20數據穩定 while(1){pt=ReadTemperature(0x7f); //讀取溫度,溫度值存放在一個兩個字節的數組中if(dismod==0)covert1();keyscan();delay_18B20(30000);}}
回答者:wenziang20112016-09-16 00:00