基于DS18B20温度控制系统

摘要

温度作为环境监控中具有重要意义的参数之一,其直接影响植物生长、土壤变化,也密切关联着高质量农产品的栽培,在工业生产等诸多领域均起着至关重要的作用。温度控制系统的实现是一个非常关键的课题,但是目前先进的温度测量技术存在数据采集精度较低、检测不科学等问题。

为了解决上述问题,本文设计了一种温度控制器,可以实时监测水温。本文可以及时获得设备内的水温,时间延迟为1ms,并根据需要控制热源来控制水温。本文主要研究了一种基于DS18B20温度传感器的温度模拟系统。 该系统控制核心为单片机, DS18B20温度传感器作为对环境温度进行实时监测的重要元件,实现环境温度的检测和管理功能。此外,系统还具有其他功能,包括环境温度数据显示和跨线报警功能。

本文的主要研究内容如下所示:

(1) 首先针对温度的测量以及控制技术的国内外研究现状进行阐述。

(2) 其次温度控制系统的具体需求对温度耦控制系统的硬件部分进行了设计以及传感器等模块的选择,介绍了不同传感器芯片以及单片机的特点和工作原理。

(3) 利用keil C汇编语言,按照系统的功能需求完成温度控制系统的软件部分调试。

(4) 最后介绍本文采用的系统硬件的低功耗措施和软硬件的抗干扰措施,并总结了系统的Keil C系统调试经验,针对系统的仿真结果加以阐述。

本系统经过实验验证,各项指标均满足温度控制系统的要求,效果良好且性能可靠稳定,可以应用于水温、大棚以及工业生产等对温度的监测与控制等领域。

关键词:单片机;温度控制系统;DS18B20;

Abstract

Temperature is one of the most important parameters in environmental monitoring, which directly affects plant growth, soil changes, and is also closely related to the cultivation of high-quality agricultural products, and plays a crucial role in many fields such as industrial production. The implementation of temperature control system is a very critical topic, but the current advanced temperature measurement technology has problems such as low data collection accuracy and unscientific detection.

In order to solve the above problem, a water temperature controller with instantaneous monitoring of water temperature has been implemented to obtain the temperature of the water in the equipment and to control the water temperature as required for the heating source. This paper focuses on a temperature simulation system using a DS18B20 temperature sensor. The system is based on a microcontroller chip and uses the DS18B20 temperature sensor to monitor the ambient temperature in realtime, thus realising the function of detecting and managing the ambient temperature, in addition, the system also has the function of displaying the ambient temperaturedata and alarming the crossing of the line.

The main research contents of this paper are as follows.

(1) Firstly the current status of domestic and international research on temperature measurement as well as control technology is described.

(2) Secondly, the hardware part of the temperature control system is designed and the sensor modules are selected according to the specific requirements of the temperature control system, and the characteristics and working principles of different sensor chips and microcontrollers are introduced.

(3) Using keil C assembly language, the software part of the temperature control system is debugged according to the functional requirements of the system.

(4) Finally, the low power consumption measures of the system hardware and the anti-interference measures of the hardware and software adopted in this paper are introduced, and the experience of debugging the system in keil C is summarised and the simulation results of the system are elaborated for the system.

The system has been experimentally verified that all the indicators meet the requirements of the temperature control system, with good results and reliable and stable performance, and can be applied to the monitoring and control of temperature in the fields of water temperature, greenhouse and industrial production.

Key: microcontroller ; Temperature control system; DS18B20;

第1章 绪论

1.1 研究背景

随着我国科技信息化、自动化水平的提高,温度作为生命生存、工业生产等方面最基本的环境参数之一,无论是物理、化学还是生物科学等方面都与环境的温度息息相关。在电力系统、化学工厂、石油以及机械制造等工业生产场所与实验室,甚至农业塑料大棚、人类居住环境等多领域均需要对环境温度的实时检测与监控,并需要对其所处在的环境区域进行温度控制。

温度测量方法主要有接触式温度测量和非接触式温度测量。 非接触式温度测量的价格相对较高,具有一定的局限性; 在温控系统开发的早期阶段,通过两个物体之间的热平衡,两个物体接触来测量目标物体的温度。该接触式的测量方式具有简洁、数据更真实、造价较低等优点。但是也存在对于热容量比较小的物体测量准确度较低等现象。接触式测温一般在外层包裹一层不锈钢套管,其导热系数会对问的测量的准确性有一定的影响。此外,也不能应用于易腐蚀性介质以及极高温度的测量部分。而目前对于温度传感器的选择主要存在感温元器件选型、装置匹配等问题,根据硬件结构的设计,提高测温精度,实现温度控制系统。

本课题为了实现对温度的实时控制,以水温为例,实时获得装置内水的温度并按要求对加热源实施控制对水温的温度控制。采用对装置内水的温度进行实时检测,并判断是否在要求的温度范围,根据比较结果,做出对加热源的实时控制,使水温控制在35 ℃~38℃范围。研究基于DSl8820温度控制传感器,利用单片机的控制来实现温度控制系统,是解决装置内水恒定温度的实时控制的重要手段。

1.2 国内外研究现状

1.2.1 温度测量模块

温度作为最基本的物理量,代表着对物体冷热的测量。 随着科学的进步,国内外在新材料、传感器等元器件以及自动化技术的突破,温度控制系统的研究也进日益迫切。

郁翔,赵学增等将DS18B20传感器应用于AT90S8515单片机。其将温度数字传感器DS18B20与铂电阻组成的多路测温传感器进行了对比。其中,在以铂电阻为传感器的多通道检测系统中,由于其应用时引线较长,会造成一定的误差。通常,自动补偿将通过三线制或四线制实现。 然而,电流和电压引线是基于多通道模拟开关进行切换的。 此外,需要为铂电阻提供稳定的恒流源,以确保良好的线性度、信号放大的零位移等,对长引线、多通道模拟开关、端子、控制电路等元件的需求量很大。 温度传感器DS18B20支持单线总线,即只需一根线即可完成温度信号的传输。一条总线可以简化系统,也可以降低成本。只不过这样系统对软件的要求相对较高。

赵松等基于单总线结构的DS18B20温度传感器设计了感温元件。该设计可以解决田间土壤温度的控制系统。在设计过程中采用了多层土壤温度探测传感器系统。魏英智等基于DSl8820传感器设计了温度控制系统,其研究对象主要是水流,主要应用在:医学、家庭生活等方面,例如医用洗胃、浴室温度控制、烧水壶温度控制等。王明辉等人将DS18B20传感器应用于化工领域,将化工现场环境与系统结合起来,在单片机系统中实现了温度检测原理和程序设计功能。

         上世纪60年代起,国外发达国家即投入到环境温度控制系统方面的研究,其各方面产品相对成熟。随着技术的突破、数字化时代的到来,将计算机科学、传感器网络以及自动控制等技术相结合,可以大幅度提高工作效率。例如,DFS-1000测温系统和远中距离测温系统均为20世纪90年代由日本和英国公司研发。

