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; } }
|