#include<reg51.h> #include<intrins.h> #define dm P0 //段碼輸出口 #define uchar unsigned char #define uint unsigned int sbit DQ=P2^7; //溫度輸入口 sbit w0=P2^0; //數碼管4 sbit w1=P2^1; //數碼管3 sbit w2=P2^2; //數碼管2 sbit w3=P2^3; //數碼管1 sbit beep=P3^7; //蜂鳴器 sbit yellow=P1^0; //指示燈 sbit led=P1^1; // 高溫指示燈 sbit set=P3^0; //低溫指示燈 sbit add=P3^1; sbit dec=P3^2; int temp1=0; uint h; uint temp; uchar r; uchar high=100,low=25; uchar sign; uchar q=0; uchar tt=0; uchar scale; uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04, 0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //小數斷碼表 uchar code table_dm[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d, 0x7d,0x07,0x7f,0x6f,0x00,0x40}; //共陰LED段碼表"0""1""2""3""4""5""6""7""8""9""不亮""-" uchar code table_dm1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //個位帶小數點的斷碼表 uchar data temp_data[2]={0x00,0x00};//讀出溫度暫放 uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//顯示單元數據,共四個數據和一個運算暫用 /***************11us延時函數***************/ void delay(uint t) { for(;t>0;t--); } void scan() { int j; for(j=0;j<4;j++) { switch(j) { case 0: dm=table_dm[display[0]];; w0=0; delay(300); w0=1; //小數點 case 1: dm=table_dm1[display[1]]; w1=0; delay(300); w1=1; //個位 case 2: dm=table_dm[display[2]]; w2=0; delay(300); w2=1; //十位 case 3: dm=table_dm[display[3]]; w3=0; delay(300); w3=1; //百位 } } } /**************DS18B20初始化**************/ ow_reset(void) { char presence=1; while(presence) { while(presence) { DQ=1;_nop_();_nop_(); DQ=0; delay(50); DQ=1; delay(6); presence=DQ; } delay(45); presence=~DQ; } DQ=1; return presence; } /****************寫命令函數*****************/ void write_byte(uchar val) { uchar i; for(i=8;i>0;i--) { DQ=1;_nop_();_nop_(); DQ=0;_nop_();_nop_();_nop_();_nop_(); DQ=val&0x01; delay(6); val=val>>1; } DQ=1; delay(1); } /****************讀一個字節函數*******************/ 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_(); DQ=1;_nop_();_nop_();_nop_();_nop_(); if(DQ)value|=0x80; delay(6); } DQ=1; return value; } /***************讀取溫度函數***************/ read_temp() { ow_reset(); delay(200); write_byte(0xcc); write_byte(0x44); ow_reset(); delay(1); write_byte(0xcc); write_byte(0xbe); temp_data[0]=read_byte(); temp_data[1]=read_byte(); temp=temp_data[1]; temp<<=8; temp=temp|temp_data[0]; return temp; } /***************溫度數據處理函數***************/ work_temp(uint tem) { uchar n=0; if(tem>6348) { tem=65536-tem; n=1; } display[4]=tem&0x0f; display[0]=ditab[display[4]]; display[4]=tem>>4; display[3]=display[4]/100; display[1]=display[4]%100; display[2]=display[1]/10; display[1]=display[1]%10; r=display[1]+display[2]*10+display[3]*100; if(!display[3]) { display[3]=0x0a; if(!display[2]) { display[2]=0x0a; } } if(n) { display[3]=0x0b; } return n; } /***************報警提示電路***************/ void BEEP() { if(r>=high&&r<129) { led=0; } else { led=1; } if(r<low) { yellow=~yellow; } else { yellow=1; } if((r>=high&&r<129)||(r<low)) { beep=!beep; } else { beep=1; }} /***************溫度顯示轉換**************/ void xianshi(int horl) { int n=0; if(horl>128) { horl=256-horl; n=1; } display[3]=horl/100; display[3]=display[3]&0x0f; display[2]=horl%100/10; display[1]=horl%10; display[0]=0; if(!display[3]) { display[3]=0x0a; if(!display[2]) { display[2]=0x0a; } } if(n) { display[3]=0x0b; } } /**************按鍵設置*************/ void keyscan() { int temp1; //最高溫度和最低溫度標志位 if(set==0) { while(1) { delay(500);//消抖 if(set==0) { temp1++; while(!set) scan(); } if(temp1==1) { xianshi(high); scan(); if(add==0) { while(!add) scan(); high+=1; } if(dec==0) { while(!dec) scan(); high-=1; } } if(temp1==2) { xianshi(low); if(add==0) { while(!add) scan(); low+=1; } if(dec==0) { while(!dec) scan(); low-=1; } scan(); } if(temp1>=3) { temp1=0; break; } } } } /**************主函數*************/ void main() { dm=0x00; w0=0; w1=0; w2=0; w3=0; for(h=0;h<4;h++) { display[h]=0; } ow_reset(); write_byte(0xcc); write_byte(0x44); for(h=0;h<100;h++) { scan(); } while(1) { if(temp1==0) { work_temp(read_temp()); scan(); BEEP(); keyscan(); } else keyscan(); } } |