目前国内对温度控制系统的研究,主要集中在化工以及农业方面。而以往对温度的控制大多数为人为控制,这样设备存在着一些弊端,会出现不可控因素。

1.3 主要研究内容及技术方案

1.3.1 主要研究内容

本课题为解决对水流温度的实时检测,实现水流温度控制系统的设计。基于目前国内外研发出的高性能温度传感器,完成单片机仿真电路设计及系统软件研发设计,最后进行了试验研究。本课题主要包含以下4个基本功能:

  1. 选择合适的加热源,以便对流水温度进行控制。
  2. 实现在流水的过程中,控制温度(水流温度在35—38度之间)。
  3. 当系统按照要求,开始预热及结束后,系统会相应给出信号。
  4. 编写相关程序,有详细的程序说明。有仿真结果。

1.3.2 技术方案

本文的研究方案是基于温度传感器DS18B20。单片机作为系统基本控制核心。当按下开始按键后,开始预热;当温度上升至38度,温度控制系统开始运行;当温度超过设定温度时,触发越线报警器模块,会发出报警声音。当温度处于设定值时结束加热,进入循环。此外还可以通过外部键盘改变温度的设定值。系统的基本结构框图如图1-1所示:

图1-1 系统的基本结构框

1.3.3 论文章节安排

第一章绪论,介绍了温度控制系统国内外研究背景,总体概述系统的基本结构框。

第二章温度控制系统的总体设计方案和硬件设计,分别介绍了温度控制系统的总体设计方案,以及硬件单片机模块、温度采集模块、温度传感器模块、温度传感器模块的功能、性能和引脚,分别介绍了显示模块和跨线报警模块。

第三章温度控制系统软件实现,利用Keil C51编译调试,配合硬件达到温度检测、对温度的设定、显示、报警等功能,完成单片机的开发与应用。

第四章系统性能总结与分析,针对芯片的选择、硬件设备和软件设备抗干扰等措施分析以及Keil C调试系统的经验等方面进行总结。

第五章总结,整体分析并总结温度控制系统的整体构建以及硬件、软件设计。对温度控制系统实现的功能进行总结。

第2章 温度控制系统设计总体方案及硬件设计

本章将以水温控制系统为例,根据系统的功能、设计要求和性能指标,详细介绍系统的总体组成框图和各部分硬件电路的设计方案,并介绍了主芯片的原理和应用。 控制核心芯片选用AT89S52单片机; 测温电路采用美国达拉斯公司生产的单线总线数字温度传感器dsl8820;数字显示电路采用LED数码管7seg-mpx4-ca,动态显示方式。

2.1温控系统总体设计方案

本文温度控制系统设计的总体功能如下:

(1) 实时显示温度检测功能。

(2) 温度控制功能:可方便地设置和维护所需的温度值,直到设置为另一个温度值。系统将自动加热到此值,并将其保持在一定的恒温范围内。

(3) 定时功能:可设定系统开始工作的时间和恒温的持续时间。

(4) 系统需要具备掉电保护功能,下一次上电后可保持相关整定参数。

(5) 尽量使用标准化零件。一旦损坏,在市场上很容易买到替代零件。

本文温度控制系统设计的主要技术指标如下:

  1. 系统的温度范围为0℃~99℃。
  2. 系统控制精度为士l℃。
  3. 本系统的额度功率为100W。
  4. 系统的实测温度数字可以实时显示。
  5. 系统对电源要求为AC 220V。

设计原则如下:

    (1) 在满足功能、性能和使用的前提下,使系统的成本和体积最小化;

(2) 在开发过程中,我们应该充分利用最新的技术和研究成果,确保目前和未来中国的先进性和实用性。

(3)在设计中应充分考虑系统的可靠性、可用性、可维护性和可扩展性,为设备的使用、维护、寿命延长和功能扩展奠定基础;

(4) 外观美观大方,配色合理。

2.2 总体硬件设计模块

温度控制系统以AT89S52单片机为核心,基于dsl8820控制整个测试系统,进行温度测量和数据处理; 将测量结果发送至LED显示屏输出,并驱动相应的温控设备。 实时温度由单线总线数字温度传感器dsl8B20获得。温度经单片机处理后,一方面通过显示驱动电路送到LED数码管进行显示。另一方面,将温度值与控制值进行比较。其结果是通过控制固态继电器来实现加热装置的通断控制,如流程图2-1所示。

图2-1 温度控制系统流程图

当系统通电时,将显示实时温度。一旦系统开始工作,MCU将测量的温度与设置的温度进行比较。当测量温度低于设定温度值的1℃时,加热设备开始加热。当测量温度高于设定温度值时,加热设备停止加热。在此期间,MCU继续根据上述条件进行判断,直到计时时间到来,当加热设备停止加热时,报警会发出报警。 可通过修改软件程序设置恒温范围。 电源部分采用220V交流电,经变压、滤波、稳压后,系统获得5V电压。整体框图如图2-2所示。

图2-2 温度控制系统硬件整体框图

2.3 单片机模块

单片机模块采用AT89C52单片机装置,采用ATMEL公司生产的高密度、非易失性存储技术。它是一种低压CMOS管8位高性能单片机。 它包含8K字节的可重写闪存只读程序存储器和256字节的随机存取数据存储器(RAM)。 AT89C52单片机装置与标准MCS-51指令系统兼容。该芯片有一个通用的8位CPU和闪存存储单元。它广泛应用于电子行业。

AT89C52单片机有40个引脚,其中32个为外部双向输入/输出端口(I/O),包括2个外部和中间断口、3个16位可编程定时计数器、2个全双工串行通信端口和2条读写端口线。 AT89C52可按常规方法编程或在线编程。 它将普通微处理器与闪存,特别是可重写闪存相结合,可以有效降低开发成本。 AT89C52有三种封装形式:PDIP、PQFP/TQFP和PLC,以满足不同产品的需要。本系统所采用的单片机最小系统如图2-3所示。

图2-3 单片机最小系统硬件设计图

2.4 温度采集模块设计

在温度传感器的选择中,热敏电阻的优点在于其成本较低,但是后续的电路设计复杂,温度标定困难。对于输出模拟信号的温度传感器,其输出端模拟信号相对较为薄弱、仍需要信号放大器、A/D转换器等部分放大电路信号,然而其放大器昂贵、系统成本较高。

