自动温度报警器(毕设援助)
- 格式:docx
- 大小:1.63 MB
- 文档页数:15
自动温度报警器报警(毕设援助)一、简介:该温度报警器采用+5V,500~700mA直流电源供电。
数码管的显示范围是0~99℃,温度误差是±0.5℃。
上电自动读取当前环境温度并检测是否超过设定的温度范围,若超过则蜂鸣器会报警。
首次使用需要设置报警温度的上下限,设置后会自动保存到EEPROM中,断电也不会丢失数据,下次上电后自动从EEPROM 中读取上次设置的报警上下限。
报警器从左到又有四个按键,分别是“设置键”,“下调键”,“上调键”和“复位键”。
按一次“设置”键进入上限温度设置,通过上调和下调键来调节。
设置好上限后再按一次则进入下限温度设置,同样是通过上调和下调键调节,按第三次“设置”则退出设置。
即按一次“设置键”设置上限温度,按第二次“设置键”设置下限温度,按第三次“设置键”退出设置。
二、成品外观图:工作中设置报警温度上限,“H”表示“高温”设置报警温度下限,“L”表示“低”上电和按下“复位键”后的界面背面:三、源程序主程序(main.c)/******************************************************************程序名称:DS18B20温度测量、报警系统简要说明:DS18B20温度计,温度测量范围0~99.9摄氏度可用按键设置上限报警温度、下限报警温度即高于上限值或者低于下限值时蜂鸣器报警默认上限报警温度为38℃、默认下限报警温度为5℃报警值可设置范围:最低上限报警值等于当前下限报警值最高下限报警值等于当前上限报警值将下限报警值调为0时为关闭下限报警功能******************************************************************/#include <AT89X52.h>#include<STC89C52_EEPROM.H>#include "DS18B20.h"#define uint unsigned int#define uchar unsigned char //宏定义#define SET P3_1 //定义调整键#define DEC P3_2 //定义减少键#define ADD P3_3 //定义增加键#define BEEP P3_7 //定义蜂鸣器bit shanshuo_st; //闪烁间隔标志bit beep_st; //蜂鸣器间隔标志sbit DIAN = P2^7; //小数点uchar x=0; //计数器signed char m; //温度值全局变量uchar n; //温度值全局变量uchar set_st=0; //状态标志unsigned int shangxian=38; //上限报警温度,默认值为38unsigned int xiaxian=5; //下限报警温度,默认值为38uchar code LEDData[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};/***写入报警阀值到EEPROM***/void eeprom(uint datup,datlow){IapEraseSector(0x2000); //擦除0x2000扇区的内容IapProgramuchar(0x2002,datup/256); //在0x2002地址上写入报警上限温度的十位数IapProgramuchar(0x2003,datup%256); //在0x2003地址上写入报警上限温度的个位数IapProgramuchar(0x2004,datlow/256); //在0x2004地址上写入报警下限温度的十位数IapProgramuchar(0x2005,datlow%256); //在0x2005地址上写入报警下限温度的个位数}/*****延时子程序*****/void Delay(uint num){while( --num );}/*****初始化定时器0*****/void InitTimer(void){TMOD=0x1;TH0=0x3c;TL0=0xb0; //50ms(晶振12M)}/*****定时器0中断服务程序*****/void timer0(void) interrupt 1{TH0=0x3c;TL0=0xb0;x++;}/*****外部中断0服务程序*****/void int0(void) interrupt 0{EX0=0; //关外部中断0if(DEC==0&&set_st==1){shangxian--;if(shangxian<xiaxian)shangxian=xiaxian;}else if(DEC==0&&set_st==2){xiaxian--;if(xiaxian<0)xiaxian=0;}eeprom(shangxian,xiaxian); //写入报警阀值到EEPROM }/*****外部中断1服务程序*****/void int1(void) interrupt 2{EX1=0; //关外部中断1if(ADD==0&&set_st==1){shangxian++;if(shangxian>99)shangxian=99;}else if(ADD==0&&set_st==2){xiaxian++;if(xiaxian>shangxian)xiaxian=shangxian;}eeprom(shangxian,xiaxian); //写入报警阀值到EEPROM}/*****读取温度*****/void check_wendu(void){uint a,b,c;c=ReadTemperature()-0.5; //获取温度值并减去DS18B20的温漂误差a=c/100; //计算得到十位数字b=c/10-a*10; //计算得到个位数字m=c/10; //计算得到整数位n=c-a*100-b*10; //计算得到小数位if(m<0){m=0;n=0;} //设置温度显示上限if(m>99){m=99;n=9;} //设置温度显示上限}/*****显示开机初始化等待画面*****/void Disp_init(){P2 = 0xbf; //显示-P1 = 0xf7;Delay(200);P1 = 0xfb;Delay(200);P1 = 0xfd;Delay(200);P1 = 0xfe;Delay(200);P1 = 0xff; //关闭显示}/*****显示温度子程序*****/void Disp_Temperature() //显示温度{P2 =0xc6; //显示CP1 = 0xf7;Delay(200);P1 = 0xff;P2 =LEDData[n]; //显示个位P1 = 0xfb;Delay(200);P2 =LEDData[m%10]; //显示十位DIAN = 0; //显示小数点P1 = 0xfd;Delay(200);P1 = 0xff;P2 =LEDData[m/10]; //显示百位P1 = 0xfe;Delay(200);P1 = 0xff; //关闭显示}/*****显示报警温度子程序*****/void Disp_alarm(uchar baojing){P2 =0xc6; //显示CP1 = 0xf7;Delay(200);P1 = 0xff;P2 =LEDData[baojing%10]; //显示十位P1 = 0xfb;Delay(200);P1 = 0xff;P2 =LEDData[baojing/10]; //显示百位P1 = 0xfd;Delay(200);P1 = 0xff;if(set_st==1)P2 =0x89;else if(set_st==2)P2 =0xc7; //上限H、下限L标示P1 = 0xfe;Delay(200);P1 = 0xff; //关闭显示}/*****报警子程序*****/void Alarm(){if(x>=10){beep_st=~beep_st;x=0;}if((m>=shangxian&&beep_st==1)||(m<xiaxian&&beep_st==1))BEEP=0; else BEEP=1;}/*****主函数*****/void main(void)shangxian=IapReaduchar(0x2002)*256+IapReaduchar(0x2003); //读取掉电前温度上限xiaxian=IapReaduchar(0x2004)*256+IapReaduchar(0x2005);//读取掉电前温度下限InitTimer(); //初始化定时器EA=1; //全局中断开关TR0=1; //开启定时器0ET0=1; //开启定时器中断IT0=1; // 中断外部0触发方式控制位,0表示电平触发,1表示边沿触发方式(下降沿有效)IT1=1; //同上一条语句类似check_wendu();check_wendu();for(z=0;z<300;z++){Disp_init();}while(1){if(SET==0){Delay(200);do{}while(SET==0);set_st++;x=0;shanshuo_st=1;if(set_st>2)set_st=0;}if(set_st==0){EX0=0; //关闭外部中断0EX1=0; //关闭外部中断1check_wendu();Disp_Temperature();Alarm(); //报警检测}else if(set_st==1){BEEP=1; //关闭蜂鸣器EX0=1; //开启外部中断0EX1=1; //开启外部中断1if(x>=10){shanshuo_st=~shanshuo_st;x=0;}if(shanshuo_st){Disp_alarm(shangxian);}}else if(set_st==2){BEEP=1; //关闭蜂鸣器EX0=1; //开启外部中断0EX1=1; //开启外部中断1if(x>=10){shanshuo_st=~shanshuo_st;x=0;}if(shanshuo_st) {Disp_alarm(xiaxian);}}}}/*****END*****/头文件(DS18B20.H)#include <AT89X52.h>#define DQ P3_6 //定义DS18B20总线I/O/*****延时子程序*****/void Delay_DS18B20(int num){while(num--) ;}/*****初始化DS18B20*****/void Init_DS18B20(void){unsigned char x=0;DQ = 1; //DQ复位Delay_DS18B20(8); //稍做延时DQ = 0; //单片机将DQ拉低Delay_DS18B20(80); //精确延时,大于480usDQ = 1; //拉高总线Delay_DS18B20(14);x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败Delay_DS18B20(20);}/*****读一个字节*****/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char 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(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;Delay_DS18B20(5);DQ = 1;dat>>=1;}}/*****读取温度*****/unsigned int ReadTemperature(void){unsigned char a=0;unsigned char b=0;unsigned int t=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);}/*****END*****/掉电保存头文件(STC89C52_EEPROM.H)#include "intrins.h"#define uchar unsigned char /*宏定义字符型数据整型数据*/#define uint unsigned int/*声明SFR与IAP */sfr IAP_DATA = 0xE2; //Flash数据寄存器sfr IAP_ADDRH = 0xE3; //Flash地址高字节sfr IAP_ADDRL = 0xE4; //Flash地址低字节sfr IAP_CMD = 0xE5; //Flash命令寄存器sfr IAP_TRIG = 0xE6; //Flash命令触发sfr IAP_CONTR = 0xE7; //Flash控制寄存器/*定义ISP / IAP / EEPROM命令*/#define CMD_IDLE 0 //待用#define CMD_READ 1 //字节读#define CMD_PROGRAM 2 //字节编程#define CMD_ERASE 3 //扇区擦除/*定义ISP / IAP / EEPROM的操作常量IAP_CONTR*/#define ENABLE_IAP 0x80 //if SYSCLK<40MHz//#define ENABLE_IAP 0x81 //if SYSCLK<20MHz//#define ENABLE_IAP x82 //if SYSCLK<10MHz//#define ENABLE_IAP 0x83 //if SYSCLK<5MHz//起始地址STC89C58xx EEPROM#define IAP_ADDRESS 0x2000void IapIdle();uchar IapReaduchar(uint addr);void IapProgramuchar(uint addr, uchar dat);void IapEraseSector(uint addr);/*----------------------------禁止ISP / IAP / EEPROM功能MCU处于安全状态----------------------------*/void IapIdle(){IAP_CONTR = 0; //关闭IAP功能IAP_CMD = 0; //清除命令到待机状态IAP_TRIG = 0; //清除触发寄存器IAP_ADDRH = 0x80; //数据指针指向非EEPROM区IAP_ADDRL = 0; //清除IAP地址,以防止误操作}/*----------------------------从ISP / IAP / EEPROM区中读取一个字节输入:地址(ISP / IAP / EEPROM地址)输出:Flash数据----------------------------*/uchar IapReaduchar(uint addr){uchar dat; //数据缓冲IAP_CONTR = ENABLE_IAP; //打开IAP功能,并设置等待时间IAP_CMD = CMD_READ; //设置ISP / IAP / EEPROM读命令IAP_ADDRL = addr; //设置ISP / IAP / EEPROM地址低字节IAP_ADDRH = addr >> 8; //设置ISP / IAP / EEPROM地址高字节IAP_TRIG = 0x46; //发送触发命令(0x46)IAP_TRIG = 0xb9; //发送触发命令(0xb9)_nop_(); //MCU将在这里等待,直到ISP / IAP / EEPROM 操作完成dat = IAP_DATA; //ISP / IAP / EEPROM数据IapIdle(); //关闭ISP / IAP / EEPROM功能return dat; //返回闪存数据}/* ----------------------------编程一个字节的ISP / IAP / EEPROM区输入:地址(ISP / IAP / EEPROM地址)DAT(ISP / IAP / EEPROM数据)输出:-----------------------------*/void IapProgramuchar(uint addr, uchar dat){IAP_CONTR = ENABLE_IAP; //打开IAP功能,并设置等待时间IAP_CMD = CMD_PROGRAM; //设置ISP / IAP / EEPROM程序命令IAP_ADDRL = addr; //设置ISP / IAP / EEPROM地址低字节IAP_ADDRH = addr >> 8; //设置ISP / IAP / EEPROM地址高字节IAP_DATA = dat; //ISP / IAP / EEPROM写入数据IAP_TRIG = 0x46; //发送触发命令(0x46)IAP_TRIG = 0xb9; //发送触发命令(0xb9)_nop_(); //MCU将在这里等待,直到ISP / IAP / EEPROM 操作完成IapIdle();}/*----------------------------擦除一个扇区的输入:地址(ISP / IAP / EEPROM地址)输出:-----------------------------*/void IapEraseSector(uint addr){IAP_CONTR = ENABLE_IAP; //打开IAP功能,并设置等待时间IAP_CMD = CMD_ERASE; //设置ISP / IAP / EEPROM擦除命令IAP_ADDRL = addr; //设置ISP / IAP / EEPROM地址低字节IAP_ADDRH = addr >> 8; //设置ISP / IAP / EEPROM地址高字节IAP_TRIG = 0x46; //发送触发命令(0x46)IAP_TRIG = 0xb9; //发送触发命令(0xb9)_nop_(); //MCU将在这里等待,直到ISP / IAP / EEPROM 操作完成IapIdle();}四、proteus仿真图五、ALtium Dsigner原理图及pcb图原理图PCB图总结:本作品可以作为毕业设计的,有需要源文件的可以“私信”我,我看到到会回复,这个作品本人亲测成功,那些都是实拍图或截图,获得源文件后毕设绝对不是问题!。