C語言程序 #include<stc15.h> #define ui unsigned int #define uc unsigned char //宏定義 sbit SET=P3^1; //定義調整鍵 sbit DEC=P3^2; //定義減少鍵 sbit ADD=P3^3; //定義增加鍵 sbit BEEP=P3^6; //定義蜂鳴器 sbit ALAM=P1^2; //定義燈光報警 sbit ALAM1=P1^4; sbit DQ =P3^7; //定義DS18B20總線I/O sbit SCL=P1^6; sbit SDA=P1^7; sbit DIAN=P0^5; //小數點 bit bdata shanshuo_st; //閃爍間隔標志 bit bdata beep_st; //蜂鳴器間隔標志 uc x=0; //計數器 ui bai,shi,ge; uc set_st=0; //狀態標志 char shangxian,xiaxian; codeLEDData[]={0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7,0xCF,0xDA,0x9B,0xDC,0x9B,0x8B}; //====================================DS18B20========================================= /*****延時子程序*****/ void Delay_DS18B20(int num) { while(num--); } void delay()//5微秒延時函數 { ;; } void start() //開始信號 { SDA=1; delay(); SCL=1; delay(); SDA=0; delay(); } void stop() //終止信號 { SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); } void respons() //應答 { uc i; SCL=1; delay(); while((SDA==1)&&(i<250))i++;//如果SDA為低應答有效,或者超過一定時間默認應答有效 SCL=0; delay(); } void init24c04()//I2C總線初始化 { SDA=1; delay(); SCL=1; delay(); } void write_byte(uc date)//寫操作 { uc i,temp; temp=date; for(i=0;i<8;i++) { temp=temp<<1; SCL=0; delay(); SDA=CY; delay(); SCL=1; delay(); } SCL=0; delay(); SDA=1; delay(); } uc read_byte()//讀操作 { uc i,k; SCL=0; delay(); SDA=1; delay(); for(i=0;i<8;i++) { SCL=1; delay(); k=(k<<1)|SDA; SCL=0; delay(); } return k; } void write_add(uc address,uc date)//往任意地址存數據 { start(); write_byte(0xa0);//0xa0代表寫入 respons(); write_byte(address); respons(); write_byte(date); respons(); stop(); } uc read_add(uc address)//讀隨意地址內容 { uc date; start(); write_byte(0xa0);//0xa0代表寫入 respons(); write_byte(address); respons(); start(); write_byte(0xa1);//0xa1代表讀出 respons(); date=read_byte(); stop(); returndate;//返回值 } /*****初始化DS18B20*****/ void Init_DS18B20(void) { uc w=0; DQ = 1; //DQ復位 Delay_DS18B20(8); //稍做延時 DQ = 0; //單片機將DQ拉低 Delay_DS18B20(80); //精確延時,大于480us DQ = 1; //拉高總線 Delay_DS18B20(14); w = DQ; //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗 Delay_DS18B20(20); } /*****讀一個字節*****/ unsigned char ReadOneChar(void) { uc i=0; uc dat = 0; for(i=8;i>0;i--) { DQ =0; // 給脈沖信號 dat>>=1; DQ =1; // 給脈沖信號 if(DQ) dat|=0x80; Delay_DS18B20(4); } return(dat); } /*****寫一個字節*****/ void WriteOneChar(uc dat) { uc i=0; for (i=8;i>0; i--) { DQ = 0; DQ =dat&0x01; Delay_DS18B20(5); DQ = 1; dat>>=1; } } /*****讀取溫度*****/ ui ReadTemperature(void) { ui b=0; float tt=0; Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號列號的操作 WriteOneChar(0x44); //啟動溫度轉換 Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號列號的操作 WriteOneChar(0xBE); //讀取溫度寄存器 a=ReadOneChar(); //讀低8位 b=ReadOneChar(); //讀高8位 t=b; t<<=8; t=t|a; tt=t*0.0625; t=tt*10+0.5; //放大10倍輸出并四舍五入 return(t); } /*****延時子程序*****/ void Delay(ui num) { while( --num); } /*****初始化定時器0*****/ void InitTimer(void) { TMOD=0x01; TH0=0x3c; TL0=0xb0; //50ms(晶振12M) } /*****讀取溫度*****/ void check_wendu(void) { ui f; f=ReadTemperature()-5; //獲取溫度值并減去DS18B20的溫漂誤差 if(f<0)f=0; if(f>999)f=999; bai=f/100; //計算得到十位數字 shi=(f%100)/10; //計算得到個位數字 ge=(f%100)%10; //計算得到整數位 } /*****顯示開機初始化等待畫面*****/ void Disp_init(void) { P0 =~0x80; //顯示---- P2 = 0x7F; Delay(200); P2 = 0xDF; Delay(200); P2 = 0xF7; Delay(200); P2 = 0xFD; Delay(200); P2 =0xFF; //關閉顯示 } /*****顯示溫度子程序*****/ void Disp_Temperature(void) //顯示溫度 { P0 =~0x98; //顯示C P2 = 0x7F; Delay(400); P0=~LEDData[ge]; //顯示個位 P2 = 0xDF; Delay(400); P0=~LEDData[shi]; //顯示十位 DIAN =0; //顯示小數點 P2 = 0xF7; Delay(400); P0=~LEDData[bai]; //顯示百位 P2 = 0xFD; Delay(400); P2 =0xff; //關閉顯示 } /*****顯示報警溫度子程序*****/ void Disp_alarm(uc baojing) { P0=~0x98; //顯示C P2 = 0x7F; Delay(200); P0=~LEDData[baojing%10]; //顯示十位 P0=~LEDData[baojing/10]; //顯示百位 P2 = 0xF7; Delay(200); if(set_st==1)P0=~0xCE; elseif(set_st==2)P0 =~0x1A; //上限H、下限L標示 P2 = 0xFD; Delay(200); P2 =0xff; //關閉顯示 } /*****報警子程序*****/ void Alarm() { if(x>=10){beep_st=~beep_st;x=0;} if((bai*10+shi)>=shangxian&&beep_st==1) { BEEP=0; ALAM1=0; } elseif((bai*10+shi)>=shangxian&&beep_st==0) { BEEP=1; ALAM1=0; } if((bai*10+shi)<xiaxian&&beep_st==1) { BEEP=0; ALAM=0; } elseif((bai*10+shi)<xiaxian&&beep_st==0) { BEEP=1; ALAM=0; } if(((bai*10+shi)<shangxian)&&((bai*10+shi)>=xiaxian)) { BEEP=1; ALAM1=1; ALAM=1; } } /*****主函數*****/ void main(void) { ui z; InitTimer(); //初始化定時器 EA=1; //全局中斷開關 TR0=1; ET0=1; //開啟定時器0 check_wendu(); check_wendu(); shangxian=read_add(10); xiaxian=read_add(20); for(z=0;z<300;z++) { Disp_init(); } while(1) { if(SET==0) { Delay(2000); do{} while(SET==0); set_st++;x=0;shanshuo_st=1; if(set_st>2)set_st=0; } if(set_st==0) { check_wendu(); Disp_Temperature(); Alarm(); //報警檢測 } elseif(set_st==1) { BEEP=1; //關閉蜂鳴器 ALAM=1; ALAM1=1; if(x>=10){shanshuo_st=~shanshuo_st;x=0;} if(shanshuo_st){Disp_alarm(shangxian);} if(ADD==0) { do{Disp_alarm(shangxian);} shangxian++; if(shangxian>99)shangxian=99; write_add(10,shangxian); } elseif(DEC==0) { do{Disp_alarm(shangxian);} while(DEC==0); shangxian--; if(shangxian<xiaxian)shangxian=xiaxian; write_add(10,shangxian); } } else if(set_st==2) { BEEP=1; //關閉蜂鳴器 ALAM=1; ALAM1=1; if(x>=10){shanshuo_st=~shanshuo_st;x=0;} if(shanshuo_st){Disp_alarm(xiaxian);} if(ADD==0) { do{Disp_alarm(xiaxian);} while(ADD==0); xiaxian++; if(xiaxian>shangxian)xiaxian=shangxian; write_add(20,xiaxian); } elseif(DEC==0) { do{Disp_alarm(xiaxian);} while(DEC==0); xiaxian--; if(xiaxian<0)xiaxian=0; write_add(20,xiaxian); } } } } /*****定時器0中斷服務程序*****/ void timer0(void) interrupt 1 { TH0=0x3c; TL0=0xb0; x++; }file:///C:/Users/Lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image001.giffile:///C:/Users/Lenovo/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif
|