本设计的温度采集模块由DS18B20温度传感器组成。 DS18B20温度传感器由达拉斯半导体公司引进。其测温范围为-55℃~+125℃,在-10℃~+85℃范围内误差为±0.4℃。此外,该款传感器返回两字节十六进制的温度数值,其中16位二进制是由于该传感器是一种基于“一线总线”接口设计的传感器,所以只有一根I/O线,只能以二进制操作,即每8次得到一个字节,读入两个字节得到完整的温度数据。其具体功能特性如下:

(1) 宽电压应用范围(3V~5V)。

(2) 温度测量范围:-55摄氏度~+125摄氏度。其中测量精度在:10℃~85℃为±0.5℃。

(3) DS18B20采用独特的单线接口方式,只需一条通信线即可实现微处理器与DS18B20的双向通信。

(4) DS18B20支持多点联网功能。多个dsl8820可以在一条独特的三线上并联连接。每片dsl8820都有一个64位序列号存储在片上Rom中,因此,多个DS18B20可以共存于同一条数据传输线上,实现多点温度测量。 CPU只需要一条端口线就可以与多个DS18B20通信。它占用微处理器的端口较少,可以节省大量的引线和逻辑电路。

(5) DS18B20在使用中不需要任何外围组件。

(6) 用户还可以通过编程实现9~12位温度读数,即温度分辨率可调。

(7) 用户可自行设置非易失性温度报警th和TL的上下限。

(8) 典型的供电方式为三线制,可通过总线供电,供电电压为3v-5v。也可以使用由寄生电源供电的2线制系统。 由于DS18B20的分辨率可以通过编程选择,因此在提高分辨率的前提下,DS18B20比DS18B20具有更好的一致性。

主从机之间的通信采用单总线,即数据传输和接收采用单线。使用时无需外围器件,工作可由独立芯片完成。 与传统热敏电阻等测温元件相比,它不仅体积小、电压宽、与微处理器接口简单,而且总线结构简单经济。它可以使用户方便地建立传感器网络,从而为测量系统的建设引入新的概念。这是一个数字温度传感器。

DS18B20的温度测量原理如图2-4:每次测量前,先将55℃对应的基数分别放入减法计数器1和温度寄存器中。 减法计数器1减去由低温系数晶体振荡器产生的脉冲信号。当减法计数器1的预设值减小到0时,温度寄存器的值将增加1,并且减法计数器l的预设值将再次加载。减法计数器1再次开始对低温系数晶体振荡器产生的脉冲信号进行计数。此循环将继续,直到减法计数器2计数为0,停止温度寄存器值的累积,并且温度寄存器中的值为测量温度。 斜率累加器用于补偿和校正温度测量过程中的非线性,其输出用于校正减法计数器的预设值。只要计数门未关闭,重复上述过程,直到温度寄存器值达到测量温度值。

图2-4 DS18B20的温度测量原理

DS18B20可以使用外部电源或寄生电源。 寄生电源的原理是利用总线信号实现寄生电源。 在寄生电源的情况下,当总线信号高时,DS18B20从总线获取能量并将其存储在内部电容器上; 当总线处于低电平时,电容器向DS18B20供电。 利用DS18B20的这一特性,可以形成一个简单清晰的温度检测系统,可以节省大量的布线和施工成本。

2.5 按键及显示模块

键盘和显示电路主要用于人机互动,包含键盘以及显示两大部分。其可以反映系统状态的同时,可以便于人工干预。

2.5.1 键盘模块

键盘作为单片机应用系统中至关重要的部件之一。它能实现输入数据、传送 命令等功能,是人工干预系统的主要手段。键盘可分为编码键盘和非编码键盘两种。前者用软件来识别和产生代码,后者用硬件来识别,本文在设计中使用独立式编码键盘。

2.5.2 显示模块

显示模块采用7seg-mpx4-ca数码管,四个公二极管显示器1、2、3、4为公共端子。 LED数码管由四个8形发光管组成,每个发光管有8个部分。 这些段分别用字母a、B、C、D、e、F、G、DP表示。 当用户编辑控制端口的不同逻辑电压时,这些特定段根据信号要求形成字符。

7seg-mpx4-caled数码管的结构如图2-5所示。 其中端口1、2、3、4为位选择端口,端口P0与段码连接,P2的4位用于I/0位选择。

图2-5 7seg-mpx4-caled数码管的结构图

7seg-mpx4-ca的工作原理是动态显示。 MCU的输出端口输出字体代码,LED数码管的接收端口可以接收字体代码,但只能点亮选定的段。 主要原因是用户只能通过位选通控制字段打开要显示的数码管的选通控制来显示字符,没有选通的数码管将不会点亮。 控制数码管的公共com端可以使每个字段依次显示字符。

旋转显示过程中的时间非常短。由于人类视觉的持久性和发光二极管的余辉效应,各个领域都采用旋转显示,但只要旋转显示的间隔足够短,人们就会觉得它是稳定的显示数据。 另外,使用动态显示还可以节省大量的I/O端口,目标功耗低,显示效果与静态显示相同。

本文选用的7seg-mpx4-ca是一种常用的阳极数码管。LED数码管的端口1、2、3和4是位选择端口。数码管显示器可以通过控制1、2、3和4的高电平和低电平来控制。 本文中,端口1、2、3、4分别与单片机P2端口的下位4位相连,单片机P0端口与显示端口相连。本温度控制系统7seg-mpx4-ca数码管与单片机连接设计图如图2-6所示。

图2-6 7seg-mpx4-ca数码管与温度控制系统单片机硬件设计图

2.5.3 过线报警模块

当DS18B20完成温度转换时。 温度值将与th和TL寄存器中的上限和下限进行比较。th和TL寄存器的格式如表2-1所示。

表2-1 TH和TL寄存器格式

bit7

bit6

bit5

bit4

bit3

bit2

bit1

bit0

S

26

25

24

23

22

21

20

标志位s表示温度为正或负。当温度为正时,s=0; 当温度为负时,s=1。 如果温度测量结果高于Th或低于TL,则存在报警条件,DS18B20中将设置一个标志,该标志将在每次温度测量后更新。因此,如果报警条件消失,则标志位将在下一次温度转换期间关闭。 越界报警模块电路图如图2-7所示。

图2-7 越界报警模块电路图

本部分采用的是SPEAKER元器件。一般在SPEAKER元器件的硬件设计中,最好不要直接采用单片机的P端口直接驱动元器件。在实验中无法使用通过仿真,因为单片机的P口直接驱动,因为P端口的驱动能力较弱,没有办法驱动SPEAKER“大功率”用电器。因此,在实际仿真与使用的时候可以采用三极管进行信号放大,如图2-8所示,从而驱动SPEAKER元器件。

