基于单片机设计的温度报警系统方案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机设计的温度报警器
摘要 (3)
1、引言 (4)
2 设计容及性能指标 (5)
3 系统方案比较、设计与论证 (5)
3.1 主控制器模块 (5)
3.2 温度测量 (6)
3.3 设置温度 (7)
3.3 显示模块 (7)
3.4 电源选取 (7)
4 系统器件选择 (8)
5 硬件实现及单元电路设计 (9)
5.1 主控制模块 (9)
5.2 显示模块电路 (9)
5.3 数码管显示驱动电路 (10)
图6 驱动电路 (10)
5.4 温度传感器(DS18B20)电路 (11)
5.4.1 DS18B20基本介绍 (11)
5.4.2 DS18B20控制方法 (11)
5.4.3 DS18B20供电方式 (12)
5.6 蜂鸣器、发光二极管报警电路 (12)
6 系统软件设计 (13)
6.1 程序结构分析 (13)
6.2 系统程序流图 (14)
6.2.1 DS18B20初始化程序流程图 (15)
6.2.2 读温度子程序流程图 (16)
7 系统的安装与调试 (16)
7.1 安装步骤 (16)
7.2 电路的调试 (16)
7.3 本章小结 (17)
结论 (17)
参考文献 (17)
附录1 整体电路原理图 (18)
附录2 部分源程序 (19)
摘要
随着时代的进步和发展,单片机技术已经普及到我们生活、工作、科研、各个领域,已经成为一种比较成熟的技术, 本文主要介绍了一个基于STC89C52单片机的温度报警系统,详细描述了利用温度传感器DS18B20开发测温系统的过程,重点对传感器在单片机下的硬件连接,软件编程以及各模块系统流程进行了详尽分析,对各部分的电路也一一进行了介绍,该系统可以方便的实现温度采集和显示,并可根据需要任意设定报警温度,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度控制,也可以当作温度处理模块嵌入其它系统中,作为其他主系统的辅助扩展。
DS18B20与STC89C52结合实现最简温度控制系统,该系统结构简单,抗干扰能力强,适合于恶劣环境下进行现场温度的控制,有广泛的应用前景。
关键词:单片机;温度控制;STC89C52;DS18B20;
1、引言
随着科技的不断发展,现代社会对各种信息参数的准确度和精确度的要求都有了几何级的增长,而如何准确而又迅速的获得这些参数就需要受制于现代信息基础的发展水平。
在三大信息信息采集(即传感器技术)、信息传输(通信技术)和信息处理(计算机技术)中,传感器属于信息技术的前沿尖端产品,尤其是温度传感器技术,在我国各领域已经引用的非常广泛,可以说是渗透到社会的每一个领域,人民的生活与环境的温度息息相关,在工业生产过程中需要实时测量温度,在农业生产中也离不开温度的测量,因此研究温度的测量方法和温度报警装置具有重要的意义。
测量温度的关键是温度传感器,温度传感器的发展经历了三个发展阶段:
①传统的分立式温度传感器
②模拟集成温度传感器
③智能集成温度传感器。
目前的智能温度传感器(亦称数字温度传感器)是在20世纪90年代中期问世的,它是微电子技术、计算机技术和自动测试技术(ATE)的结晶,特点是能输出温度数据及相关的温度控制量,适配各种微控制器(MCU)。
社会的发展使人们对传感器的要求也越来越高,现在的温度传感器正在基于单片机的基础上从模拟式向数字式,从集成化向智能化、网络化的方向飞速发展,并朝着高精度、多功能、总线标准化、高可靠性及安全性、开发虚拟传感器和网络传感器、研制单片测温系统等高科技的方向迅速发展,本文将介绍智能集成温度传感器DS18B20的结构特征及控制方法,并对以此传感器,STC89C52单片机为控制器构成的数字温度控制装置的工作原理及程序设计作了详细的介绍。
其具有读数方便,方便控制,输出温度采用数字显示,主要用于对温度控制要求比较准确的场所,或科研实验室使用。
该设计控制器使用STC89C52单片机,测温传感器使用DALLAS公司DS18B20,用数码管来实现温度显示。
2 设计容及性能指标
本设计主要是介绍了单片机控制下的温度报警系统,详细介绍了其硬件和软件设计,并对其各功能模块做了详细介绍,其主要功能和指标如下:
单片机实时检测温度传感器DS18B20的状态,并将DS18820得到的数据进行处理。
上电后数码管显示当前的环境温度,通过按键可设置高低温报警值,当检测到的温度高于设置的报警值的时候,蜂鸣器报警同时报警灯闪烁,温度检测精确到0.1度。
并具有掉电保存功能,数据保存在单片机部EEPOM中,进入设置界面后如果没有键按下系统会在15秒后自动退出设置界面。
3 系统方案比较、设计与论证
该系统主要由温度测量和温度设置及系统状态显示三部分电路组成,下面介绍实现此系统功能的方案。
3.1 主控制器模块
方案1:
采用可编程逻辑器件CPLD 作为控制器。
CPLD可以实现各种复杂的逻辑功能、规模大、密度高、体积小、稳定性高、IO资源丰富、易于进行功能扩展。
采用并行的输入输出方式,提高了系统的处理速度,适合作为大规模控制系统的控制核心。
但本系统不需要复杂的逻辑功能,对数据的处理速度的要求也不是非常高。
且从使用及经济的角度考虑我们放弃了此方案。
方案2:
采用STC89C52单片机作为整个系统的核心,用其控制温度报警功能,以实现其既定的性能指标。
充分分析我们的系统,其关键在于实现温度的自动显示并报警功能,而在这一点上,单片机就显现出来它的优势——控制简单、方便、快捷。
这样一来,单片机就可以充分发挥其资源丰富、有较为强大的控制功能及可位寻址操作功能、价格低廉等优点。
STC89C52单片机具有功能强大的位操作指令,I/O口均可按位寻址,程序空间多达8K,对于本设计也绰绰有余,更可贵的是STC89C52单片机价格非常低廉。
3.2 温度测量
方案1:
采用数字温度芯片DS18B20 测量实际温度,输出信号全数字化。
便于单片机处理及控制,省去传统的测温方法的很多外围电路。
且该芯片的物理化学性很稳定,它能用做工业测温元件,此元件线形较好。
在0—100 摄氏度时,最大线形偏差小于 1 摄氏度。
DS18B20 的最大特点之一采用了单总线的数据传输,由数字温度计DS18B20和微控制器STC89C52构成的温度测量装置,它直接输出温度的数字信号,可直接与计算机连接。
这样,测温系统的结构就比较简单,体积也不大。
采用51 单片机控制,软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。
既可以单独对多DS18B20控制工作,还可以与PC 机通信上传数据,另外STC89C52在工业控制上也有着广泛的应用,编程技术及外围功能电路的配合使用都很成熟。
方案2:
采用热电偶温差电路测温,温度检测部分可以使用低温热偶,热电偶由两个焊接在一起的异金属导线所组成(如下图),热电偶产生的热电势由两种金属的接触电势和单一导体的温差电势组成。
通过将参考结点保持在已知温度并测量该电压,便可推断出检测结点的温度。
数据采集部分则使用带有A/D 通道的单片机,在将随被测温度变化的电压或电流采集过来,进行A/D 转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来。
热电偶的优点是工作温度围非常宽,且体积小,但是它们也存在着输出电压小、容易遭受来自导线环路的噪声影响以及漂移较高的缺点,并且这种设计需要用到A/D 转换电路,感温电路比较麻烦。
图1 热电偶电路图
从以上两种方案,容易看出方案二的测温装置可测温度围宽、体积小,但是线性
误差较大。
方案一的测温装置电路简单、精确度较高、实现方便、软件设计也比较简单,故本次设计采用了方案一。
3.3 设置温度
方案1:
采用键盘输入设置温度,键盘则可以用4个按键,一个复位键,一个功能设定键,一个加减一个减键。
四个键比较常用,而且用到的接口得到了极好的利用,仅需要4个接口。
方案2:
可采用4*4矩阵键盘,该键盘需要8个接口,而我们不需这么多键。
综上所述,我们选择第一种方案。
3.3 显示模块
方案1:
用数码管进行显示。
数码管由于显示速度快,使用简单,显示效果简洁明了而得到了广泛应用。
方案 2:
用LCD液晶进行显示。
LCD由于其显示清晰,显示容丰富、清晰,显示信息量大,使用方便,显示快速而得到了广泛的应用。
单对于此系统我们不需要显示丰富的容,而且LCD液晶价格贵,因此我们选择了此方案。
综上所述我们选择方案1
3.4 电源选取
由于本系统采用电池供电,我们考虑了如下几种方案为系统供电。
方案1:
采用5V蓄电池为系统供电。
蓄电池具有较强的电流驱动能力以及稳定的电压输出性能。
但是蓄电池的体积过于庞大,在小型电动车上使用极为不方便。
因此我们放弃了此方案。
方案2:
采用3节1.5 V干电池共4.5V做电源,经过实验验证系统工作时,单片机、传感器的工作电压稳定能够满足系统的要求,而且电池更换方便。
综上所述采用方案2
4 系统器件选择
1.温度传感器的选择
由于传统的热敏电阻等测温元件测出的一般都是电压,再转换成对应的温度,需要比较多的外部元件支持,且硬件电路复杂,制作成本相对较高。
这里采用DALLAS公司的数字温度传感器DS18B20作为测温元件。
图2 外部封装形式图3 传感器电路图
下载可编辑
5 硬件实现及单元电路设计
5.1 主控制模块
主控制最系统电路如图4所示。
图4 单片主控电路
5.2 显示模块电路
显示采用四位数码管显示,当位选打开时,送入相应的段码,则相应的数码管打开,关掉位选,打开另一个位选,送入相应的段码,则数码管打开,而每次打开关掉相应的位选时,时间间隔低于20ms,从人类视觉的角度上看,就仿佛是全部数码管同时显示的一样。
显示电路如图5
下载可编辑
图5 数码管显示
5.3 数码管显示驱动电路
三极管8550来驱动4位数码管,不仅简单,而且价格便宜。
图6 驱动电路
5.4 温度传感器(DS18B20)电路
5.4.1 DS18B20基本介绍
DS18B20是美国DALLAS半导体公司推出的第一片支持“一线总线”接口的温度传感器,它具有微型化、低功耗、高性能、抗干扰能力强、易配微处理器等优点,可直接将温度转化成串行数字信号处理器处理。
DS18B20进行精确的温度转换,I/O线必须保证在温度转换期间提供足够的能量,由于每个DS18B20在温度转换期间工作电流达到1mA,当几个温度传感器挂在同一根I/O线上进行多点测温时,只靠4.7K上拉电阻就无法提供足够的能量,会造成无法转换温度或温度误差极大。
因此,下图电路只适应于单一温度传感器测温情况下使用,不适宜采用电池供电系统中。
并且工作电源VCC必须保证在5V,当电源电压下降时,寄生电源能够汲取的能量也降低,会使温度误差变大。
图7 温度传感器电路引脚图
5.4.2 DS18B20控制方法
DS18B20有六条控制命令:
温度转换 44H 启动DS18B20进行温度转换
读暂存器 BEH 读暂存器9个字节容
写暂存器 4EH 将数据写入暂存器的TH、TL字节
复制暂存器 48H 把暂存器的TH、TL字节写到E2RAM中
重新调E2RAM B8H 把E2RAM中的TH、TL字节写到暂存器TH、TL字节
读电源供电方式 B4H 启动DS18B20发送电源供电方式的信号给主CPU
5.4.3 DS18B20供电方式
DS18B20可以采用两种方式供电,一种是采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。
另一种是寄生电源供电方式,如图3.1所示单片机端口接单线总线,为保证在有效的DS18B20时钟周期提供足够的电流,可用一个三极管来完成对总线的上拉。
本设计采用电源供电方式, P2.2口接单线总线为保证在有效的DS18B20时钟周期提供足够的电流,可用一个上拉电阻和STC89C52的P2.2来完成对总线的上拉。
当DS18B20处于写存储器操作和温度A/D变换操作时,总线上必须有强的上拉,上拉开启时间最大为10 μs。
采用寄生电源供电方式是VDD和GND端均接地。
由于单线制只有一根线,因此发送接收口必须是三状态的。
主机控制DS18B20完成温度转换必须经过3个步骤:
●初始化。
●ROM操作指令。
●存储器操作指令。
5.6 蜂鸣器、发光二极管报警电路
电路如图8主要是用来设定温度报警温度的、有高温和低温报警。
图8 蜂鸣器、发光二极管驱动引脚图
6 系统软件设计
6.1 程序结构分析
主程序调用了3个子程序,分别是数码管显示程序、温度信号处理程序、按键设定报警温度程序。
温度信号处理程序:对温度芯片送过来的数据进行处理,进行判断和显示。
数码管显示程序:向数码管的显示送数,控制系统的显示部分。
按键设定程序:可以设定低温和高温报警可精确到0.1度。
6.2 系统程序流图
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s进行一次。
这样可以在一秒之测量一次被测温度,主程序的主要功能是负责温度的实时显示,读出并处理DS18B20的当前温度值,与设定的报警温度比较,其程序流程见图9所示。
通过调用读温度子程序把存入存储中的整数部分与小数部分开分存放在不的的两个单元中,然后通过调用显示子程序显示出来。
图9 DS18B20温度流程图
6.2.1 DS18B20初始化程序流程图
在DS18B20工作之前需要进行初始化,流程图如下:
图10 初始化程序流程图
6.2.2 读温度子程序流程图
读温度子程序的主要功能是从DS18B20中读出温度数据,移入温度暂存器保存。
其程序流程图如下:
图11 温度子程序流程图
7 系统的安装与调试
7.1 安装步骤
1.检查元件的好坏
按电路图买好元件后首先检查买回元件的好坏,按各元件的检测方法分别进行检测,一定要仔细认真。
而且要认真核对原理图是否一致,在检查好后才可上件、焊件,防止出现错误焊件后不便改正。
2.放置、焊接各元件
按原理图的位置放置各元件,在放置过程中要先放置、焊接较低的元件,后焊较高的和要求较高的元件。
特别是容易损坏的元件要后焊,在焊集成芯片时连续焊接时间不要超过10s,注意芯片的安装方向。
7.2 电路的调试
首先烧入显示程序,看显示正不正常。
在调试程序时,发现有的指令用的不正确,导致电路功能不能完全实现,另外软件程序中的延时有的过长、有的过短。
类似的现象还有很多就不一一列举了。
7.3 本章小结
本章的主要容是电路的测试和调试注意事项
结论
本温度报警器,通过单片机实时检测温度传感器DS18B20的状态,并将DS18820得到的数据进行处理。
上电后数码管显示当前的环境温度,通过按键可设置高低温报警值,当检测到的温度高于设置的报警值的时候,蜂鸣器报警同时报警灯闪烁,温度检测精确到0.1度。
并具有掉电保存功能,数据保存在单片机部EEPOM 中,进入设置界面后如果没有键按下系统会在15秒后自动退出设置界面。
由于采用了4节干电池供电使系统的抗干扰性得到加强。
在软件上,充分利用了STC89C52的系统资源,系统运行流畅。
本设计结构简单,调试方便,系统反映快速灵活,经实验测试,该温度报警系统设计方案正确、可行,各项指标稳定、可靠。
参考文献
1曹巧媛主编. 单片机原理及应用(第二版). 北京:电子工业,2002
2全国大学生电子设计竞赛组委会编.第五届全国大学生电子设计竞赛获奖作品选编(2001), 北京:北京理工大学,2003
3何力民编. 单片机高级教程. 北京:北京航空大学,2000
4金发庆等编. 传感器技术与应用.北京机械工业,2002
5坤、宋戈、洪波、宪栋编.51单片机C语言应用开发技术大全,北京:人民邮电,2008
6谭浩强著.C程序设计.北京:清华大学,2007;
7王忠飞,胥芳.MCS-51 单片机原理及嵌入式系统应用[M].:电子科技大学,2007.P268-273
8 Peter Van Der Linden著,徐波译.C专家编程,人民邮电,2003
附录1 整体电路原理图
附录2 部分源程序
#include <reg52.h>
#include "eepom52.h"
#define uchar unsigned char
#define uint unsigned int
//数码管段选定义 0 1 2 3 4 5 6 7 8 9 uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //断码//数码管位选定义
uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};
uchar dis_smg[8] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
uchar smg_i = 3; //显示数码管的个位数
sbit dq = P2^4; //18b20 IO口的定义
sbit beep = P2^5; //蜂鸣器IO口定义
uchar a_a;
uint temperature ; //
bit flag_300ms ;
uchar key_can; //按键值的变量
uchar menu_1; //菜单设计的变量
uint t_high = 300,t_low = 100;
bit flag_lj_en; //按键连加使能
bit flag_lj_3_en; //按键连3次连加后使能加的数就越大了
uchar key_time,flag_value; //用做连加的中间变量
bit key_500ms ;
uchar flag_clock;
uchar zd_break_en,zd_break_value; //自动退出设置界面
/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/***********************小延时函数*****************************/ void delay_uint(uint q)
{
while(q--);
}
/***********************数码显示函数*****************************/ void display()
{
uchar i;
for(i=0;i<smg_i;i++)
{
P3 = smg_we[i]; //位选
P1 = dis_smg[i]; //段选
delay_1ms(1);
P3 = 0xff; //位选
P1 = 0xff; //消隐
}
}
/******************把数据保存到单片机部eepom中******************/ void write_eepom()
{
SectorErase(0x2000);
byte_write(0x2000, t_high % 256);
byte_write(0x2001, t_high / 256);
byte_write(0x2002, t_low % 256);
byte_write(0x2003, t_low / 256);
byte_write(0x2055, a_a);
}
/******************把数据从单片机部eepom中读出来*****************/ void read_eepom()
{
t_high = byte_read(0x2001);
t_high <<= 8;
t_high |= byte_read(0x2000);
t_low = byte_read(0x2003);
t_low <<= 8;
t_low |= byte_read(0x2002);
a_a = byte_read(0x2055);
}
/***********************18b20初始化函数*****************************/ void init_18b20()
{
bit q;
dq = 1; //把总线拿高
delay_uint(1); //15us
dq = 0; //给复位脉冲
delay_uint(80); //750us
dq = 1; //把总线拿高等待
delay_uint(10); //110us
q = dq; //读取18b20初始化信号
delay_uint(20); //200us
dq = 1; //把总线拿高释放总线
}
/*************写18b20的数据***************/
void write_18b20(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{ //写数据是低位开始
dq = 0; //把总线拿低写时间隙开始
dq = dat & 0x01; //向18b20总线写数据了
delay_uint(5); // 60us
dq = 1; //释放总线
dat >>= 1;
}
}
/*************读取18b20的数据***************/
uchar read_18b20()
{
uchar i,value;
for(i=0;i<8;i++)
{
dq = 0; //把总线拿低读时间隙开始
value >>= 1; //读数据是低位开始
dq = 1; //释放总线
if(dq == 1) //开始读写数据
value |= 0x80;
delay_uint(5); //60us 读一个时间隙最少要保持60us的时间}
return value; //返回数据
}
/*************读取温度的值读出来的是小数***************/
uint read_temp()
{
uint value;
uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
init_18b20(); //初始化18b20
write_18b20(0xcc); //跳过64位ROM
write_18b20(0x44); //启动一次温度转换命令
delay_uint(50); //500us
init_18b20(); //初始化18b20
write_18b20(0xcc); //跳过64位ROM
write_18b20(0xbe); //发出读取暂存器命令
EA = 0;
low = read_18b20(); //读温度低字节
value = read_18b20(); //读温度高字节
EA = 1;
value <<= 8; //把温度的高位左移8位
value |= low; //把读出的温度低位放到value的低八位中
value *= 0.625; //转换到温度值小数
return value; //返回读出的温度带小数
}
/*************定时器0初始化程序***************/
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0、定时器1工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}
/****************独立按键处理函数************************/
void key()
{
static uchar key_new = 0,key_old = 0,key_value = 0; if(key_new == 0)
{ //按键松开的时候做松手检测if((P2 & 0x0f) == 0x0f)
key_value ++;
else
key_value = 0;
if(key_value >= 10)
{
write_eepom();
key_value = 0;
key_new = 1;
flag_lj_en = 0; //关闭连加使能
flag_lj_3_en = 0; //关闭3秒后使能
flag_value = 0; //清零
}
}
else
{
if((P2 & 0x0f) != 0x0f)
key_value ++; //按键按下的时候
else
key_value = 0;
if(key_value >= 7)
{
key_value = 0;
key_new = 0;
flag_lj_en = 1; //连加使能
zd_break_en = 1; //自动退出设置界使能
zd_break_value = 0; //自动退出设置界变量清零}
}
key_can = 20;
if(key_500ms == 1)
{
key_500ms = 0;
zd_break_en = 1; //自动退出设置界使能
zd_break_value = 0; //自动退出设置界变量清零
key_new = 0;
key_old = 1;
}
if((key_new == 0) && (key_old == 1))
{
switch(P2 & 0x0f)
{
case 0x0e: key_can = 4; break; //得到k1键值
case 0x0d: key_can = 3; break; //得到k2键值
case 0x0b: key_can = 2; break; //得到k3键值
case 0x07: key_can = 1; break; //得到k4键值
}
}
key_old = key_new;
}
/****************按键处理数码管显示函数***************/
void key_with()
{
if(key_can == 4)
{
menu_1 ++;
if(menu_1 >= 3)
{
menu_1 = 0;
}
if(menu_1 == 0)
{
dis_smg[0] = smg_du[temperature % 10]; //取温度的小数显示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取温度的个位显示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取温度的十位显示
smg_i = 3;
}
if(menu_1 == 1)
{
dis_smg[0] = smg_du[t_high % 10]; //取小数显示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取low十位显示
dis_smg[3] = 0x89;
smg_i = 4;
}
if(menu_1 == 2)
{
dis_smg[0] = smg_du[t_low % 10]; //取low小数显示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位显示
dis_smg[3] = 0xc7;
smg_i = 4;
}
}
if(menu_1 == 1) //设置高温报警
{
if(key_can == 3)
{
if(flag_lj_3_en == 0)
t_high ++ ; //按键按下未松开自动加三次
else
t_high += 10; //按键按下未松开自动加三次之后每次自动加10 if(t_high > 990)
t_high = 990;
dis_smg[0] = smg_du[t_high % 10]; //取小数显示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取十位显示
dis_smg[3] = 0x89; //H
}
if(key_can == 1)
{
if(flag_lj_3_en == 0)
t_high -- ; //按键按下未松开自动加三次
else
t_high -= 10; //按键按下未松开自动减三次之后每次自动减10 if(t_high <= t_low)
t_high = t_low + 1;
dis_smg[0] = smg_du[t_high % 10]; //取小数显示
dis_smg[1] = smg_du[t_high / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_high / 100 % 10] ; //取十位显示
dis_smg[3] = 0x89; //H
}
// write_eepom();
}
if(menu_1 == 2) //设置低温报警
{
if(key_can == 3)
{
if(flag_lj_3_en == 0)
t_low ++ ;
else
t_low += 10;
if(t_low >= t_high)
t_low = t_high - 1;
dis_smg[0] = smg_du[t_low % 10]; //取小数显示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位显示
dis_smg[3] = 0xc7; //L
}
if(key_can == 1)
{
if(flag_lj_3_en == 0)
t_low -- ;
else
t_low -= 10;
if(t_low <= 10)
t_low = 10;
dis_smg[0] = smg_du[t_low % 10]; //取小数显示
dis_smg[1] = smg_du[t_low / 10 % 10] & 0x7f; //取个位显示
dis_smg[2] = smg_du[t_low / 100 % 10] ; //取十位显示
dis_smg[3] = 0xc7; //L
}
// write_eepom();
}
}
/****************报警函数***************/
void clock_h_l()
{
if((temperature <= t_low) || (temperature >= t_high))
{
flag_clock = 1;
}
else
{
flag_clock = 0;
beep = 1;
}
}
void main()
{
temperature = read_temp(); //先读出温度的值
time_init(); //初始化定时器
read_eepom();
if(a_a == 0xff) //新的单片机初始单片机问EEPOM
{
t_high = 300;
t_low = 100;
a_a = 1;
write_eepom();
}
delay_1ms(650);
temperature = read_temp(); //先读出温度的值
dis_smg[0] = smg_du[temperature % 10]; //取温度的小数显示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取温度的个位显示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取温度的十位显示
while(1)
{
display(); //显示函数
key(); //按键程序
if(key_can < 10)
{
key_with(); //设置报警温度
}
temperature = read_temp(); //先读出温度的值
if(flag_300ms == 1) //300ms 处理一次温度程序
{
clock_h_l(); //报警函数
if(flag_clock == 1)
beep = ~beep;
flag_300ms = 0;
if(menu_1 == 0)
{
smg_i = 3;
dis_smg[0] = smg_du[temperature % 10]; //取温度的小数显示
dis_smg[1] = smg_du[temperature / 10 % 10] & 0x7f; //取温度的个位显示
dis_smg[2] = smg_du[temperature / 100 % 10] ; //取温度的十位显示
}
if(zd_break_en == 1) //自动退出设置界面程序
{
zd_break_value ++; //每300ms加一次
if(zd_break_value > 50) //15秒后自动退出设置界面
{
menu_1 = 0;
zd_break_en = 0;
zd_break_value = 0;
}
}
}
}
}
/*************定时器0中断服务程序***************/ void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms
value ++;
if(value % 6 == 0)
{
flag_300ms = 1; //300ms
value = 0;
}
if(flag_lj_en == 1) //按下按键使能
{
key_time ++;
if(key_time >= 10) //500ms
{
key_time = 0;
key_500ms = 1; //500ms
flag_value ++;
if(flag_value > 3)
{
flag_value = 10;
flag_lj_3_en = 1; //3次后1.5秒连加大些}
}
}
}。