3.png (323.07 KB, 下載次數(shù): 31)
下載附件
2019-5-30 18:02 上傳
#include <AT89C51.h> #define unchar unsigned char #define uint unsigned int uchar Tem1,Tem2,Smok1,Smok2; #include "intrins.h" //_nop_();延時(shí)函數(shù)用 #define Disdata P0 //段碼輸出口 #define discan P2 //掃描口 #define uchar unsigned char #define uint unsigned int sbit DQ=P3^3; //溫度輸入口 sbit DIN=P0^7; //LED小數(shù)點(diǎn)控制 uint h; uchar flag; void caiji_wenyan(); void delay(uint x); void delay_10ms(uint i); //程序聲明 void panduan(); void baojing(); //**************溫度小數(shù)部分用查表法***********// uchar code ditab[16]= {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; // uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //共陰LED段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列掃描控制字 uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫放 uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //顯示單元數(shù)據(jù),共4個(gè)數(shù)據(jù)和一個(gè)運(yùn)算暫用
/***********11微秒延時(shí)函數(shù)**********/ // void delay(uint t) { for(;t>0;t--); } // /***********顯示掃描函數(shù)**********/ scan() { char k; for(k=0;k<4;k++) //四位LED掃描控制 { Disdata=0xff; Disdata=dis_7[display[k]]; if(k==1){DIN=0;} discan=scan_con[k];delay(90); discan=0xff; } } // // /***********18B20復(fù)位函數(shù)**********/ ow_reset(void) { char presence=1; while(presence) { while(presence) { DQ=1;_nop_();_nop_(); DQ=0; // delay(50); // 550us DQ=1; // delay(6); // 66us presence=DQ; // presence=0繼續(xù)下一步 } delay(45); //延時(shí)500us presence = ~DQ; } DQ=1; } // // /**********18B20寫(xiě)命令函數(shù)*********/ //向 1-WIRE 總線上寫(xiě)一個(gè)字節(jié) void write_byte(uchar val) { uchar i; for (i=8; i>0; i--) // { DQ=1;_nop_();_nop_(); DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出 delay(6); //66us val=val/2; //右移一位 } DQ = 1; delay(1); } // /*********18B20讀1個(gè)字節(jié)函數(shù)********/ //從總線上讀取一個(gè)字節(jié) uchar read_byte(void) { uchar i; uchar value = 0; for (i=8;i>0;i--) { DQ=1;_nop_();_nop_(); value>>=1; DQ = 0; // _nop_();_nop_();_nop_();_nop_(); //4us DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us if(DQ)value|=0x80; delay(6); //66us } DQ=1; return(value); } // /***********讀出溫度函數(shù)**********/ // read_temp() { ow_reset(); //總線復(fù)位 write_byte(0xCC); // 發(fā)Skip ROM命令 write_byte(0xBE); // 發(fā)讀命令 temp_data[0]=read_byte(); //溫度低8位 temp_data[1]=read_byte(); //溫度高8位 ow_reset(); write_byte(0xCC); // Skip ROM write_byte(0x44); // 發(fā)轉(zhuǎn)換命令 } // /***********溫度數(shù)據(jù)處理函數(shù)**********/ void work_temp() { uchar n=0; uchar doth,dotl; uchar flag3=1,flag2=1; //數(shù)字顯示修正標(biāo)記 if((temp_data[1]&0xf8)!=0x00) { temp_data[1]=~(temp_data[1]); temp_data[0]=~(temp_data[0])+1; n=1; flag=1; }//負(fù)溫度求補(bǔ)碼 if(temp_data[0]>255) { temp_data[1]++; } display[4]=temp_data[0]&0x0f; display[0]=ditab[display[4]]; doth=display[0]/10; dotl=display[0]%10; display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4); display[3]=display[4]/100; display[2]=display[4]/10%10; display[1]=display[4]%10; if(!display[3]) { display[3]=0x0a; flag3=0; if(!display[2]) { display[2]=0x0a; flag2=0; } }//最高位為0時(shí)都不顯示 if(n) { display[3]=0x0b;//負(fù)溫度時(shí)最高位顯示"-" flag3=0; } } Disdata=0xff; //初始化端口 discan=0xff; for(h=0;h<4;h++){display[h]=8;}//開(kāi)機(jī)顯示8888 ow_reset(); // 開(kāi)機(jī)先轉(zhuǎn)換一次 write_byte(0xCC); // Skip ROM write_byte(0x44); // 發(fā)轉(zhuǎn)換命令 for(h=0;h<500;h++) {scan();} //開(kāi)機(jī)顯示"8888"2秒 while(1) { read_temp(); //讀出18B20溫度數(shù)據(jù) work_temp(); //處理溫度數(shù)據(jù)
scan(); //顯示溫度值2秒 m=3.6,Smok=4.6; //設(shè)定溫度煙霧報(bào)警閾值 uchar i ,a1,a2,b,b1,b2; extern unsigned int idata Temperature; // 聲明引用外部變量 extern GetTemp(); //聲明引用外部函數(shù) void caiji_wenyan(); void delay(uint x); void delay_10ms(uint i); //程序聲明 void panduan(); void baojing(); void main() { uchar i; TMOD|= 0x11;TH1=0xDC;TL1=0x00; IE = 0x8A;TR1=1; P26=0;P20=0;WR=1;RD=1; P0=0XFa;P23=1;P24=1;P25=1;P22=0; //初始化 while(1) //主程序 { caiji _wenyan (); //第一次采集煙霧信號(hào) GetTemp(); //第一次采集溫度信號(hào) Temp2=Temperature; Smok2=Smok1; delay_10ms(5); //延時(shí)50ms,讓ADC0809準(zhǔn)備好第二次數(shù)據(jù)轉(zhuǎn)換 caiji _wenyan(); //第二次采集煙霧信號(hào) GetTemp(); //第二次采集溫度信號(hào) Temp1=Temperature; panduan(); //將轉(zhuǎn)換的數(shù)據(jù)與設(shè)定的報(bào)警閾值比較 baojing(); //報(bào)警程序 delay_10ms(1500); //系統(tǒng)隔15s對(duì)現(xiàn)場(chǎng)判斷 }; } void caiji_wenyan() { WR=0; if(EOC=1) {RD=0;Smok1=P0}; else RD=1; }
void delay_10ms(uint i) //10ms延時(shí)程序 { while(i--) { uchar i,j,k; for(i=5;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } }
void panduan() { if(Tem1>Tem) a1=1; //當(dāng)采集的溫度高于閾值置1,否則,置0 else a1=0; if(Tem2>Tem) a2=1; else a2=0; if(Smok1>Smok) b1=1; //當(dāng)采集的煙霧濃度高于閾值置1,否則,置0 else b1=0; if(Smok2>Smok) b2=1; else b2=0; }
baojing() { if(a1=a2&&b1=b2) //兩次采集數(shù)據(jù)的標(biāo)志位相同 { a=a1; b=b1; if(a=1&&b=1) {P24=0;P26=1;P22=1}; //溫度煙霧標(biāo)志位都是1,發(fā)生火災(zāi) if(a=1&&b=0) {P25=0;P26=1;P22=1}; if(a=0&&b=1) {P25=0;P26=1;P22=1}; //溫度煙霧標(biāo)志位只有一個(gè)1,異常 if(a=0&&b=0) P22=0; //溫度煙霧標(biāo)志位都為0,正常 }; else {P23=0;P26=1;P22=1} //兩次采集的數(shù)據(jù)標(biāo)志位不同,系統(tǒng)故障。 void read_bytes (unsigned char idata j) //讀18B20 { unsigned char idata i; for(i=0;i<j;i++) { *p = ReadByte(); p++; } } void GemTemp (void) //讀取溫度 { read_bytes (9); if (CRC(9)==0) //校驗(yàn)正確 { Temperature = temp_buff[1]*0x100 + temp_buff[0]; Temperature *= 0.625; Temperature /= 16; TempDelay(1); } } void TemperatuerResult(void) 18B20ID全處理 { p = id_buff; ReadID(); Config18b20(); Init18b20 (); WriteByte(0xcc); //skip rom WriteByte(0x44); //Temperature convert
Init18b20 (); WriteByte(0xcc); //skip rom WriteByte(0xbe); //read Temperature p = temp_buff; GemTemp(); }
unsigned int TempTick=0; void GetTemp() //獲取溫度值 { if(TIM==1) { TIM=0; TemperatuerResult(); D[5]=Temperature; } }
|