图2-8 三极管信号放大器件图

本系统采用的是PNP型三极管。单片机与三极管电路驱动SPEAKER的电路设计如图2-9所示,单片机仿真图中,左部分作为单片机最小系统,右部分作为SPEAKER驱动电路。当温度高于阈值,则单片机P3.3端口输出高低电平交替信号,三极管导通,SPEAKER元器件工作。当P3.3端口持续输出高电平是,SPEAKER元器件不工作。

图2-9 单片机与三极管电路驱动SPEAKER的电路设计图

2. 6 本章小结

本章以水流量温度控制系统为例,首先介绍了温度控制系统的组成,并简要介绍了系统的硬件设计、功能原理、主要技术指标和性能特点。 其次,详细介绍了系统各模块的硬件电路设计,并介绍了主芯片的功能、特点和用途。键盘模块作为单片机应用系统中重要组成部分,使用独立式编码键盘,实现输入数据、传送和命令等功能。温度检测系统由dsl8820数字温度传感器组成,以AT89S52单片机为数据处理和控制核心。 为了减少电路板的空间和成本,简化设备之间的连接,提高可靠性,简化系统结构,增加系统扩展的灵活性,在设计中更多地采用了串行技术。

第3章 温度控制系统的软件实现

本章主要针对温度控制系统的软件部分展开阐述。介绍了温度控制系统的Keil C51软件设计、主程序设计以及按键显示、报警子程序等各个部分的软件设计。主程序将围绕温度数据采集、传输和对温度的监控展开描述。子程序包括按键显示部分以及越线报警部分,可以通过按键实现对温度的高低阈值控制。

3.1 软件设计概述

系统程序采用Keil C51作为编程语言进行编译和调试。所设计的软件需要硬件配合才能实现温度控制系统的温度、报警等功能的实现。 C51是一种用于单片机的C语言程序设计语言。 与标准C语言一样,它也是一种结构化编程语言。它支持当前编程中广泛使用的自顶向下的结构化编程技术,可以方便地实现程序结构的模块化。 用C51编写系统程序将大大缩短开发周期,显著提高软件的可读性,使程序易于维护和扩展,具有很强的可移植性。 因此,利用C51设计单片机程序是单片机发展和应用的必然趋势。

目前, C语言的代码长度达到汇编级的1.2~1.5倍。 尤其是4K以上字节的代码,采用C语音更具备优势。 从开发速度、软件质量和严谨的结构来看,C语言的完美程度绝对无法与汇编语言编程相比。 使用MCU C语言具有以下优点:

(1) 覆盖不同功能的数据,有效利用芯片上有限的RAM空间;

(2) 健壮性:C语言有很多专业的数据处理,避免了中间数据的破坏;

(3) 它提供了复杂的数据类型(结构、枚举、指针等),极大地提高了程序的处理能力和灵活性;

(4) 提供8051单片机专用的自动、静态、常量等存储类型和数据、IData、nata、扩展数据、代码等存储类型,自动合理分配变量地址;

(5) 提供小、紧凑、大等编译模式,以适应片上存储器的大小;

(6) 中断服务程序的现场保护和恢复以及中断向量表的填充由编译器处理;

(7) 头文件定义宏。头文件可以解释复杂的数据类型和功能原型。定义宏在程序移植和开发过程中相对更容易一些,系统兼容性更好;

(8) 它可以方便地接受各种实用程序的服务,如片上资源的初始化,并自动生成特殊的实用程序。

由上述可知,C语言在系统编程实现以及实现后的兼容性等方面均更容易、更稳定于汇编语言。因此, 本设计的软件设计遵循软件工程的要求,采用模块化结构。

3.2主程序的功能与实施

温度控制系统软件的设计和实现将围绕温度数据采集、传输和监控进行描述。 作为系统的“大脑”,系统软件起着核心作用。在其设计过程中,需要不断优化,然后设计出适合本系统的定制软件,以提高测温效率,保证系统长期稳定运行。 C51软件编写的主要程序列表如表3-1所示。

表3-1 C51软件编写的主要程序

/********主函数**********/

VOID MAIN (  )

{ TIME_INIT(  );            //初始化定时器

WHILE( 1 )

{ KEY(  );              //按键程序

IF( KEY_CAN < 10 )

{ KEY_WITH(  );         //设置报警温度

}

IF( FLAG_300MS == 1 )

//300MS 处理一次温度程序

{ FLAG_300MS = 0;

TEMPERATURE = READ_TEMP(  ); //先读出温度的值   CLOCK_H_L(  );        //报警函数

IF( MENU_1 == 0 ) 

{DIS_SMG[0] = SMG_DU[TEMPERATURE % 10];

//取温度的小数显示

DIS_SMG[1] = SMG_DU[TEMPERATURE / 10 % 10] & 0XFB;

//取温度的个位显示

DIS_SMG[2] = SMG_DU[TEMPERATURE / 100 % 10] ;  //取温度的十位显示

}

}

DISPLAY(  );//数码管显示函数

}

}

3.3 子程序设计与实现

3.3.1 按键显示子程序

按键显示模块分为设置高阈值和低阈值设置,如果menu==1时,加号与减号控制高阈值,当按键一直按着未松开时,温度的高阈值分别以三次和十次两种模式持续增长或衰减;如果menu==2时,加号与减号控制低阈值,当按键一直按着未松开时,温度的高阈值分别以三次和十次两种模式持续增长或衰减。显示区域分别计算温度的小数、个数以及十位三位,满足温度控制范围。

本系统除按键与显示模块外,还存在独立按键部分,如图3-1所示。

按键显示模块分为设置高阈值和低阈值设置,如果menu==1时,加号与减号控制高阈值,当按键一直按着未松开时,温度的高阈值分别以三次和十次两种模式持续增长或衰减;如果menu==2时,加号与减号控制低阈值,当按键一直按着未松开时,温度的高阈值分别以三次和十次两种模式持续增长或衰减。显示区域分别计算温度的小数、个数以及十位三位,满足温度控制范围。

本系统除按键与显示模块外,还存在独立按键部分,如图3-1所示。

图3-1 独立按键部分设计图

其功能主要包含:当点击第一个按键时,得到k1键值;当点击第二个按键时,得到k2键值;当点击第三个按键时,得到k3键值。由软件C51编写的独立按键程序列表如表3-2所示。

表3-2 C51软件编写的独立按键程序

/*******独立按键程序************/

UCHAR KEY_CAN; //按键值

VOID KEY()              //独立按键程序

