单片机驱动的智能热水器设计与实现全过程解析
摘 要
在当今21世纪,人们生活质量不断提高,各种各样的先进电器进入到家家户户,其中就包括日常洗漱会用到的
热水器,它满足了人们日常生活中对热水的需求。但是尽管科技是多么的先进,当今市面上的热水器,在控制电路
方面仍存在不足的地方。所以基于这个现状,为了弥补控制电路方面的不足,我设计了本次的热水器。
本次设计中,以STC89C51单片机作为整个电路的核心部分,用来控制热水器各个模块稳定地运行。我通过软件
和硬件的不断调试,热水器最终能够实现的主要功能是可以对水位进行设置实现自动加水,主要流程是先设置好需
要加水的水位段数,然后STC89C51单片机会根据这个数值来判断是否需要加水。与此同时,热水器通过温度传感器
将温度值传输到单片机芯片中,之后通过液晶显示屏显示实时水温。人为的可以设置水温范围,若水温超过或低于
所设置的水温范围,则会停止加热或开启加热。
该水温水位测控系统采用的是软件设计,编程采用C语言,可以实现水位地检测,水量不足时自动加水。水温地
检测,温度不够时智能加热,还可以设置定时时间,到时自动工作并且提高了整个系统的可靠性和稳定性,进一步
完善了热水器控制电路。
关键词:STC89C51,DS18B20,水温水位控制
第一章 引 言
1.1 本课题的研究背景
在市场上,有很多种热水器,它们主要区别在于加热的方式不同。放在以前,燃气热水器可以说是风光无限,
未来发展前景很好,很多家庭中都有所使用,但是如今却渐渐地被人们所舍弃,主要是它存在着诸多问题[1]。现
在,在居民居住的房屋顶上大都可以见到太阳能热水器的身影,虽然它的普及度会受到一些条件的限制,例如安装
地点的光照强度、天气气候等[2],但它不会污染环境,不用耗费太多的电能,以及拥有很高的安全性。在如今,随
着社会安全教育的不断普及,城镇居民更乐意地选择电热水器和太阳能热水器。其中很大一部分原因是现在城镇居
民的房屋通风效果还是存在些许不足,当燃气燃烧时,会存在燃烧不充分,导致热水器漏出一些易燃且对人体有害
的气体[2],不能够及时地消散而存留在房屋中,日积月累后会产生很大的隐患。而由太阳能和电能提供热源的热水
器就不会存在这样的问题。除此外,人们更乐意选择电热水器还包括其他原因,例如安装容易、人力物力投入小、
容易操控等。如今的热水器产品已经绝对不是一个简单的加热器,而是科技含量很高的现代化家电产品[4]。
随着科技的进步以及新品的不断研发,各种全新装置方式的电热水器相继推出,比如嵌入式、下置式等,几乎
完全打破了传统房间空间地束缚。选用STC89C51单片机作为控制芯片,实现了电热水器的智能化、持续稳定的热水
供应、自动断电等功能,使人们洗浴时能放心享受,利于人们的身体健康,其实用、便捷的优点能快速满足人们对
现代生活快节奏的需求[5]。所以基于这个背景,我设计了本次的智能热水器。
1.2 本课题选题的意义和目的
1.2.1 选题的意义
本次的选题,一个主要意义在于通过采用STC89C51单片机对热水器的水温水位参数进行控制,实现了热水器的
智能化改进,提高了热水器在工作时的可靠稳定性。人们在洗漱过程中不会遇到突然断电停水或一些其他异常状
况,对人们的人身安全有很好的保障。此外,本次设计的热水器选用DSI8B20作为温度传感器,提高了单片机对水温
数据采集的精确性,从而提高了系统整体的精度,大大降低了水温突然超过自己设置的温度的概率。该热水器还配
备遥控功能,人们可以远程进行操控,方便了人们的生活,利于人们的身心健康。
这次的改进的意义,不仅仅只是对改进热水器这一个产品有意义,它对整个电器产品研究改进领域也有着重大
意义。人们可以根据热水器改进技术的思路和方法,将其应用到各个行业中,在此基础上不断开拓创新。此外,本
次智能化改进的参数主要是水温水位,这其中参数改进的思路方案,对其他参数的改进也有很大的参考价值,推动
了热水器在将来全面的改进创新。
1.2.2选题的目的
本课题选题的目的,主要是为了设计一个能够更好地满足人们对热水器需求的控制系统。而本次设计的基于
STC89C51单片机的水温水位测控系统就能很好地实现。它能保证热水器在运行时能够持续地给热水器水箱供应水
源,同时它还可以实现自动断电。此外,本次设计的热水器支持红外遥控和定时功能,是为了使人们在使用热水器
时更加的便捷和简单。综上所述,设计智能化热水器的目的归根究底是出于对人们身心健康的考虑,为了满足人们
对快节奏生活的需求。
1.3 基于51单片机的研究设想和实验设计
本次实验设计的思路如下:以51单片机为基础作为热水器的“大脑”,围绕它设计和控制各个功能模块,其中
包括电源模块:给单片机以及外围电路供电;水温、水位检测模块:用来检测水温和水位;报警模块;反应异常状
态;液晶和指示灯显示模块:用来显示各个参数以及继电器的工作状态;按键模块:设置参数值和初始化单片机;
ISP在线编程接口:可以重新烧入程序[4]。这些模块和单片机芯片组合起来,来达到设计的要求。
当系统接通电源并按下开机按键时,单片机会先检测按键模块,持续时间很短,检测完后,人为地通过PCB板上
的按键进行温度最大值最小值和定时时间的调节,也可以用红外遥控来设置,设置完后单片机执行主程序,热水器
各个模块开始运行。
1.4 本论文的思路
根据本次课题想要设计的功能,主要分为以下几个部分:1、外部可以接入220v交流电给系统供电;2、用按键
模块来实现人为地设置参数;3、当系统出现异常或人为地设置,系统要能够报警;4、设置驱动模块来驱动电路;
5、能够显示出各个参数值;6、要能检测实时水温和水位;7、通过将检测到的参数传入到单片机,从而控制热水器
地加水和加热。
在本次论文中,根据以下几大部分来展开编写:
第一章为引言部分,它主要用来描述本次设计研究的背景是什么以及出于什么样的目的来设计本次的热水器,
还讨论了设计本次的热水器有什么样的实际意义。
第二章为本次设计的硬件设计部分,它主要是用来介绍本次设计选用STC89C51单片机作为控制芯片的原因以及
热水器各个功能模块电路。
第三章为软件设计部分,它主要用来介绍硬件功能能够实现所需的软件部分,以流程图的形式来阐述程序的编
写步骤。
第四章为软硬件的调试部分,它主要用来介绍最终的调试过程以及展示本次设计的热水器能够实现的功能。
第五章为总结与展望部分,它主要用来对本次设计的总结以及对热水器后续功能改进的展望。
最后罗列中本次设计所引用的参考文献、致谢以及附录部分。
第二章 系统硬件设计
2.1 方案验证
系统硬件能够实现的功能如下:
(1)用LCD1602液晶屏来显示各个参数。
(2)水温能够检测到的范围是0~99摄氏度。
(3)温度上下限值可以设置的范围为0~99摄氏度,通过加热继电器控制热水器的加热。
(4)用两个水位传感器检测热水器水箱中的水位,通过加水继电器控制热水器的加水。
(5)设置5个按键,分别为功能设置按键、确认按键、加键和减键,复位按键。
(6)红外遥控功能,可以远程操控热水器。
2.1.1 单片机的选型
方案1:选用AT 89S52 芯片
它在通电工作时,产生的能耗较小,且内置具有性能较高的8位微处理器。在它的内部,还拥有8KB系统可编程
的FLASH只读存储器以及128B的RAM,擦写周期约在一千次。它的I/O口电路像其他芯片一样可以进行编程,且拥有多
达32个接口线。此外,它还有一个可以同时发送和接受数据的串行口,三个16位的定时器。
方案2:选用STC89C51芯片
它不仅内部结构十分的简单、集成度也很高,而且它的控制能力方面十分的强大,已经在很多行业得到应用和
认可。图2.1所示的是交通灯系统框图,它是围绕51单片机,配以各个模块电路。
图2.1 STC89C51控制的智能电热水器
要想设计电热水器的控制电路理论上有很多种方式,上面所罗列的是两种容易实现的方案。通过综合考虑,本
人觉得使用51单片机设计的电路结构较简单,而且性能也比较稳定,供电可靠性高,不会出现异常情况。其次选择
STC89C51另一个原因是本人对51单片机的掌握程度高于AT89S52,更容易实现完成本次的设计。
2.1.2 显示模块的选型
方案1:选用LCD1602。
它相当于把点阵屏集中放在一个屏幕中,只是每个点阵为5×7(5行7列)。它的字母中16代表16个点阵排成一
行,02表示一共有两行。这样的话,按理说应该有16×5+7×2个引脚,才能实现逐行扫描显示。但是LCD一共只有16个
引脚,这是因为它上门集中了控制驱动电路HD 44780及其扩展电路HD 44100。与单片机组合时,并不是直接控制LCD
显示器,而是通过HD44780来控制LCD。
方案2:选用 HS – 12864。
它使用 KS 0108 作为控制芯片,适配M6800系列时序,具有8位标准数据总线,能够显示多种字符图形。但它在
控制方面比较复杂,需要使用三根控制线和八根数据线,且它的体积比较大,控制难度比LCD1602大。
通过上述的比较,本人决定用LCD1602作为显示模块,一方面是考虑到两者在使用方面有所差别,LCD1602总的
来说要简单一些。另一方面,本人对LCD1602的熟练度要高于HS-12864,降低了本次设计的难度。
2.2 硬件系统设计
系统硬件设计总体思路是围绕单片机,根据它的I/O口的功能来设计各个模块电路。在设计时,要结合实际情况
进行元件合适地选择,尽可能地使硬件电路简单化。由于在本次设计中,单片机自身的资源能够满足本次的设计任
务,所以就无需再另外设计扩展电路。
本次的硬件设计是从供电部分开始设计,到最终能够控制各个元件达到想要的功能。基于设计的主要任务,例
如能够控制热水器自动加水,加水这一过程就用继电器吸合和分离来模拟,具体设计就到此为止,无需设计水箱来
实现加水过程,加热模块也大致如此。
2.2.1 直流电源电路
设计电源电路的目的是考虑到热水器在实际使用中是通过市电220V(或380V)单相交流电来供电的,而热水器内部
的电子电路只需要很小的直流电源供电。所以本次所设计的直流电源电路就可以很好的解决这一问题。
各部分功能简介
(1)电源电压器
它的作用是可以将输入的交流电压U0降低到后面电路所需的电压值U1,变压器的变比则为U0/U1。除了变换电压
外,它还可以起到电气隔离的作用,减小电网侧对电子电路的干扰。
(2)整流电路
它的作用是可以将变压器变换后的AC(交流)进行整流,变换后可以得到一个脉动的DC(直流)。在本设计
中,选用桥式整流电路来进行电压从AC到DC的变换。相比于半波整流电路,它得到的电压值高,电压波形更为平
滑,脉动较小。
(3)滤波电路
通过整流电路变换后得到的是一个脉动的直流,通过分解,在它里面还是会含有较多的交流部分。所以,为了削弱所得到的电压中交流成分,让它的脉动更加的小,就必须设计一个滤波电路。在本次设计中,为了能够简化电
路,所以采用常见且简单的电容滤波电路,最终得到的直流电压U3≈1.2U1。
(4)稳压电路
由于变压器的原边是接与电网的,而电网电压又是会波动的,如果不设计一个稳压电路,最终得到的直流电压
U3也会波动,这对电子电路会产生很大的不利影响,减少整个热水器的使用寿命,所以稳压电路的设计完全是有必
要的。在本次设计中,采用7805集成芯片,构成的电路图如下图所示,通过它可以输出所需的+5V直流电压。如图
2.3所示,LM7805的1脚为输入端,在此引脚上接一个电容用来对输入电压进一步的滤波,2引脚接GND,
2.2.2 按键电路
按键电路可以由很多种设计方法,由于在本次设计中预计使用的按键数较少,其次独立按键是学习单片机最基
本的程序,本人对此熟练程度也较高,所以选用独立按键来完成本次设计。独立按键有诸多优点,例如每个按键可
以单独地工作,按键之间的状态不会存在干扰。
如上图所示,4个按键的2引脚同时接地。3引脚接到单片机的P1.4~P1.7接口。由于外接按键模块,通过按键输
入给I/O口来反应按键的状态,所以需要在P1.4~P1.7这四个引脚引出线上分别接一个上拉电阻。由于单片机的独立
式按键常采用软件查询式结构。单片机如果检测到P1.4接口中有低电平输入,代表这个接口被按下,单片机就会转
向这个按键按下之后对应的功能程序,其他3个按键也一样。其功能程序可以通过程序编写来实现。
2.2.3 报警电路
报警电路通过蜂鸣器报警,来提醒人们热水器出现异常状况,如下图2.5所示。
以下为报警电路可能存在误启动的状况:
1、当热水器中水温超过设定的最大值时,热水器蜂鸣器报警,提醒人们水温已经过热,要注意安全。
2、当热水器中上下放置的两个传感器异常时蜂鸣器会报警。可能会存在上面的传感器因为故障等其他原因,即使在
下面的传感器没有检测到水,它也依然检测到有水时,热水器的蜂鸣器就会报警。
2.2.4 继电器驱动电路
这个模块由BJT、LED、继电器以及若干个电阻组成。BJT采用的是PNP型,R17是一个限流电阻。当给基极输入一
个低电平时,BIT就会导通。LED在正常工作时所需要电压大小为3V左右,而在本次设计的电路中,当三极管导通
时,如果不串联一个电阻,LED两端的电压值会达到5V左右,这样就会烧坏LED,所以就必须串连一个电阻来进行分
压,使得LED两端的电压值达到3V左右。继电器和指示灯并联,当BJT导通时,从它的发射极向集电极流过的电流Ic
同时给继电器和LED供电。另外电路还有连接一个外接负载。
利用三极管饱和和截止这两个状态所对应的条件,可以起到开关元件的作用。它的基极(引出线b)通过R17接
与单片机的I/O。当单片机通过I/O输出一个低电平时,b端的点位小于e端的点位,此时Q3会因内部的发射结处在正
偏状态而不会导通,就没有电流从集电极流向继电器线圈,常开触点就不会闭合,外接负载不会启动并且LED处于熄
灭状态;当单片机输出一个高电平时,集电结反偏,三极管就会导通,有电流从集电极流到继电器,此时就会由于
线圈得电产生电磁感应效应,使得线圈变为磁性物体,从而被上方的衔铁吸引,带动了常开触点的闭合,外接的负
载电路就会工作[6]。
2.2.5 温度检测电路
考虑到由DS18B20温度传感器设计的电路容易实现,测量精度很高,并且可靠性靠,所以选用它来设计本次的温
度检测电路。如下图所示,它有3根引脚,1管脚用来接地,3管脚由单片机提供电源,2管脚用做数据交互等。
DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚TO-92小体积封装形式;温度测量范围为0℃
~99℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输
出,支持3V~5.5V的电压范围,使系统设计更灵活、方便[3]。系统在工作时,可以通过按键置温度的范围,单片机将检测到的温度值和设置的温度范围作比较。如果检测到的水温低于最小值时,热水器就会启动加热功能,高于最
大值就会关闭加热功能。
2.2.6 水位检测电路
本次设计的水位检测电路,由2个水位传感器、2个电位器、2个上拉电阻以及LM358芯片组成,
对于下水位传感器J1而言,它的3引脚接GND,2引脚接VCC,1引脚用来输出一个变化的电压值,这个电压值的大
小会随传感器是否接触到水而变化。当传感器检测到有水时,就会从1脚输出一个高电压给LM358的2脚,设为U1;当
检测到没有水时,就会从1脚输出一个低电压给LM358的2脚,设为U2。通过改变LM358外接的电位器的阻值,从而改
变输入给LM358的3脚的电压值,设为U3。当系统工作时,通过调节电位器,确保U1大于U3,U3大于U2。当U3大于U2
时,代表传感器没有检测到水,由于LM358上拉电阻的存在,就会通过LM358的1脚给单片机的P3.6口输入一个高电
平;当U3小于U1时,代表传感器检测到有水,此时LM358的1脚就会输出一个低电平给单片机的P3.6口。通过这两个
状态从而实现单片机对加水继电器的控制。
2.2.7 1602液晶模块
在本系统中,用LCD液晶屏来构成显示部分,LCD液晶显示器具有功耗低、寿命长、无辐射、不易引起视疲劳等
优点,正在被广泛应用于仪表、家用电器、计算机、医疗仪器及交通和通信领域。
1、1602LCD主要技术参数如下:
(1)显示容量:16×2个字符
(2)芯片工作电压:4.5-5.5V
(3)工作电流:2.0mA(5.0V)
(4)最佳工作电压(模块):5.0V
(5)字符尺寸:2.95×4.35(W×H)mm
2、引脚的各部分功能说明如下表2.1所示:
表2.1 引脚接口说明表
编号 符号 引脚说明 编号 符号 引脚说明
1 VSS 电源地 9 D2 数据
2 VDD 电源正极 10 D3 数据
3 VL 液晶显示偏压 11 D4 数据
4 RS 数据/命令选择 12 D5 数据
5 R/W 读/写选择 13 D6 数据
6 E 使能信号 14 D7 数据
7 D0 数据 15 BLA 背光源正极
8 D1 数据 16 BLK 背光源负极
3、1602LCD的指令说明及时序
如下表2.2所示,一共有11条控制指令
表2.2 指令说明
序号 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
1 清显示 0 0 0 0 0 0 0 0 0 1
2 光标返回 0 0 0 0 0 0 0 0 1 *
3 置输入模式 0 0 0 0 0 0 0 1 I/D S
4 显示开/关控制 0 0 0 0 0 0 1 D C B
5 光标或字符移位 0 0 0 0 0 1 S/C R/L * *
6 置功能 0 0 0 0 1 DL N F * *
7 置字符发生存贮器地址 0 0 0 1 字符发生存贮器地址
8 置数据存贮器地址 0 0 1 显示数据存贮器地址
9 读忙标志或地址 0 1 BF 计数器地址
10 写数到CGRAM或DDRAM) 1 0 要写的数据内容
11 从CGRAM或DDRAM读数 1 1 读出的数据内容
4、单片机与1062LCD接口电路设计
2.2.8 红外一体接收模块
红外一体模块由红外一体热电源,两个滤波电容以及上拉电阻组成,热电源的1引脚接与单片机的P3.3口,利用
中断来检测相应信号;第3引脚接Vcc,另外在2引脚和3引脚之间并联两个滤波电容,起到滤波的作用,因工作电压
小于5V,所以在再加一个阻值为100Ω的分压电阻。
2.2.9 STC89C51功能特点介绍
(1)主要性能参数
它的主要性能参数如下表2.3所示:
表2.3 STC89C51主要性能参数
主要性能参数介绍
兼容MCS51指令系统 8K可反复擦写Flash ROM
32个双向I/O口 256x8bit内部RAM
3个16位可编程定时/计数器中断 时钟频率0-24MHz
2个串行中断 可编程UART串行通道
2个外部中断源 共6个中断源
2个读写中断口线 3级加密位
低功耗空闲和掉电模式 软件设置睡眠和唤醒功能
(2)STC89C51单片机最小系统
它是由单片机、电源、时钟电路和复位电路组成,如下图2.10所示。
①时钟电路:
它由一个晶振和两个电容构成,其接线如下图所示。时钟电路相当于人的心脏,它会给单片机提供时钟脉冲,
CPU依据脉冲来进行一步一步的操作,具有严格的时序[14]。通过时钟电路,进行软件编程的方式,可以完成本次设
计需要的定时等功能。在本次设计中采用振荡频率为11.0592MHz的晶振,它产生一个脉冲的时间为1/11.0592 us
[9],这个时间表示的是一个机器周期,单片机工作时的时钟周期为12个机器周期。所以定时时间=(2^16-X)*12
/11.0592,单位为us,X为定时器的初值,通过改变X的值从而实现不同的定时时间。
②复位电路:
单片机的复位电路可以使单片机初始化,利于解决单片机死机的问题。当需要单片机执行初始化程序时,就可
以按下PCB板上的复位按键并保持2个机器周期以上或重新给单片机上电,这样就可以使单片机重新执行出场程序。
图2.10 单片机最小系统
上电复位电路的原理是利用了电阻和电容构成的电路会产生先充电后放电的现象,通过这个现象就可以实现类
似于开关按键的功能。
当给单片机上电时,电容有一个充电过程,当电容和电阻以及电源值的大小确定下来时,就可以通过一系列的
计算算出电容器的充电时间大概为0.1s(大于2个时钟周期),而电容两端的电压在这个时间段是一个变化的值,变
化范围大概是03.5V[16],也就是说,电阻两端分得的电压在51.5V变化,所以Rest引脚的电压在这0.1s的内的电
压值是大于1.5V的。对于工作电压为5V的单片机而言,高电平信号为大于1.5V的点平。所以在电容充电的0.1s内,
Rest引脚接受的是高电平信号,此时单片机就会进去复位状态[8]。
当电容充满电时,由于外接的是一个直流电源,它就会有个放电过程,最终阻隔直流电源,使电路断开,Rest
引脚最终接受到一个低电平,单片机复位结束。按键复位的原理更为简单,按键按下不松开时,持续时间大于2个时
钟周期,它两端的电路就会被接通,Rest引脚接受到一个高电平,单片机就会复位。当按键松开时,电路断开,单
片机复位结束。
复位后,程序从0000H这一地址开始执行[15]。此外,单片机内部的部分寄存器也会被初始化,如下表2.4所示:
表2.4 专用寄存器状态表
寄存器 状态 寄存器 状态
PC 0000H TCON 00H
ACC 00H TL0 00H
PSW 00H TH0 00H
SP 07H TL1 00H
DPTR 0000H TH1 00H
P0 – P3 FFH SCON 00H
IP xxx00000H SBUF 不确定
13
IE 0xx00000H PCON 0xxx0000H
TMOD 00H
2.3 本章总结
在本次设计中,我先通过Altium Designer这一仿真软件来构造整体的硬件电路原理图。模块的设计,要考虑内
部元件的型号以及接线方式。例如,在继电器控制电路中,有NPN型和PNP型这两个三级管可供选择,两者的工作原
理不太相同,意味着接线方式是不同的,要考虑最终实物焊接时实现的简单程度来决定。又例如,在复位电路中,
电解电容是有正负极的,在原理图绘画中不能把正负极弄反。总之,在确保硬件电路构造正确性的前提下,尽可能
的使电路简单化,方便最终的电路焊接。
第三章 软件系统设计
当硬件原理图绘画好之后,就通过Keil软件来编写程序,将生成的hex文件烧入到单片机中。程序是根据硬件电
路,以及本次实验的设计要求来编写的。例如本次设计的按键模块,在硬件设计中,它的四个按键每一端分别接与
单片机的P1.4~P1.7这四个接口,所以在程序中就需要给P1口进行编程控制,从而实现按键功能。考虑人为按下按键
的实际情况,就必须在程序设计中加入按键的消除抖动部分。此外,依照往常有关单片机的设计经验,不同的程序
编写可以实现相同的功能,这就要求尽可能选择简单的程序,减少单片机资源的不必要浪费。总而言之,在确保软
件设计的正确性前提下,尽可能使程序简单化,最大程度地利用单片机资源。
在本次程序的编写中,总体由以下三个部分组成:主程序、键盘扫描子程序以及一些其他功能模块子程序[9]。
其中主控制器子程序包括A/D转换子程序(水位、水温),键盘处理及显示子程序,温度控制子程序(使用输出比较
功能),漏电保护子程序等组成。主程序要先对单片机的定时器、COP模块、A/D转换、端口、键中断等部分的工作
模式参数进行初始化设定,之后系统的主程序循环可以调用各个功能模块的子程序,对相关事件的处理则是依靠标
志位和判断标志位来实现。下面以流程图的形式展示主要设计过程:
3.1 按键工作程序流程图
当单片机上电时,复位电路使单片机初始化,程序开始执行。1602LCD会显示各个参数的初始值,包括温度,定
时时间和水温的上下限值。通过软件查询的方式来进行判断是否有按键按下,下面的流程图以通过按键设置水温范
围为例。若是没有按键按下则返回初始设置的水温状态,单片机继续查询;若是查询到按键被按下,之后就可以设
定温度范围。若是设定了最低温度和最高温度值,则通过新设定的温度范围来运行;若是设定完毕之后没有按下确
认键,则设定不成功,需返回重新设定温度范围,再次按下确认键。整个按键模块的工作流程如下图3.1所示:
图3.1 按键程序流程框图
3.2 温度测量模块流程图
先对DS18B20初始化,再进行ROM操作命令,最后才能对存储器操作和数据操作。DS18B20每一步操作都要遵循严
格的工作时序和通信协议。如主机控制DS18B20完成温度转换这一过程,根据DS18B20的通讯协议,须经三个步骤:
每一次读写之前都要对DS18B20进行复位,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进
行预定的操。大概的流程为:DS18B20先复位,通过单片机给它写入字节0XCC,跳过ROM指令,然后再给它写入字节
0X44,开始温度转化,将温度数据放入暂存器中。单片机向DS18B20写入字节0XBE,读取存放在DS18B20高速暂存器
中的温度数据。单片机将读取的二进制数据转化为ASCII值显示在LCD上。流程图如下图3.2所示:
图3.2 测温程序流程图
3.3 主程序工作程序流程图
当单片机上电时,通过设置的上电复位电路来初始化定时器等各个参数,然后设置循环程序,保证单片机从开
机开始,一直处在工作状态,能够实时检测水温水位等状态。在循环执行的程序中,给温度传感器写入时序,通过
温度传感器来读取实时温度,判断是否是设置的状态。然后通过液晶屏显示程序显示温度和定时时间。之后判断水
位的状况,分为三种状态,分别是低于下限、高于上限和错误状态,然后分别根据当时的状态执行所对应的程序。
然后判断预约时间是否到达,如果时间到了,在比较此时温度和上下限值的关系,分为两种,分别是高于上限和低
于下限,然后分别根据这两个状态执行对应的程序,执行完后结束。如果时间没到,直接结束程序。其流程图如下
图3.3所示:
图3.3 主程序流程图
附录二:程序
#include <reg52.h>
#include <display.h>
#define uint unsigned int
#define uchar unsigned char
sbit jdq= P1^0; //加热继电器
sbit shui=P1^3;//加水继电器
sbit Feng = P2^6; //蜂鸣器
sbit Key1=P1^4; //设置
sbit Key2=P1^5; //加
sbit Key3=P1^6; //减
sbit Key4=P1^7; //确定
sbit shang=P3^7;//上限
sbit xia=P3^6;//下限
sbit DQ=P2^2; //定义DS18B20总线I/O
signed char w,bj,bjx,bjd; //温度值全局变量
uchar c; //温度值全局变量
bit bdata flag=0,flag_BJ,flag_off=1,que;
#define Imax 14000 //此处为晶振为11.0592时的取值,
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 145 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
unsigned char Im[4]={0x00,0x00,0x00,0x00};
uchar f;
unsigned char m,Tc;
unsigned char IrOK;
uchar xx=29;
uchar sx=35;
int ds=0;
23
uchar Mode=0;
void delay(uint z)
{
uint i,j;
for(i=0;i<z;i++)
for(j=0;j<121;j++);
}
void Delay_DS18B20(int num)
{
while(num--) ;
}
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
Delay_DS18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay_DS18B20(8); //精确延时,大于480us
DQ = 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 = 1;
DQ = dat&0x10;
Delay_DS18B20(5);
DQ = 0;
24
dat>>=1;
}
}
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xC1); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xC1); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.00625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
void check_wendu(void)
{
c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
w=c/10; //计算得到整数位
if(w<0){w=0;} //设置温度显示上限
if(w>99){w=99;} //设置温度显示上限
}
void Key()
{
//模式选择
if(Key1==0)
{
while(Key1==0);
Feng=0;
Mode++;
Display_wd();
if(Mode==4)
{
Mode=1;
Feng=1;
}
write_com(0x38);//屏幕初始化
write_com(0x0d);//打开显示 无光标 光标闪烁
25
write_com(0x06);//当读或写一个字符是指针后一一位
switch(Mode)
{
case 1:
{
write_com(0x80+15);//位置
Feng=1;
break;
}
case 2:
{
write_com(0x80+0x40+5);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+0x40+14);//位置
Feng=1;
break;
}
}
}
if(Key2==0&&Mode!=0)
{
while(Key2==0);
Feng=0;
switch(Mode)
{
case 1:
{
if(ds<999)
{
ds++;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx<99-1)
{
26
sx++;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx<sx-1)
{
xx++;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
if(Key3==0&&Mode!=0)
{
while(Key3==0);
Feng=0;
switch(Mode)
{
case 1:
{
if(ds>0)
{
ds--;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx>xx+1)
27
{
sx--;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx>0)
{
xx--;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
if(Key4==0)
{
while(Key4==0);
Feng=0;
Mode=0;
write_com(0x38);//屏幕初始化
write_com(0x0c);//打开显示 无光标 无光标闪烁
Init1602();
if(ds>0)
{
flag=1;
jdq=1;
TR1=1;
}
Feng=1;
}
if(IrOK==1)
{
if(Im[2]==0x0d) //遥控设置键
{
Feng=0;
Mode++;
28
Display_wd();
if(Mode==4)
{
Mode=1;
Feng=1;
}
write_com(0x38);//屏幕初始化
write_com(0x0d);//打开显示 无光标 光标闪烁
write_com(0x06);//当读或写一个字符是指针后一一位
switch(Mode)
{
case 1:
{
write_com(0x80+15);//位置
Feng=1;
break;
}
case 2:
{
write_com(0x80+0x40+5);//位置
Feng=1;
break;
}
case 3:
{
write_com(0x80+0x40+14);//位置
Feng=1;
break;
}
}
}
else if(Im[2]==0x40)
{
if(Mode!=0)
{
Feng=0;
switch(Mode)
{
case 1:
{
if(ds<999)
{
ds++;
write_com(0x80+13);
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
29
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx<99-1)
{
sx++;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx<sx-1)
{
xx++;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
}
else if(Im[2]==0x19)
{
if(Mode!=0)
{
Feng=0;
switch(Mode)
{
case 1:
{
if(ds>0)
{
ds--;
write_com(0x80+13);
30
write_data('0'+ds/100);
write_data('0'+ds/10%10);
write_data('0'+ds%10);
write_com(0x80+15);//位置
}
Feng=1;
break;
}
case 2:
{
if(sx>xx+1)
{
sx--;
write_com(0x80+0x40+4);
write_data('0'+sx/10%10);
write_data('0'+sx%10);
write_com(0x80+0x40+5);//位置
}
Feng=1;
break;
}
case 3:
{
if(xx>0)
{
xx--;
write_com(0x80+0x40+13);
write_data('0'+xx/10%10);
write_data('0'+xx%10);
write_com(0x80+0x40+14);//位置
}
Feng=1;
break;
}
}
}
}
else if(Im[2]==0x15)
{
Feng=0;
Mode=0;
Init1602();
if(ds>0)
{
flag=1;
jdq=1;
TR1=1;
31
}
Feng=1;
}
IrOK=0;
}
}
void Alam()
{
if(flag_BJ==1&&flag_off==1)
{
Feng=0;
delay(1000);
Feng=1;
flag_off=0;
flag_BJ=0;
}
}
void main()
{
Init1602();
EA=1;//打开中断总开关
IT1=1;//下降沿有效
EX1=1;//外部中断1开
ET1=1;//打开允许开关
TMOD=0x01;//设置工作方式
TL1=0x3c;
TH1=0xb0;//赋初值
TH0=0;//T0赋初值
TL0=0;
TR0=0;//t0开始计时
check_wendu();
delay(1000);
bjd=99;
bjx=0; //这两个变量的作用就是,防止温度大范围跳动造成加热设备误动作
while(1)
{
check_wendu();
if(Mode==0)
{
Display_1602(c,ds,sx,xx);
if((xia==1)&&(shang==1)) //低于下限
{
que=1;
shui=0;
jdq=1;
}
else
32
{
que=0;
}
if((shang==0)&&(xia==0)) //高于上限
{
shui=1;
if(flag_BJ==0)
flag_BJ=1;
}
if((shang==0)&&(xia==1)) //错误
{
shui=1;
jdq=1;
Feng=0;
que=1;
}
if(flag==0)
{
if((w<bjd)&&(w>bjx))
{
if(w>=sx)
{
jdq=1;
if(flag_BJ==0)
flag_BJ=1;
}
else if((w<xx)&&(que==0))
{
jdq=0;
if(flag_BJ==0)
flag_BJ=1;
}
else
{
flag_BJ=0;
flag_off=1;
}
bjd=w+5;
bjx=w-5;
}
}
}
Key();
Alam();
}
}
void time1() interrupt 3//定时器函数
33
{
uint s;
TH1=0x3c;
TL1=0xb0;//重新赋初值
s++;
if(s==1200) //s=20为1s钟 1200为1分钟
{
s=0;
ds--;
if(ds==0)
{
flag=0;
if(w>=sx)
{
jdq=1;
if(flag_BJ==0)
flag_BJ=1;
}
else if((w<xx)&&(que==0))
{
jdq=0;
if(flag_BJ==0)
flag_BJ=1;
}
else
{
flag_BJ=0;
flag_off=1;
}
bjd=w+10;
bjx=w-10;
TR1=0;
}
}
}
第四章 软硬件调试
4.1软硬件结合调试
本课题的硬件部分的设计采用Altium Designer 软件,软件部分采用Keil uVision4 软件,硬件实物部分的焊
接是根据Altium Designer 软件设计的原理图来实现。
在Keil软件中,通过一步一步的调试,去优化整个程序,使得最终的程序简洁明了,可读性高,便于后续的修
改。通过它生成hex文件烧入到原理图中的单片机芯片中,在Altium Designer 中进行仿真调试,不断修改不足的地
方,使得焊接实物时更加的容易。当总体的效果能够达到要求时,就对照着原理图来焊接。
4.2 硬件实物图
图4.1为最终焊接完成的实物图,它是在9*15万用板进行焊接。
图4.1 硬件实物图
4.3 硬件测试结果
现象一:
按下左下角的开关按键,此时整个系统转入工作状态,同时会有蜂鸣器的提示声音。在初始状态下,温度探头
和两片水位传感器未放置在水中,这个状态对应在实际应用中热水器中的水箱还没有加水。由于温度探头是放置在
空气中,测量的温度代表当前环境温度,所以LCD液晶屏的第一行中Tp显示的数值就代表当前环境的温度,在实际应
用中将温度探头放入到水箱中来测量水箱中的水温。Up和Down显示的数值分别代表设置的水温的上限值和下限值,
Ti代表定时时间,初始状态为0 min。
在软件设计中,给它初始设置的温度范围为29~35℃。因为在当前状态下,下水位传感器未检测到水,所以即使
当前温度探头测得的温度低于设置的下限水温,此时加热继电器处于分离状态,热水器的加热功能没有开启。这样
做的一个最大好处在于它可以防止热水器在没水时发生干烧,从而损坏热水器。此外,从下图开发板上所见到的,
绿灯和黄色的LED亮起,分别对应了控制加水功能的继电器吸合和控制加热功能的继电器分离,代表热水器的加水功
能开启和加热功能关闭。开发板上的红灯是用来提醒一些异常状况,例如当热水器的上水位传感器检测到水,而下
水位未检测到水时,红色指示灯就会亮起,蜂鸣器报警。在初始状态,红色指示灯亮起,代表此时就是处于异常状
态,结合实际热水器的应用,热水器只要通上电并且按下电源开关,它就会一直保持热水器中的水箱是处于一个有
水的状态。
现象图如下图4.2所示
:
图4.2 初始状态
现象二:
按下功能按键,也就是最下面四个按键中从左到右的第一个按键,它可以设置温度的限值以及定时时间。通过
第二个和第三个按键实现数值的加减,第四个为确认按键。当按下功能按键时,会最先选择设置定时时间功能,再
次按下功能按键,就会跳到设置水温上限,再次按下功能按键,就会跳到设置水温下限功能,之后再次按下按键就
会循环操作。当选中需要设置的功能时,对应的数值就会不断闪烁,通过第二个和第三个按键实现数值的加减,当
设置的参数达到要求是,按下确认按键确认后结束。
在实际使用中,人们可以根据自己的喜好来设置合适的水温。在本次设计中,通过一连串的按键设置,变化后
的参数如下图所示,设置温度上限为36度,下限为28度,定时时间为0min。由于此时热水器的两个水位传感器还未
接触到水,三个指示灯的状态还未改变。
现象图如下图4.3所示:
图4.3 设定的温度范围
现象三:
当把下水位传感器放入水中,此时系统检测到有水,单片机就会打开加热功能,由于此时的水位还未超过上限
水位,所以热水器加热和加水功能都会开启。表现为黄灯、绿灯亮。由于热水器中已经开始有水,处于正常工作状
态,此时红灯就会熄灭。
这一现象代表了热水器在实际使用中,热水器的加水功能开启,水箱中的水量在有少到多不断地增加,当水位
超过水位下限传感器的位置时,热水器中的水量已经达到可以加热的状态并且此时水箱中的水温小于设置的水温下
限的数值,热水器的加热功能开启,伴随着Tp的数值不断缓慢地变化。
值得注意的是,在人们日常洗漱中会不断地消耗热水器水箱中的水量,这样就会致使热水器水箱中的水位不断
地下降,所以为了避免在使用中出现断水的现象,就得确保热水器水箱注入水的速度要大于日常洗漱所消耗水的速
度。
现象图如下图4.4所示:
图4.4下水位
现象四:
将上水位传感器放入到水中,此时绿色指示灯熄灭,代表着开发板上的加水继电器分离,加水功能关闭。这一
现象代表了热水器在实际使用中,水箱中的水量不断地增加,最终达到最大值,此时热水器已经不能继续再加水,
热水器就得把加水功能关闭。由于此时的水温未达到上限值,所以加热功能就会继续开启。表现为黄灯亮,红灯、
绿灯不亮。
值得注意的是,在实际使用中,关于水温的变化过程,要考虑以下两个方面:一方面热水器中不断注入凉水时
会使水温下降,另一方面,热水器的加热功能使在不断地给水加热。一个是降温,一个是升温,所以为了保持持续
的热水供应,就必须保证前者地变化速度是小于后者的变化速度。此外,本设计中硬件调试过程是将两个水位传感
器手动放入水中来模拟水箱中水温的变化,在实际使用中,两个水位传感器是上下固定放置在水箱中。
现象图如下图4.5所示:
图4.5上水位
现象五
当水温超过上限值时,加热继电器就会分离,加热指示灯熄灭,代表了热水器的加热功能关闭。表现为黄色、绿色
和红色指示灯都处于熄灭状态。现象图如下图4.6所示。
当温度降低到水温下限值时,同时热水器中依然有足够的水,此时热水器的加热功能就会重新开启。表现为黄
灯亮、绿灯和红灯不亮。
现象五:
将上水位传感器放入水中,此时系统出现错误,表现为红灯亮,蜂鸣器一直响,直至人为按下取消报警建(即确认
键)蜂鸣器才停止工作。
现象六:
按下功能按键来设置定时时间为1min。在这1min之内,即使当前的温度是低于水温下限值并且热水器中已经注
满水,热水器也不会开始加热。当1min定时时间到了,热水器就会自动开始加热,定时时间清零。
4.4 本章总结
在本章中,通过软件和硬件地不断调试,最终完成了本次的设计任务。起初把多次调试好的程序和仿真电路在
电脑上运行,能够实现的任务和要求的一致,未出现错误。但把程序烧入实物里的单片机芯片中时,能够实现的功
能和预期地不一样,初步考虑是电路焊接问题。之后通过万用表等一些测量工具,不断地进行排查,这期间对程序
也做了一定地修改,最终实物能够正常运行起来,实现的功能达到了预期的效果。
整个设计调试的大概过程为:先在Altium Designer 软件中绘制整个电路的原理图,这一步尤为重要,关系最
终实物焊接的成败。之后依据绘制好的原理图,在Keil uVision4 软件中编写程序,编译无误后将程序写入原理图
中的单片机芯片中,进行仿真调试,仿真效果达到预期后就可以对照着原理图进行实物地焊接。
第五章 总结与展望
5.1 总结
本次设计的智能热水器耗时近三个月,先是经历了硬件部分的设计与焊接,之后又不断地通过软件设计来调试
整个电路,这期间用到了大学期间所学习的大部分相关知识,可谓是活学活用。本次课题的设计主要是针对
STC89C51单片机相关知识点的运用,搭配其他所学的知识点来共同完成的,例如电力电子技术、模电技术等等。其
实,本次毕业设计可以算得上是一次小的工程设计,这让我对大学四年所学的大部分知识有了更高层次的认识。
本次设计的热水器在智能化方面有了一定的提高,但有些方面还是可以做到更好。例如远程操控方面,可以与
手机联网,通过手机就可以实现人不在家就能控制热水器,同时还可以设计语音唤醒功能,使操作更加的智能化,
为社会上残疾人士提供使用更加简单方便的热水器。就目前人们的需求来说,本次设计的热水器已经足够了,但科
技是一直在进步的,只有不断地学习尝试,才会跟上社会的步伐。
此次的毕业设计的过程使我学到了很多宝贵的经验,这些经验是单纯的学习理论知识所学不到的。只有真正的
把知识应用到实践中,才能真真体会到学习的乐趣所在。在本次设计中,我也体会到自己的知识储备的缺乏,这也提
醒我要不断地学习思考,虚心向他人请教。
5.2 展望
本次的设计完成了热水器的大概的一些功能,但其实还有很多可以扩展的地方。例如,长期使用的热水器,难
免会积累很多水垢,所以在本次设计的热水器基础上,可以增加自动清洗的功能。其实还有很多可以改善的地方,
这些对于后面的学习提供了方向,给予我不断改进热水器的动力。
作者:qq_1694456187