STC12C4052單片機測溫報警器 作者: Odie 1)核芯元件: STC12C4052單片機1PCS,DS18B20 1PCS,共陰極數碼管2PCS。 2)電路圖: file:///C:/Users/odie/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg 備注:圖示用的是80C51,只需按接點對應到STC12C4052上即可。D1報警可以換成三極管+蜂鳴器,即可聽到聲音。 3)功能說明: 3.1)37.帶點顯示為實測試溫度。 3.2)按1次P34按鍵可以到達設定報警溫度面,此面顯示不帶點。 按2次P34按鍵可以到達十位加(加用按鍵P35數字0-9循環)。 按3次P34按鍵可以到達個位加(加用按鍵P35數字0-9循環)。 按4次P34按鍵返回實測溫度顯示界面。 3.3)設定溫度寫入到EEPROM中,掉電不丟失。 4)C程序: #include<STC12C2052AD.H> typedefunsigned char u8; typedefunsigned int u16; u8 a2,a3; u8 i=0; u16WD1=0x46,WD2=0Xb9; #defineENABLE_ISP 0X83 #defineDATAP1 P1 #define LEDP3P3 sbitLED0= P3^2; sbitLED1= P3^3; sbit KY0=P3^4; sbit KY1=P3^5; sbit DQ=P3^7; sbitLED_DY= P3^1; //報警輸出腳 u8 codeseg_tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數碼管顯示代碼 voiddelay1ms(u16 c) //1ms延時11.0592MHz不分頻用于STC12單片機誤差 -0.018084490741us { unsigned char a,b; for(c;c>0;c--) for(b=106;b>0;b--) for(a=20;a>0;a--); } voiddelay1us(u16 a) //1us延時11.0592MHz不分頻用于STC12單片機 誤差 -0.005353009259us { for(a+2;a>0;a--); } voiddisplay_LEDX4(u8 a,u8 b) //正常實際溫度顯示函數 { LED0=0; DATAP1=seg_tab[a]; delay1ms(2); LED0=1; LED1=0; DATAP1=seg_tab+0x80; delay1ms(2); LED1=1; } voiddisplay_LEDX4_A(u8 a,u8 b) //設定溫度顯示函數去點 { LED0=0; DATAP1=seg_tab[a]; delay1ms(5); LED0=1; LED1=0; DATAP1=seg_tab; delay1ms(5); LED1=1; } voiddisplay_LEDX4_B(u8 a,u8 b) //十位加1時顯示函數個位閃爍 { LED0=0; DATAP1=seg_tab[a]; delay1ms(8); LED0=1; delay1ms(1); LED1=0; DATAP1=seg_tab; delay1ms(1); LED1=1; } voiddisplay_LEDX4_C(u8 a,u8 b) //個位加1時顯示函數個位閃爍 { LED0=0; DATAP1=seg_tab[a]; delay1ms(1); LED0=1; delay1ms(1); LED1=0; DATAP1=seg_tab; delay1ms(8); LED1=1; } /*DS18B20函數*/ voidReset(void) //初始化函數 { u8 x=0; do{ DQ=1; delay1us(10); DQ=0; delay1us(600); DQ=1; delay1us(100); x=DQ; delay1us(10); }while(0); delay1us(400); } voidWriteBit(char val) //位寫入函數 { DQ=0; if(val==1) DQ=1; //寫1 else DQ=0; //寫1 delay1us(60); DQ=1; } void WriteByte(charval) //字節寫入函數 { u8 i,j; for (i=0;i<8;i++) { j=val>>i; j&=0x01; WriteBit(j); } } u8ReadBit(void) //位讀取函數 { DQ=0; DQ=1; delay1us(10); if(DQ) return 1; else return 0; } u8ReadByte(void) //字節讀取函數 { u8 i; u8 value=0; for (i=0;i<8;i++) { if(ReadBit()) value|=0x01<<i; else ; delay1us(60); } return(value) ; } u16Readtemp(void) //溫度讀取函數 { u8 i=0; u8 j=0; u16 temp,temp1; Reset( ); WriteByte(0xcc); //跳過ROM WriteByte(0x44); //溫度轉換 delay1ms(1); Reset( ); WriteByte(0xcc); WriteByte(0xbe); //讀暫存器 i=ReadByte( ); j=ReadByte( ); temp=j*256+i; temp1=temp*0.0625; return temp1; } u8KYO_HS(void) //按鍵P34函數3種狀態 { if (KY0 == 0) {delay1ms(10); if (KY0 == 0) i++;} if(i>3) i=0; while(!KY0); return i; } u8KY1_HS(u8 j ) //按鍵P35函數位數+1 { if (KY1 == 0) {delay1ms(10); if (KY1 == 0) j++;} if(j>9) j=0; while(!KY1); return j; } //關閉IAP voidIAP_Disable() { IAP_CONTR=0; IAP_CMD=0; IAP_TRIG=0; IAP_ADDRH=0; IAP_ADDRL=0; } //讀一字節 調用前打開IAP u16Byte_read(u16 add) // 從EEPROM讀數據 { IAP_DATA=0X00; IAP_CONTR=ENABLE_ISP; //打開IAP IAP_CMD =0X01; IAP_ADDRH =add/256; IAP_ADDRL =add%256; IAP_TRIG =WD1; IAP_TRIG =WD2; delay1us(10); IAP_Disable(); return (IAP_DATA); } //字節編程 voidByte_write(u16 add,u16 ch) //數據寫入EEPROM { IAP_CONTR =ENABLE_ISP; IAP_CMD =0X02; IAP_ADDRH=add/256; IAP_ADDRL =add%256; IAP_DATA=ch; IAP_TRIG =WD1; IAP_TRIG =WD2; delay1us(10); IAP_Disable(); } //擦除扇區 voidsector_Erase(u16 add) { IAP_CONTR =ENABLE_ISP; IAP_CMD =0X03; //功能定義 IAP_ADDRH=add/256; IAP_ADDRL=add%256; IAP_TRIG =WD1; IAP_TRIG =WD2; delay1us(10); IAP_Disable(); } void main(void) { u8 a0,a1; u16 b,b0,b1; u8 table0,table1; P1M0=0x00; P1M1=0xFF; P3M0=0x00; P3M1=0x02; LEDP3=0x00; IDLE_CLK=0x00; //單片機時間分頻寄存器 Readtemp( ); DATAP1=0xFF; //上電LED全亮 亮500MS滅500MS LED_DY=1; delay1ms(500); DATAP1=0x00; LED_DY=0; delay1ms(500); LED_DY=1; KY0=1; KY1=1; while (1) { a2=Byte_read(0x200)%256; a3=Byte_read(0x0000)%256; if (KYO_HS( ) == 1) //按鍵狀態1顯示設置溫度無個位數點 { display_LEDX4_A(a2,a3); } if (KYO_HS( ) == 2) //按鍵狀態2十位+1設置 { display_LEDX4_B(a2,a3); a2=KY1_HS(a2); sector_Erase(0x200); Byte_write(0x200,a2); } if (KYO_HS( ) == 3) //按鍵狀態3個位+1設置 { display_LEDX4_C(a2,a3); a3=KY1_HS(a3); sector_Erase(0x0000); Byte_write(0x0000,a3); } b1=a2*256+a3; if(KYO_HS( )== 0){ b=Readtemp( ); table1=b/10; table0=b%10; a0=table1; a1=table0; display_LEDX4(a0,a1); //實測溫度顯示 b0=a0*256+a1; } if(b0>=b1) { LED_DY=1; } else LED_DY=0; } }
|