{ STATIC UCHAR KEY_NEW;

KEY_CAN = 20; //按键值还原

P3 |= 0XF0;

IF((P3 & 0XF0) != 0XF0)    //按键按下

{ IF(KEY_500MS == 1)       //连加

{ KEY_500MS = 0;

KEY_NEW = 1;

}

DELAY_1MS(1);        //按键消抖动

IF(((P3 & 0XF0) != 0XF0) && (KEY_NEW == 1))

{//确认是按键按下

KEY_NEW = 0;

SWITCH(P3 & 0XF0)

{ CASE 0XD0: KEY_CAN = 3;

BREAK; //得到K1键值   CASE 0XB0: KEY_CAN = 2;

BREAK; //得到K2键值

CASE 0X70: KEY_CAN = 1;

BREAK; //得到K3键值

}

FLAG_LJ_EN = 1;    //连加使能

}                                            

}

ELSE

{ IF(KEY_NEW == 0)

{ KEY_NEW = 1;

FLAG_LJ_EN = 0; //关闭连加使能

FLAG_LJ_3_EN = 0; //关闭3秒后使能

KEY_VALUE = 0;     //清零

KEY_TIME = 0;

KEY_500MS = 0;

}

}                                 

}                                 

在本设计中,显示器采用硬件电路驱动八位LED。作为系统的显示器,主要完成连续循环温度检测的功能。 首先,要显示的BCD代码(非压缩)先存储在MCU的显示缓冲区中。然后,调用显示子例程。通过P1-2端口,微控制器向显示驱动芯片发送数据。通过微控制器可以驱动LED数码管显示当前值。 LED显示屏采用动态显示方式。 根据键盘获取得到k1键值、k2键值和k3键值,以下是根据键值由软件C51编写的AT89S52接口程序列表(见表3-3)。

表3-3 C51软件编写的按键处理数码管显示函数

/****按键处理数码管显示函数***************/

VOID KEY_WITH()

{ IF(KEY_CAN == 1)   //设置键

{ MENU_1 ++;

IF(MENU_1 >= 2)

{ MENU_1 = 0;

SMG_I = 3;            //数码管显示3位

}

}

IF(MENU_1 == 1)         //设置高温报警

{ SMG_I = 4;          //数码管显示4位

IF(KEY_CAN == 2)

{ IF(FLAG_LJ_3_EN == 0)

T_HIGH ++ ;         //按键按下未松开自动加三次 

ELSE

T_HIGH += 10;      //按键按下未松开自动加三次之后每次自动加10

IF(T_HIGH > 990)

T_HIGH = 990;

}

IF(KEY_CAN == 3)

{ 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] & 0XFB;  //取个位显示     DIS_SMG[2] = SMG_DU[T_HIGH / 100 % 10] ;

//取十位显示

DIS_SMG[3] = 0X26; //H

}

IF(MENU_1 == 2)         //设置低温报警

{SMG_I = 4;           //数码管显示4位

IF(KEY_CAN == 2)

{ IF(FLAG_LJ_3_EN == 0)

T_LOW ++ ;              //按键按下未松开自动加三次 

ELSE

T_LOW += 10;        //按键按下未松开自动加三次之后每次自动加10

IF(T_LOW >= T_HIGH)

T_LOW = T_HIGH - 1;

}

IF(KEY_CAN == 3)

{ IF(FLAG_LJ_3_EN == 0)

T_LOW -- ;              //按键按下未松开自动减三次 

ELSE

T_LOW -= 10;        //按键按下未松开自动加三次之后每次自动加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] & 0XFB;   //取个位显示

DIS_SMG[2] = SMG_DU[T_LOW / 100 % 10] ;        //取十位显示

DIS_SMG[3] = 0XBC;   //L

}

3.3.2 报警子程序

在本设计中报警子程序部分是根据温度检测结果,控制继电器的开关。温度过高,则传递的flag为1,打开蜂鸣报警器以及继电器。否则,关闭继电器,系统持续循环工作。下面给出软件C51编写的接口程序清单(见表3-4)。

表3-4 C51软件编写的报警子程序

/****************报警函数********/

VOID CLOCK_H_L()

{ STATIC UCHAR VALUE;

IF((TEMPERATURE<=T_LOW)||

(TEMPERATURE>=T_HIGH))

{ VALUE ++;  //消除实际距离在设定距离左右变化时的干扰

IF(VALUE >= 2)

{ IF(FLAG_EN == 1)

BEEP = ~BEEP;                  //蜂鸣器报警

IF(TEMPERATURE <= T_LOW)

RELAY1 = 0;    //打开继电器       IF(TEMPERATURE >= T_HIGH)

RELAY2 = 0;    //打开继电器      

IF(TEMPERATURE >= T_HIGH)

RELAY2 = 0;    //打开继电器      

}                                          

}

ELSE

{ BEEP = 1;                       

RELAY1 = 1;    //关闭继电器      

RELAY2 = 1;    //关闭继电器      

FLAG_EN = 1;

}}

3.3.3 DS18B20温度传感器温度控制程序

DS18B20的内部存储器由高、低温触发器、电擦除寄存器和高速暂存系统四部分构成。DS18B20的每片均含有64 位编码,并可以直接录入到 ROM 中。每一个 64 位编码都代表着不同的含义,其中前 8 位代表的是DS18B20产品的家族码,后8位是CRC 码,可以用于校验,中间48 位作为该温度传感器自身的序列号。每个DS18B20温度传感器的序列号均相互独立,所以可以一根总线上,多个DS18B20温度传感器协调工作、互不影响。关于DS18B20温度传感器中常见的几种ROM指令可分为五项,如表3-5所示。

表3-5 DS18B20温度传感器中常见的几种ROM指令

操作命令

33H

55H

CC

FOH

ECH

含义

读 ROM

匹配 ROM

跳过 ROM

搜索 ROM

报警搜索 ROM

主机接收到相应的 ROM 操作命令后,就可以根据操 作命令进行相应的操作,完成对内部存储器的控制,其具体情况如表 3-6 所示。

表3-6 DS18B20温度传感器对内部存储器的控制

操作命令

4EH

BEH 

48H

44H

B8H

B4H

含义

内部复制

温度转换

重新调出

读电源

温度控制系统主程序部分主要是实现对温度的实时监测与显示,并对监测出的温度值进行读取与处理,其中将温度的监测延迟设置为1ms。温度控制程序的流程图如图3-2所示。

图3-2 DS18B20温度传感器温度控制程序的流程图

对DS18B20温度传感器初始化、监测出的温度值进行读写与处理程序的接口程序清单如表3-7所示。

表3-7 C51软件编写的温度控制系统子程序

/***********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

EA = 0;

INIT_18B20();//初始化18B20

WRITE_18B20(0XCC); //跳过64位ROM

WRITE_18B20(0XBE); //发出读取暂存器命令

LOW = READ_18B20();//读温度低字节

                   VALUE = READ_18B20();  //读温度高字节

EA = 1;

VALUE <<= 8; //把温度的高位左移8位

VALUE |= LOW; //把读出的温度低位放到VALUE的低八位中

VALUE *= 0.625; //转换到温度值 小数

RETURN VALUE;      //返回读出的温度

}

3.4 总结

本章主要阐述温度控制系统主程序和显示报警子程序的功能。 硬件电路驱动八位LED数码管作为系统的温度显示。根据温度传感器的监测结果,使用报警子程序控制继电器的开关。 如果温度过高,则传输标志为1,SPEAKER警报和继电器打开。 否则,关闭继电器,系统将继续循环。最后,实现了温度监控,并对温度控制系统进行了改进。

第4章系统性能总结与分析

本章主要针对系统的性能以及仿真过程中要考虑的问题展开阐述,首先是介绍了系统硬件的低功耗措施和软硬件的抗干扰措施,其次总结了系统的Keil C系统调试经验,最后针对本系统的仿真结果加以阐述,验证本系统具有良好的效果与稳定的性能,各项指标均满足温度控制系统的要求。

4.1系统低功耗措施

(1) 为降低系统功耗可采用低功耗的CMOS芯片。

(2) 系统的键盘采用编码键盘的中断扫描模式,即只有在键盘上按下一个键时,才执行键盘扫描和键功能程序。如果没有按键,CPU将忽略键盘,从而提高CPU工作效率,提高系统对键盘的响应速度。

(3) 在软件设计时,选择低功耗系统待机模式,使系统空闲时处于待机低功耗状态,也可以降低系统的功耗。

(4) 系统负载功率小,热惯性小,温度滞后时间短,同时超调小。

4.2 抗干扰措施

4.2.1硬件抗干扰措施:

(1)印刷电路板的设计中,采用更宽的电源线和地线,提高抗干扰能力。

(2) 在每个集成芯片的电源附近添加滤波电容器。

(3) 尽量减少电源接线的有效周围区域。

(4) 尽量避免在印制板上打开或开槽,尤其是在地线层或电源线附近:打开或开槽可能会增加电流路径的有效周围面积。

(5) 布线中不得有分支或缠绕,因为这可能导致反射和谐波产生。 因此应避免900条断线在接线时,这样可以减少高频噪声发射。

(6) 敏感元件的接地端应采用抗干扰保护环。保护环在一个点接地,周围部分的辐射有效减少。

(7) 不要在印制板上留下空白的铜层,因为它们可以用作发射天线或接收天线来将其接地。

4.2.2软件容错和抗干扰措施硬件

软件容错和抗干扰措施如下:

软件容错性是衡量软件性能的重要指标。 主要是防止由于操作人员的误操作或其他原因导致系统异常退出或崩溃,避免给操作人员带来不便甚至数据丢失。 在系统的软件设计中,在一些容易形成死区的地方,例如初始化dsl8820时,不是等待电平条件满足后再继续下一步操作,而是根据初始化顺序主动读取电平状态,如果满足条件则执行。否则,放弃此操作并再次发送信号进行初始化。

软件抗干扰措施

(1) 在测量数据时,CPU操作和控制功能采用数字滤波方法,以减少随机噪声。

(2) 避免软件冗余。将控制条件的一次采样和处理控制输出更改为循环采样和处理控制输出。 这对大惯性系统具有良好的抗干扰效果。

(3) 设置存储单元的当前输出状态。当干扰侵入输出通道并破坏输出状态时,系统可以及时查询寄存器的输出状态信息,并及时纠正输出状态。

    (4) 设置自检程序。 在微机中的特定部件或某些存储单元上设置状态标志位,并在启动后进行连续循环试验,以保证系统中信息存储、传输和运行的高可靠性。

4.3 Keil C系统调试经验

(1) Keil C软件不支持中文,显示的鼠标与实际位置不一致。该现象会严重影响中文注释的修改。 在Windows下,您可以将字体设置为courier,这样字体可以正常显示。

(2) 当使用带片上存储器的MCU(如W77E58,具有1K片上存储器)时,必须设置标志位,并且编译模式应选择大模式,否则将发生错误。

(3) 当使用Keil C跟踪程序的运行状态时,应屏蔽引起警告的语句,否则在跟踪语句时可能会出现错误。

(4) 调用数组时,keilc首先将数组加载放入内存。 如果要在C中使用长数组,可以使用code关键字,从而实现组合数据库的功能。KeilC不会将数组加载标记代码调用到内存中,而是直接读取ROM。

(5) 当编程涉及到交流时,计时非常重要。 拉动销的执行速度比检查销级别快得多。

(6) 等待引脚级别更改时,需要设置超时处理,否则程序会因意外错误而死锁。

(7) 凡能用C语言实现的,尽量不要使用汇编语言,尤其是在算法实现中,汇编语言晦涩难懂。

(8) 程序的几个参数数组占用了大量空间,因此将这些初始化数组放在另一个C文件中,并在主文件中使用关键字extem定义它们,以免干扰主文件的写入。

(9) 所有功能之间的相关性越低,越有利于将来功能的扩展。

4.4 系统运行结果展示

如图4-1、4-2、4-3所示,当温度控制系统内DS18B20温度传感器检测温度为60℃时,LED显示为60℃,蜂鸣器报警模块响起。如果DS18B20温度传感器检测温度为29℃时,警报模块接口处显示为蓝色,蜂鸣器不工作。当DS18B20温度传感器检测温度为37℃时,警报模块接口处显示为红蓝闪烁,蜂鸣器工作。

图4-1 60℃温度控制系统

图4-1 29℃温度控制系统

图4-1 37℃温度控制系统

4.5 本章总结

本章讨论了提高系统可靠性的措施以及使用keil c调试系统时的一些经验。介绍了系统硬件的低功耗措施和软硬件的抗干扰措施,总结了系统的Keil C系统调试经验,最后针对本系统的仿真结果加以阐述。本章展示了温度控制系统的仿真效果,验证本系统各项指标均满足温度控制系统的要求,效果良好且性能可靠稳定。

第5章总结

本章首先从水温控制器的研究开始,以水温为例,重点研究了一个基于DS18B20温度传感器的水温模拟系统。系统由单片机控制器为核心控制,使用温度传感器DS18B20 检测环境温度变化,并实时控制水温值。温度控制系统的主要功能包括:(1)选择合适的继电器,以便对流水温度进行控制。(2)实现在流水的过程中,控制温度(水流温度在35—38度之间)。(3)当系统按照要求,开始预热及结束后,系统会相应给出信号。(4)编写相关程序,有详细的程序说明。(5)对环境温度的实时检测和控制功能(6)系统还具有环境温度数据显示和跨线报警等功能。

本系统软件与硬件的实现方法如下:首先,针对温度的测量以及控制技术的国内外研究现状进行调研,设计本系统的技术手段。其次,以温度控制系统的硬件部分展开阐述,根据本系统的具体需求对温度控制系统的硬件部分进行了设计。通过对传感器、单片机等模块的选择,介绍了不同传感器芯片以及单片机的特点、引脚和工作原理。然后,以温度控制系统的软件部分展开阐述,利用keil C汇编语言,按照系统的功能需求完成温度控制系统的软件部分调试。最后,对芯片的选择、硬件设备和软件设备抗干扰等措施分析以及 Keil C 调试系统的经验等方面进行总结,完善温度控制系统。

本系统经过实验验证,各项指标均满足温度控制系统的要求,效果良好且性能可靠稳定。

参考文献

[1] 孙福生,张丽君,等.环境监测实验.化学工业出版社.2007.

[2]高梅娟.双模预测模糊控制在温控系统中的应用[J].基础自动化.2001,8(2):26-28.

[3] 纪友芳,李大海,林美娜.智能温度控制仪的设计与实现[J].计算机工程与设计2007.28(17):4200-4202..

[4] 齐志才,赵继印.MCS-51系列单片机原理及接口技术.北京:中国建筑工业出版社,2005.

[5] 沙占友. 集成温度传感器原理与应用.北京:机械工业出版社,2002,84-95.

[6] 张宇.高精度恒温箱温度控制理论研究与系统设计[D].合肥工业大学硕士学位论文,2005.

[7] Fuji Jian,Digvir S,Jayas,Noel D.G.White.Temperature fluctuations and moisture migration in wheat stored for 1 5 months in a metal silo in Canada[J].Journal of Stored Products Research, 2009,45(2):82.90.

[8] Thysen I.Agriculture in the Information Society[J].Journal ofagriculture engineering research, 2000,76(3):297.303.

[9] Jian, F.Jayas,Ds.White,etc.A three—dimensional, asymmetric, and transient model to predict grain temperatures in grain storage bins[J].Transactions ofthe ASAE,2005,48(i): 263.271.

[10] Li Zhu Wu,Yu Zhao.Cold Chain Logistics Temperature Monitoring System Based on Internet of Things Technology[J].Applied Mechanics and Materials,201 3(4 1 6):1 969-1973.

[11] LI Xiang-Li,SF Wang,YC Wang.Numerical simulation oftemperature and moisture in grain heap in large warehouse[J].Science&Technology ofCereals Oils&Foods,2012(14):120- 125.

[12] Ru Bo Lan.Research on Real Time Acquisition and Control Technology of Mine Excavation Surface Temperature Based on the Technology ofthe Internet ofThings[J].Applied Mechanics and Materials。20 14(686):272—276.

[13] Lei Wang.Design of Remote Monitoring System of Temperature and Humidity Based on Internet ofThings Technology[J].Advanced Materials Research,2014(989):3415-3418.

[14] Lan Xin HuI Hai Bo Feng,Hai Meng Yin。Remote Wireless Monitoring System for Wind Turbine]J].Applied Mechanics and Materials,2013(385):614-617.

[15] 芦燕.温室实时监测系统上位机软件设计与实现[D].银川:宁夏大学,2014.

[16] 薛小玲,炅寿强.数字式温度检测系统的设计.闽江学院学报.2003,(12):53

[17] 朱麟章.高温测量原理与应用.科学出版社,1991:387~152

[18] A.Rosso,E mghiul.A New Transfer Standard Pyrometer.Measurement.1985,3, (131):131-136 4

[19] P.B.Coates.The Least-Squares Approach to Multi—Wavelength Phrometer.High Temp and Hi曲Press.1988,(20):433,-441

[20] P.B.Coates.Wavelength Specification in Multi.Wavelength Pyrometer.High Temp and High Press.1988,(20):443,448

[21] 陈蜻.自控温加热器的研制.电子机械工程.2000,(3):48~5 1 7

[22] 黄永光.用于直流电位差计稳压电源的自动恒温槽.计量技术.1990,(8):17~1

[23] J.Aracil.G Heredia and A.Ouem.Global Stability Analysis of Fuzzy Path Tracking Using Frequency Response.Engineering Applications of Articial Intelligence.2000,13(2):109--119 13

[24] Y Cho,K.Lee,J.Yoo,M.Park.Autogeneration of Fuzzy Ruks and Membership Functions for Fuzzy Modeling Using Rough Set Theory.IEEE Proceedings Control Theory and Applicafings.1997,145(5):437--448

[25] D.S.Reay,M.W.Dunnigan.Learning Issues in Model Reference Based Fuzzed Contr01.IEEE Proceedings Control Theory and Applicatings.1997,144(6): 605---61l

[26] M.Ghassan,Abdelnour.Design of a Fuzzy Controller Using Input Mapping .Factors.IEEE Trans.On Systems,Man,and Cybemetics.1990,5(20):25-30

[27] S.G Cao,N.W.Rees,and G Feng.Analysis and Design for a Class ofComplex Control Systems Part II:Fuzzy Controller.Automatica.1997.33(6):1029~1039

[28] 张毅刚,彭喜元,姜守达,乔立岩.新编MCS.51单片机应用设计.哈尔滨 工业大学出版社.2003:23 101

[29] David M.Auslander.Mechatronics:A Design and Implementation Methodology for Real Tune Control Software.1997.22—24

[30] 杜维,张宏建等.过程检测技术及仪表.北京化学工业出版社,1999:8~9

[31] 王建春 , 李凤菊 , 于伟军 , 等 . 设施农业中温湿度监测系统 的设计与应用 [J]. 天津农业科学 ,2014,20(12):50-53.

附录

代码

#include <reg52.h>          //调用单片机头文件

#define uchar unsigned char  //无符号字符型 宏定义       变量范围0~255

#define uint  unsigned int      //无符号整型 宏定义 变量范围0~65535

uchar code smg_du[]={0x14,0x47,0x41,0x46,0x47,0x88,0x84,0x27,0x14,0x05,

//                                              A         B       C      D     E   F          不显示

                                                0x06,0xa4,0x9c,0x65,0x8c,0x8e,0xff};      //断码   

//数码管位选定义

uchar dis_smg[8] = {0};   

uchar smg_i = 3;    //显示数码管的个位数

sbit dq   = P1^6;    //18b20 IO口的定义

sbit beep = P3^3;   //蜂鸣器IO口定义

bit flag_lj_en;            //按键连加使能

bit flag_lj_3_en;       //按键连3次连加后使能  加的数就越大了

uchar key_time,key_value;      //用做连加的中间变量

bit key_500ms  ;

uchar flag_en = 1;

int temperature ;  //

bit flag_300ms ;

uchar menu_1;       //菜单设计的变量

int t_high = 350,t_low = 100;     //温度上下限报警值

sbit relay1 = P1^5;  //温度报警继电器IO口定义

sbit relay2 = P1^3;  //湿度报警继电器IO口定义

//数码管位选定义

sbit smg_we1 = P2^0;         //数码管位选定义

sbit smg_we2 = P2^2;

sbit smg_we3 = P2^4;

sbit smg_we4 = P2^6;

/***********************数码位选函数*****************************/

void smg_we_switch(uchar i)

{

         switch(i)

         {

                   case 0: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;

                   case 1: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;

                   case 2: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;

                   case 3: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;

         }       

}

/***********************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()

{

         static uchar i;  

         i++;

         if(i >= smg_i)

                   i = 0;         

         P0 = 0xff;                    //消隐

         smg_we_switch(i);           //位选

         P0 = dis_smg[i];                 //段选           

}

/***********************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

         EA = 0;

         init_18b20();                //初始化18b20         

         write_18b20(0xcc);    //跳过64位ROM

         write_18b20(0xbe);             //发出读取暂存器命令

                  

         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定时

}

/********************独立按键程序*****************/

uchar key_can;         //按键值

void key() //独立按键程序

{

         static uchar key_new;

         key_can = 20;                   //按键值还原

         P3 |= 0xf0;

         if((P3 & 0xf0) != 0xf0)                //按键按下

         {

                   if(key_500ms == 1)  //连加

                   {

                            key_500ms = 0;

                            key_new = 1;

                   }

                   delay_1ms(1);             //按键消抖动

                   if(((P3 & 0xf0) != 0xf0) && (key_new == 1))

                   {                                                       //确认是按键按下

                            key_new = 0;

                            switch(P3 & 0xf0)

                            {

                                     case 0xd0: key_can = 3; break;           //得到k1键值

                                     case 0xb0: key_can = 2; break;           //得到K2键值

                                     case 0x70: key_can = 1; break;           //得到k3键值

                            }

                            flag_lj_en = 1;  //连加使能

                   }                          

         }

         else

         {

                   if(key_new == 0)

                   {

                            key_new = 1;

                            flag_lj_en = 0;           //关闭连加使能

                            flag_lj_3_en = 0;      //关闭3秒后使能

                            key_value = 0;           //清零

                            key_time = 0;

                            key_500ms = 0;

                   }

         }       

}

/****************按键处理数码管显示函数***************/

void key_with()

{

         if(key_can == 1)          //设置键

         {

                   menu_1 ++;

                   if(menu_1 >= 2)

                   {

                            menu_1 = 0;

                            smg_i = 3;                    //数码管显示3位

                   }

         }

         if(menu_1 == 1)                           //设置高温报警

         {

                   smg_i = 4;                    //数码管显示4位

                   if(key_can == 2)

                   {

                            if(flag_lj_3_en == 0)

                                     t_high ++ ;                 //按键按下未松开自动加三次     

                            else

                                     t_high += 10;   //按键按下未松开自动加三次之后每次自动加10

                            if(t_high > 990)

                                     t_high = 990;

                   }

                   if(key_can == 3)

                   {

                            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] & 0xfb;  //取个位显示

                   dis_smg[2] = smg_du[t_high / 100 % 10] ;         //取十位显示

                   dis_smg[3] = 0x26;  //H

         }       

         if(menu_1 == 2)                           //设置低温报警

         {

                   smg_i = 4;                    //数码管显示4位

                   if(key_can == 2)

                   {

                            if(flag_lj_3_en == 0)

                                     t_low ++ ;                            //按键按下未松开自动加三次     

                            else

                                     t_low += 10;              //按键按下未松开自动加三次之后每次自动加10

                            if(t_low >= t_high)

                                     t_low = t_high - 1;

                   }

                   if(key_can == 3)

                   {

                            if(flag_lj_3_en == 0)

                                     t_low -- ;                     //按键按下未松开自动减三次     

                            else

                                     t_low -= 10;               //按键按下未松开自动加三次之后每次自动加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] & 0xfb;   //取个位显示

                   dis_smg[2] = smg_du[t_low / 100 % 10] ;               //取十位显示

                   dis_smg[3] = 0xBC;   //L

         }       

/****************报警函数***************/

void clock_h_l()

{

         static uchar value;

        

         if((temperature <= t_low) || (temperature >= t_high))

         {

                   value ++;  //消除实际距离在设定距离左右变化时的干扰

                   if(value >= 2)

                   {

                            if(flag_en == 1)

                            beep = ~beep;           //蜂鸣器报警

                            if(temperature <= t_low)

                                     relay1 = 0;    //打开继电器                           

                            if(temperature >= t_high)

                                     relay2 = 0;    //打开继电器                           

                   }       

         }

         else

         {

                   beep = 1;

                   relay1 = 1;    //关闭继电器                           

                   relay2 = 1;    //关闭继电器                           

                   flag_en = 1;

         }                          

}

/****************主函数***************/

void main()

{

         time_init();                    //初始化定时器

         while(1)

         {                

                   key();                                              //按键程序

                   if(key_can < 10)

                   {

                            key_with();                          //设置报警温度     

                   }

                   if(flag_300ms == 1)     //300ms 处理一次温度程序

                   {          

                            flag_300ms = 0;      

                            temperature = read_temp();  //先读出温度的值

                            clock_h_l();        //报警函数

                            if(menu_1 == 0)

                            {       

                                     dis_smg[0] = smg_du[temperature % 10];      //取温度的小数显示

                                     dis_smg[1] = smg_du[temperature / 10 % 10] & 0xfb; //取温度的个位显示

                                     dis_smg[2] = smg_du[temperature / 100 % 10] ;      //取温度的十位显示

                            }

                   }

                   display();           //数码管显示函数

         }

}

/*************定时器0中断服务程序***************/

void time0_int() interrupt 1

{       

         static uchar value;                     //定时2ms中断一次

         TH0 = 0xf8;

         TL0 = 0x30;     //2ms

         value++;    

         if(value >= 150)

         {

                   value = 0;  

                   flag_300ms = 1;

         }

         if(flag_lj_en == 1)        //按下按键使能

         {

                   key_time ++;

                   if(key_time >= 250) //500ms

                   {

                            key_time = 0;

                            key_500ms = 1; //500ms

                            key_value ++;

                            if(key_value > 3)

                            {

                                     key_value = 10;

                                     flag_lj_3_en = 1; //3次后1.5秒连加大些

                            }                                                      

                   }

         }

}

  • 1
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beryl2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值