基于单片机的空调温度控制系统设计毕业设计


     毕业设计  题 目 基于单片机的空调温度控制系统设计 学生姓名 学 号 学 院 计算机与信息工程系 专业班级 指导教师 职 称   年 月 内容摘要 空调是一种能够改善室内温度、湿度、洁净度和空气流速等参数的电器装置。它在生产生活中用途非常广泛。空调不仅可以在夏天用来制冷,还可以用于冬天供暖。同时它具有的送风功能也能够改善室内空气流速,提供人们清新空气。空调的出现及其发展满足了人们对舒适环境的追求和生产工艺过程的要求。 本文通过论述当前空调的发展现状和趋势,介绍了一款自制的基于单片机的空调温度控制系统。该系统是以AT89C52单片机为核心,使用DS18B20温度传感器采样温度,并以LCM1602液晶显示器作为人机对话窗口。具有检测、显示当前温度和设置温度的功能。处理器根据预定的比较算法,采用模拟脉冲宽度调制Pulse Width Modulation(简写为PWM)的方法控制光耦开关和继电器的闭合时间,完成对室温的调控。由于客观条件限制,本次设计以发光二极管LED(英语:Light-Emitting Diode,简称LED)的亮灭来模拟空调的置冷、置热、送风功能。其中红灯表示置热,蓝灯表示置冷,绿灯表示送风。该控制系统具有结构简单,操作灵活,使用方便等优点。 关键词 单片机;温度传感器;液晶显示器;矩阵键盘;继电器;Keil;Proteus ABSTRACT Air conditioning is the electrical device which can improve the indoor temperature, humidity, cleanliness and air velocity and other parameters. Its use in production and life is very extensive. Air conditioning can not only be used for cooling in the summer, but also can be used for heating in winter. Wind supplying it has also can improve indoor air velocity, provide people with fresh air. The emergence and development of air conditioning to meet the pursuit of a comfortable environment and production process requirements. This paper discusses the present situation and trend of development of air conditioning, Introduced a self-made air temperature control system based on MCU. The system is based on AT89C52 microcontroller as the core, the use of DS18B20 temperature sensor sampling temperature, And to the LCM1602 LCD monitor as the man-machine dialog window. Can detect and display the current temperature and setting temperature function. According to the comparison algorithm processor reservation. Closing time is simulated by the simulation of pulse width modulation Pulse Width Modulation(referred to as PWM) method to control the optical switch and relay. Complete control of the room temperature.. Because of the limitations of objective conditions. The design uses a light emitting diode LED (English: Light-Emitting Diode, referred to as LED) light out to simulate air conditioning cold、heat、wind.The red light indicates the hot, blue lights that chill air, a green light means air. The control system has the advantages of simple structure, flexible operation, easy to use. KEY WORDS Single chip microcomputer; Temperature sensor;Liquid crystal display; Matrix keyboar; Relay; Keil; Protuess 目 录 1. 绪 论 1 1.1 空调温度控制系统研究背景和意义 1 1.2 空调温度控制系统的现状和不足 2 1.3 本文设计任务及目的 3 1.4 本文主要内容 3 2 方案设计 4 2.1 总体方案设计与选择 4 2.1.1 总体方案设计 4 2.1.2 总体方案论证 5 2.1.3 总体方案选择 6 2.2 模块方案论证与选择 6 2.2.1 显示模块 6 2.2.2 按键输入模块 8 2.2.3 开关控制模块 9 2.2.4 温度采集模块 10 2.3 软件总体框图 10 2.4 本章小结 11 3 系统硬件电路设计 12 3.1 总电路设计 12 3.2 单片机最小系统介绍 12 3.2.1 AT89C52单片机介绍 12 3.2.2 单片机的复位电路设计 15 3.2.3 单片机的时钟电路设计 16 3.3 输入电源电路设 17 3.4 矩阵键盘电路设计 17 3.5 温度测量电路设计 19 3.5.1 温度传感器DS18B20概述 20 3.5.2 温度采样电路 21 3.6 驱动控制电路设计 22 3.7 显示电路设计 23 3.8 模拟执行电路设计 24 3.9 蜂铃器电路模块 25 3.10 PWM控制技术 25 3.10.1 PWM简介 25 3.10.2 AT89C52单片机生成PWM方法 26 4 系统软件设计 27 4.1 主程序设计 27 4.2 初始化程序设计 28 4.3 DS18B20温度采样程序设计 28 4.4 LCD显示程序设计 30 4.5 按键程序设计 32 4.6 本章小结 33 5系统调试与仿真 34 5.1 系统调试 34 5.1.1 编程与画原理图 34 5.1.2 进行调试与仿真 36 5.2 硬件调试 38 5.3 实物图 40 5.4 本章小结 40 结束语 41 参考文献 42 致 谢 44 附录1 系统总电路图1 45 附录2 系统总电路图2 46 附录3 元件清单列表 47 附录4 程序源代码 48 Main.c文件 48 Global.c文件 52 DS18B20.c文件 53 DS18B20.h文件 58 LCD.c文件 58 LCD.h文件 61 KEY.c文件 62 KEY.h文件 76 基于单片机的空调温度控制系统设计 1. 绪 论 随着科学技术和市场经济的快速发展以及人们生活质量的提高。空调等家电广泛的应用在人们的工作生活中。现代科技的飞速发展和普及也促进了空调技术的不断前进。空调的功能就是通过采取特定的方法调节和控制人们生活、工作和科研所需的空气环境。通过对室内空气的温度、洁净度、湿度以及空气交换速度的调控,使室内空气能够达到人们日益提高的温度需求范围,以满足生产过程对温度的严格需求和人体舒适生活的要求。 1.1 空调温度控制系统研究背景和意义 在空调出现之前。人们主要是通过手工操作加热、通风和降温设备来控制温度的变化,比如烧煤木、发电和日光等提高环境温度,使用大型风轮送风,或者利用水蒸发散热等。这些人力操作方法不但控制效果比较差,温度的精确度比较低,也提高了操作人员的劳动强度,这会影响某些工业生产的可靠性。随着科技的不断进步以及工业生产的严格环境要求,在生产生活中温度已成为一种重要的调控参数,温度的检测和控制广泛应用于工业、农业及日常生活的诸多领域。生产生活的强烈需求让制热或者制冷电器系统的产生成为科研的方向。空调也就出现了。空调从诞生发展到现在,已经从简单的空调扇到传统的功能单一的空调,再到今天高智能化的、低功耗的变频空调时代,已经过去了一个世纪。空调也从最初的为机器降温逐渐发展到为人类提供舒适的生活工作环境。 科学技术的日新月异为高精度、高稳定速度的温度需求的实现提供了可靠的技术支持。单片机的功能不断增强,为先进的控制方法提供了更好的处理器。单片机作为空调温度控制系统的核心,它的作用是不可替代的。采用单片机等微控制器作为空调智能控制的核心已成为当今智能控制系统的主流。 空调是采用嵌入式技术的温控装置,广泛应用于家庭、商城、影院、办公及生产车间等公共场所,已经成为人们生产生活中不可或缺的必需品。本文设计了一款模拟空调工作的控制系统。使用单片机作为空调的微处理器,通过温度传感器采样温度,MCU进行数据分析并处理。实现对模拟部件的控制。通过此次设计了解空调温度控制的原理和微处理器在现代工业生产中的应用。 1.2 空调温度控制系统的现状和不足 国外对空调温度控制技术的研究比较早,1970年初日本开始运用变频空调技术,变频空调可以根据室温情况自动进行无极变速,为室内环境提供所需冷热量,从而保证室温的稳定。变频空调具有低功耗,低噪音,温度控制精度高等优点。我国在学习了发达国家温度控制技术理论知识后,在此基础上通过创新和吸收才掌握以单片机为控制器的室内温度控制技术,而此时国外已经在完全自动化,智能化方向有了长足发展。与发达国家比我们在技术上还有一定差距。 市场上有电气式空调控制器和电子式空调控制器。电气式空调的温度控制系统采用双金属片作为温度传感器,可以通过调节预先设置的功能按钮控制预紧力来设定温度。这类空调温度控制器一般都存在几个问题,比如温度设定时的精确度不高、时间常数比较大、容易损坏机械开关等。 电子式空调温度控制系统采用热敏电阻或热电阻作为温度传感器,通过触摸键设置温度和控制风速开关,采用液晶显示屏能实现人机友好的交互界面,自动完成冷热的切换。电子式空调温度控制系统解决了电气式空调温控器中出现的一些问题,但仍存在调节精度不高、用户操作复杂等问题。应用新型控制模型和数控芯片的智能型室温空调温控器正在研究开发中,部分已经应用于实际工程。 21世纪,物联网技术的兴起和发展使用户可以通过传感设备,再根据物联协议要求,可以直接对空调进行通信和控制。智能化的识别技术和管理技术和监控技术已开始面向市场。2010年4月,家电巨头海尔集团研发的无氟变频物联网空调面世。它能根据外界温度和室内环境温度的差异将室内温度调节到最合适状态。物联网空调还可以将空调的功耗和室内温度的变化等信息报告给用户。物联网技术支持下空调将实现真正互联化和高度智能化。但是空调的控制原理没有变化,只是其微型控制器更先进,并能实现网络通信。单片机方面,8位机仍将是主流,但18位和32位单片机也将发挥越来越大的作用,专用型空调单片机的应用也会更广泛。满足各类不同需求的单片机种类会越来越多。 本设计结合当前迅速发展的单片机技术,设计了一个单片机温度控单元,对空调的温度控制原理进行一定的研究。 1.3 本文设计任务及目的 设计一个以AT89C52单片机为核心的空调温度控制系统。主要功能为: 1. 具有检测温度功能; 2. 具有显示温度的功能 3. 通过设定的温度,由固态继电器采用模拟PWM控制方法,改变电子开关的闭合时间;完成对空调温度的控制; 4. 具有加热(红灯)、制冷(蓝灯)、送风(绿灯)功能; 5. 具有采集环境温度功能; 6. 具有警报功能。 1.4 本文主要内容 根据设计题目的需求分析,对论文结构做了如下安排: 第一章介绍了空调温度控制系统的背景和意义,针对现状与不足提出本设计的任务和目的。 第二章介绍了空调温度控制系统的几种常见的设计方案。也分别介绍了各种不同方案实现的主要模块。根据不同的设计方法,对系统方案和各功能模块方案分别进行分析论证,分别选择了适合该系统的实际设计方案。 第三章以硬件电路介绍为主,简单据介绍了本系统采用的芯片的性能参数和在系统中的连接与使用方法。给出了完成各部分功能的电路设计图。列出本次设计所需的元器件。 第四章是软件模块设计。根据系统的功能要求。在Keil软件中建立工程并分模块编写程序。主要介绍了各功能模块的程序流程图。本设计用单片机C语言编写程序。程序按模块分为主程序、温度采集程序、显示程序、键盘扫描程序和执行程序等几个独立模块。按照软件开发的模块化编程思想。独立完成各模块的程序编写。最后将各模块整合在工程里面运行,生成的.hex文件就是单片机能够执行的程序命令集合。 第五章主要介绍了系统调试和仿真。在Proteus和Keil软件平台进行编程和画图。然后通过两个软件联合调试仿真。模拟实现空调温控系统所要求的功能。 2 方案设计 空调温度控制系统要具有足够的稳定性、实时调节性以及高精确控制的特点。所以 设计思想和设计方案是前提,也是关键环节。要遵循控制系统经济、可靠性、高效性等原则来设计空调温度控制系统。 2.1 总体方案设计与选择 2.1.1 总体方案设计 方案一:模糊控制 模糊控制就是根据人工控制的经验,把收集到的外部信息形成一个概念,如人们对温度的感受:过高、合适、过低,然后根据判断决定控制方法。根据偏差及偏差的变化率计算出要输出的模糊控制量,再进行模糊运算,得出模糊输出信号,实现对执行器的控制,达到调节受控变量的目的。该方案的结构框图如图2.1所示。 单 片 机 制热 室内温差 d/dt 室内热交换 器管壁温度 d/dt 制冷 室外热交换 器管壁温度 d/dt 送风 图2.1模糊控制方框图 方案二:单片机加A/D转换 该方案采用AT89C51单片机作为空调控制系统的核心控制器件。首先通过温度传感器AD590对室温进行采样,将采样的温度信号通过模数转换电路把模拟信号转换成数字信号,然后输入单片机进行处理。单片机输出信号控制LED显示当前温度。由键盘输入设定温度并显示。单片机处理器根据程序算法比较当前温度和设置温度的大小,输出相应控制信号驱动执行单元工作。该方案主要特点是把模拟信号转换成数字信号。再由单片机处理。该方案的结构框图如图2.2所示。 执行器 执行器 继电器 继电器 LED显示 键盘 AD590 A/D转换 AT89C52 单片机 图2.2 单片机控制和A/D结合控制方框图 方案三:用AT89C52作为系统的控制核心。 该方案以AT89C52单片机为空调温控系统的核心。通过高精度的DS18B20温度传感器采样室内温度并将温度信号直接传递给控制器。同时也可以通过矩阵键盘设置温度并传递给控制器。单片机根据软件设定的定时中断功能从指定引脚读入信号,经过信号处理,定时/计数函数输出PWM控制信号到驱动电路,驱动电路采用继电器控制执行器的通断电,这样的开关设置具有隔离和和放大的功能。单片机通过软件控制各模块协调工作。完成对温度的自动化控制。该方案的结构框图如图2.3所示。 LED显示 AT89C52 单片机 DS18B20 温度传感器 蜂铃器 驱动部分 制热 按键输入 部分 驱动部分 制冷 送风 驱动部分 图2.3 AT89C52和DS18B20传感器为核心的结构框图 2.1.2 总体方案论证 方案一:该方案采用模糊控制技术输入,空调的温度控制系统做模糊技术处理后就可实现对温度变量的控制。通过获取室内外温差及其变化率,数据经过单片机处理后输出对加热、制冷、送风等功能实现智能化控制。 优点:设计时不需要建立温度的相对准确数学模型,只需要熟悉掌握人类的控制经验。适用于非线性的、滞后性系统的控制。 缺点:设计时缺乏系统控制的方法。主要靠经验和实验操作系统运行。模糊控制规则的总结很困难。 方案二:该方案通过AD590进行温度采样,然后通过ADC0809进行A/D转换,将转换后的信号传输给AT89C51,由AT89C51控制液晶显示器显示温度,通过比较当前温度与设置温度大小,单片机根据比较结果驱动空调机工作,从而模拟实现空调各种功能要求。 优点:该方案系统原理简单,信号采样比较精确。电路可靠。比较容易实现对空调的控制。 缺点:该方案的温度采样电路中。用到A/D转换,使得芯片的译码过程复杂些,容易产生误差。 方案三:该方案采用DS18B20作为温度采样器件,由于DS18B20能独立完成温度采样并输出单片机能处理的数字信号。且DS18B20无需外部元件,采样精度高,在温度采集系统中的应用广泛。该方案控制原理和方案二是一样的,但其电路更简单,采样数据更可靠,且电路无需外接其它器件,节省了一定的成本。 优点:该方案控制原理简单可靠。各模块单元直接连接单片机,处理速度快,使用的元器件比较常见,更具有易用性和可维护性。 2.1.3 总体方案选择 比较上述三种设计方案,方案一的模糊控制理论比较复杂,采样数据有一定的误差。模糊控制属于事后控制,有一定的延时性,而且模糊控制的额外计算量大,不利于控制系统的实时快速反应。方案二和方案三控制原理相同,但方案二采用A/D转换技术,采样数据经过译码器译码后会出现误差,采样电路也相对复杂。综上所述,本次设计选择方案三来实现对空调温度的自动化控制。 2.2 模块方案论证与选择 2.2.1 显示模块 对于人机交互式控制系统来说,不仅需要响应输入信息,同时也要将一些测量控制信息输出并显示在屏幕上,以便提供实时的数据供用户观察和处理。 方案一:采用LED数码管作为显示界面。LED是由多个发光二级管组成的显示器件,通过控制指定字段的导通与断开使数码管显示相应的字符。单片机系统中LED数码管是最常用的显示器件。其成本低廉,使用简单。本设计需显示99.9 ℃~ -99.9℃的当前温度和设置温度,所以需要8个LED数码管并列使用。4位数码管如图2.4所示。 A B C D E F G DP 1 2 3 4 图2.4 数码管 方案二: 用LCM1602液晶显示器做显示界面,LCD液晶显示依靠液晶显示器来显示数据和图形的。LCD液晶显示效果良好,可以显示数字,也能显示一些简单的图形和汉字等,在电路设计中应用广泛。该显示屏幕能显示一行或者二行。液晶显示器如图2.5所示。 图2.5 液晶显示器 本次设计需要显示当前温度和设置温度,需要8个数码管才能显示温度。数码管过多不仅占用电路板空间,也占用单片机的I/O接口,而且没有提示功能。使用LCD显示不仅可以设置提示栏,如“Now,Set”等标注栏,能双行显示当前温度和设置温度。使用LCM1602液晶显示器让交流界面美观友好,而且LCD占用占用电路板的空间也比数码管小得多。显示质量比数码管高,它的数字式接口电路也易于操作。所以显示模块选用LCD液晶显示器。 2.2.2 按键输入模块 键盘是人机交互温度控制系统中用来输入功能信号或设置温度数据的接口。使用键盘输入操作命令或温度数据控制单片机运行。单片机设置电路中常用的键盘组成有矩阵式键盘和独立式的键盘。 方案一:独立式的简单按键键盘。这种键盘和单片机的接口简单,适合用于使用少量开关而且简单控制系统的输入。每个按键占用一个I/O引脚,各按键相互独立,互不影响,不适合按键交多的系统。独立式键盘如图2.6所示。 图2.6 独立式键盘 方案二:矩阵式的4x4按键键盘。该键盘的按键跨接在单片机一个P接口的行线和列线上。当有键按下时相关行线和列线接通而发生短路。并利用软件计算出该按键的键值。这种键盘占用引脚接口较少,实现功能的软件结构比较简单。适用于按键较多的设计电路中。矩阵式键盘如图2.7所示。 图2.7 矩阵式键盘 本设计系统中需要数字按钮10个,用于输入0到9十个数字,其他功能按钮6个,由于确定设置、切换等。总共需要16个按钮。按件比较多,若用独立式键盘接法将占用单片机宝贵的接口,第二种方案只需要单片机的8个I/O口就能满足设置需求,所以本设计采用4x4的矩阵式键盘。 2.2.3 开关控制模块 控制系统运行后,温度传感器采样温度并处理,处理器输出信号控制执行器的运行。在单片机模拟小型控制系统中,既可以直接驱动压缩机工作。也可以设置开关控制压缩机运行。两者都能自动控制单片机的工作时间。 方案一:空调压缩机直接和单片机引脚连接。这种方法只能由软件控制执行器的工作状态。在简单系统中虽然也能完成自动控制,但单片机输出电流小。只能驱动小功率器件工作。也没有隔离放大效果。很容易损害执行器件。这种设计的电路连接如图2.8所示。 图2.8 无开关键驱动电路图 方案二:单片机通过控制固态继电器的闭合来控制执行器工作。固态继电器是一种带光电隔离器的无触点开关。既能把干扰信号隔离开,通过继电器也能实现低电压控制高电压器件工作。本设计用继电器实现在5V电压下工作的系统控制220V的空调自动化工作。继电器在电路中的电路设计图可以如下2.9所示。 图2.9 由继电器控制的驱动电路图 继电器的高可靠、抗干扰、转换快等优点,使其广泛应用于开关量的控制中,在空调控制系统中,使用继电器作为执行器的通断电控制器。所以本系统选择方案二。 2.2.4 温度采集模块 温度是最重要的物理参数之一,是最常见、最基本的物理量之一。在很多地方都需要测控温度,而温度采集需要温度传感器,因此,熟悉正确的测温方法及使用高效的采样器件非常重要。 方案一: 采用热敏电阻传感器,热敏电阻是利用半导体材料制成的元件,热敏电阻传感器显著的特点是对温度非常敏感,在温度越高时阻值越低。其优点是灵敏度高、体积小。缺点是互换性差,温度和阻值是非线性严重的关系,元件容易老化。如图2.10所示: 图2.10 热敏电阻 方案二: 采用DS18B20温度传感器,DS18B20是1-Wire总线接口温度传感器。他具有数据保存、结构简单、使用方便。比较高的精度测量范围,不需要外接其他的器件。可以直接与单片机通信。 基于DS18B20温度传感器的优点,本设计选择方案二, 2.3 软件总体框图 本设计采用C语言编写程序。由主程序模块、温度采样模块、键盘扫描模块、液晶驱动程序模块和执行程序模块组成。软件部分总体结构框图如下2.11图: 主 函 数 键 盘 扫 描 模 块 执 行 模 块 液 晶 驱 动 模 块 温 度 采 样 摸 块 图2.11 总体结构框图 2.4 本章小结 本章进行了总体设计方案的论证。也对显示模块、按键模块、温度模块以及开关模块的方案进行了论证,根据系统设计的简单、可靠、经济、高效等原则选择了较为实用的方案。该方案利用AT89C52作为控制系统的处理器。单片机定时从I/O口读取DS18B20输入的信号,经过分析处理,由单片机把控制信号和数据传输到液晶显示器和执行器。既实现了温度的显示。也启动执行电路工作。按键设置温度,单片机根据温度比较结果控制空调机执行制冷、制热、送风的工作。 3 系统硬件电路设计 在模拟空调温度控制系统中,AT89C52单片机作为核心处理器,DS18B20温度传感器负责室内温度采集,LCM1602液晶显示器显示温度参数,由继电器和光耦开关控制LED灯的亮灭来模拟制冷制热等功能,键盘设置用户需求温度。编程实现各模块的功能。系统原理图见附录1。 3.1 总电路设计 空调温控系统大体可分为6个模块,输入5V直流电压模块、DS18B20与单片机的温度模块、LCM1602与单片机的显示模块、驱动执行模块、设置模块和蜂铃器模块。单片机的工作电压是5V,系统上电后单片机通过DS18B20温度传感器获得当前温度,单片机接收DS18B20传回的数据,利用并行通信原理把数据发送给LCM1602显示器显示。单片机从键盘获得的设置温度以同样的原理显示在LCM1602上面。单片机比较两个温度值并输出控制信号,驱动执行电路工作。总电路图见附录1。 3.2 单片机最小系统介绍 3.2.1 AT89C52单片机介绍 AT89C52是ATMEL公司生产的一个8位单片机。性能比C51单片机高,该型号单片机采用CMOS技术生产。兼容标准的MSC-51指令系统。程序可以通过JTAG接口下载到单片机中。不需要很多外部资源去开发该芯片,能够实现实时仿真。用户能使用单片机的所有资源。 其主要功能特性如下: ● 32个输入/输出引脚; ● 2个电源引脚; ● 6个控制引脚; ● 2个XTAL引脚; ● 21个特殊功能寄存器; ● 8KB的可擦写Flash程序储存器,可擦一千次左右; ● 128B数据储存器和128B特殊功能寄存器; ● 时钟频率为0~24MHz; ● 工作电压为2.7V~6.5V; ● 兼容标准MCS-51指令系统集; ● 有多种封装形式; ● 断电数据保护; ● 有定时器、外部中断.串行中断等; ● 程序存储器能够多级加密保护,能保存几年以上。 AT89C52引脚图如图3.1所示。 图3.1 AT89C52芯片封装引脚图 1.电源及外接晶体引脚 (1) VCC:接+5V电源。 (2) GND:接地。 (3) XTAL1、XTAL2:晶体振荡电路反向输入输出端。 2.输入/输出引脚 (1) P0端口是一个双向8位三态I/O接口,每个I/O口可独立控制。也可分时复用,可作为双向数据总线用,也可以做为低8为地址总线。本控制系统中P0端口作为连接显示器的数据总线。 (2) P1端口是一个8位准双向I/O端口,该端口没有高阻态,不能锁存,一般用作数据的输入或者输出。本控制系统中P1端口连接温度传感器和LCD显示器的使能端。 (3) P2端口使用时一般作为准双向高8位地址总线接口使用。本控制系统中P2端口连接矩阵键盘。 (4) P3端口既能准双向8位I/O接口使用,也具有做是具有分时复用功能。P3端口的第二功能见表3.1。本控制系统中P2端口的P3^5、P3^6、P3^7做普通的I/O接口连接执行器。P3^2脚用作为外部中断功能。 表3.1 P3端口线的第二功能表 引脚 P3端口的第二功能 P3.0 RXD 串行输入口 P3.1 TXD 串行输出口 P3.2 INT0 外部中断0输入端 P3.3 INT1 外部中断1输入端 P3.4 T0 定时器/计数器0外部输入端 P3.5 T1 定时器/计数器1外部输入端 P3.6 WR 外部RAM写脉冲输出端 P3.7 RD 外部RAM读脉冲输出端 3.控制引脚 (1) ALE:地址锁存信号输出端。本控制系统没有使用该引脚。 (2) :单片机外部程序储存器选用端。当ALE为1时,先访问内部ROM,再访问外部ROM。当ALE为0时只访问外部ROM。本设计没有使用该引脚。 (3) :读选通单片机外部程序储存器的信号输出控制端,低电平有效。本设计没有使用该引脚。 (4) RST:上电复位端,也可用作掉电保护作用,当该引脚有持续10ms的高电平时即可复位。 3.2.2 单片机的复位电路设计 单片机复位后。处理器从这个初始状态进行工作。单片机有按键复位和上电复位两种方式,时钟电路工作以后施加持续10ms以上的高电平就可以实现上电和按键复位。这个过程在两个机器周期以上。利用电解电容的充电就能够实现上电复位。复位电路如下图3.2所示。 (a)上电自动复位电路 (b)上电及按键复位电路 图3.2 复位电路图 复位后程序从0000H地址单元开始运行,PC=0000H,单片机复位后不会改变片内RAM的存储内容。本设计电路采用上电复位。复位后各特殊功能寄存器的初始化状态见表3.2。 表3.2 复位后各特殊功能寄存器的初始化状态 特殊功能寄存器 内容初始状态 特殊功能寄存器 内容初始状态 B 00H SCON 00H A 00H PCON 00H PSW 00H TMOD 00H IP XXX00000B TCON 00H P0,P1,P2,P3 FFH TL0 00H IE 0XX00000B TL1 00H SBUF 不定 TH0 00H DPL 00H TH1 00H DPH 00H SP 07H P0~P3端口复位后既可以用于输出,也能用于输入。PSW=00H表示CPU的工作寄存器选为0组。SP=07H,表示堆栈指针指向片内RAM的07H单元。IE=00H表示各中断被关闭,IP=00H表示中断源处于低优先级,PCON=00H表示串行通信的波特率不变。 3.2.3 单片机的时钟电路设计 单片机的时钟电路产生一个时钟信号用于控制单片机按时序进行工作。单片机内部的反向放大器通过XTAL1和XTAL2引脚与外部的晶振以及2个电容构成单片机的并联谐振电路。电容取30pF。电容的功能是对频率起微调作用,晶振取12MHz。该振荡电路的振荡频率设置为12MHz。时钟电路有关周期的计算如下表3.3所示。 表3.3 单片机相关周期 振荡电路如图3.3所示。 图3.3 AT89C52的振荡电路 3.3 输入电源电路设 空调机是工作在220V交流电压下的电器设备,单片机、液晶显示器、温度传感器的工作电压都是5V直流电压。所以需要设计一个把220V交流电压转换成5V的直流电压,为控制系统提供工作电压。其原理图如下3.4图所示。 DC5V 稳 压 滤 波 整 流 变 压 AC220V 图3.4 电源转换图 首先220V交流电压通过变压器降为5V交流电压,再经过桥式整流变为脉冲直流5V电压、滤波消除脉冲,输出5V的直流电压,经过集成三端稳压输出稳定的5V直流电压供控制系统各部分工作。电源电路可以设计如下图3.5所示。本设计直接采用5V直流电压供电,实际电路中电源部分不做上述设计 图3.5 电源部分电路图 3.4 矩阵键盘电路设计 键盘就是几个或多个按钮的集合,在没有键按下时都是断开的。当有键按下时它就导通。市场上的键盘一般都是机械按键,这类按键有机械弹性,按键闭合和断开时都会有抖动发生,按键电路产生的电压波形如下图3.6所示。该抖动会对高速运行的CPU产生干扰,所以需要消除抖动对控制系统的影响。通常有硬件消抖法和软件消抖法。 图3.6 键闭合和断开时的电压波动 由上图可知键按下是在t1+t2阶段,其中t1是键按下时的前沿抖动时间,t2是闭合稳定时间,这一阶段读取的键值有效,t3是释放按键时的后延抖动时间。本设计采用软件延时10ms避开了t1抖动时间段,在t2时间段读入按键信息,这样就能够消除抖动的影响。 在按键电路上加特定的电路来消除抖动的方法是硬件消抖法。用简单的R-S触发器或RC积分滤波电路构成去抖动按键电路,如下图3.7(a)所示。键闭合,释放时的电压波形如图3.7(b)所示。也可以用单稳态电路构成去抖动按键电路。软件消抖法一般可以用软件延时来完成,当有按键按下时,调用一段延时(>10ms)程序,避开抖动时间段,然后再读入按键键值。 (a)去抖动电路 (b)键闭合断开时的电压波动 图3.7 R-S触发器消抖电路 本次设计采用中断扫描控制方法,其工作原理是:当有按键按下时产生一个中断信号(四输入端的与门有0时),此时INT0=0,若没有按键则INT0=1。CPU响应中断后。执行中断服务程序,求出键码。本次设计共设置了16个按键。采用4x4矩阵键盘连线。其中有10个数字按键。用来设置温度。5个功能按键。用来控制系统工作。一个预置空闲键,按键电路如图3.8所示。 图3.8 中断方式的矩阵键盘接口电路 其中4x4矩阵键盘的列线与单片机P2口的低四位相连,作输入端。行线与P2口的高四位相连,做输出线。键盘的行线分别引出接在一个四输入端的与门,与门输出端接外部中断INT0。采用中断法进行键盘设计既能及时响应按键输入,又提高了CPU的运行效率,不会产生空扫描。 按键功能说明:本次设计工使用16个按键。10个数字按键(0~9),一个确定键(OK),一个切换键(Shift),一个清零键(Clear),一个加键( Up),一个减键(Down),还有一个预置键,用于扩展功能时用。温度设置有两个按键方法,可以使用数字键设置温度范围在00.0~99.9之间的任一个度数。再按OK键就能设置成功。另一种办法是按Up或者Down键使数字加减。每按一次指定位加减’1’,由Shift键切换待设置的指定位。前一种方法适合对小数点前面的数字进行设置,后一种方法适合对小数点后面的数字进行调整,适合做温度的微调。也可以两种方法结合使用。按键操作简单明了,设置方法多样。 3.5 温度测量电路设计 按照测温方式的不同有接触式测温和非接触式测温两中方法。 接触式温度传感器需要与被测对象进行接触,通过热量传递达到热平衡,从而测得被测对象的温度。这类传感器比较简单、温度值可靠、测温精度高。但需要时间才能达到热平衡,有一个延时过程。同时传感器的材料要求具有耐高温的特性,所以这类传感器不适合对高温物体的测量。 非接触式温度传感器是通过采样热能辐射来测量温度的。传感器不需要和被测对象直接接触,这类传感器能测量变化幅度大的温度,检测速度比较快。这类传感器在一些特殊场合的应用不可替代。但它容易受距离,空气等外界因 素的影响,所以测温误差比较大。本次设计采用的DS18B20属于接触式温度传感器。 3.5.1 温度传感器DS18B20概述 DS18B20是一种1-Wire总线接口温度传感器,由Dallas Semiconductor公司生产。它由ROM序列号、温度传感器和报警触发器三个主要部件组成。只需要一个引脚DQ就可和处理器实现数据的发送或接收。其引脚少、接口简单、无需外接元件,测量温度的精度比较高。多用于基于单片机的温度监控系统中。DS18B20具有的特点如下图3.9所示。 图3.9 DS18B2的特点 DS18B20的核心芯片是一个数字式温度传感器,该芯片的分辨率可以设置为9位、10位、11位、12位。传感器上电后默认设置是12位的,温度变化量是0.0625℃。部分分辨率下的温度变化量如下表3.4所示。 表3.4 DS18B20在不同分辨率下的温度变化量 分辨率 9位 10位 11位 12位 温度变化量 0.5℃ 0.25℃ 0.125℃ 0.0625℃ DS18B20接到温度转换命令后,开始采样温度并把温度结果在内部进行A/D转换,转换后的数据暂存在温度寄存器中。DS18B20采用TQ-92封装,体积小,占用空间小。DS18B20引脚排列如下图3.10所示。 其引脚功能如下: VDD:外部电源引脚。 DQ :1-Wire总线数据输入/输出引脚。 GND:接地引脚。 图3.10 DS18B20引脚排列及封装 3.5.2 温度采样电路 本设计的温度采样电路如下图3.11所示。 图3.11 温度采样电路图 采用外部供电方式,VCC脚接5V电源,DQ数据线与单片机的P1^7脚相连。系统工作后,DS18B20采样温度并把结果进行A/D转换,经过A/D转换后,把温度数据送入两个温度寄存器单元,单片机通过1-Wire总线接收温度数据。 3.6 驱动控制电路设计 自动控制系统设计中常用到继电器作为开关,继电器一般由铁芯、簧片和线圈等组成,当继电器两端加上电压通电时。由于电磁效应而产生磁场力吸引衔铁,衔铁克服簧片的拉力而和铁芯闭合。当线圈电流断开时,磁场力消失,在簧片拉力作用下衔铁和铁芯断开。继电器线圈工作电压一般是直流9V、12V、24V等,输出部分可以直接接220V交流电。是一个典型的小电流控制大电流运作的开关。在电路中有隔离机械碰撞、保护敏感器件、转换电压和自动开关调节等作用。 以上继电器一般都采用电磁吸合的方式,在开关闭合的瞬间会产生火花。从而对单片机引起干扰。所以在实际应用中固态继电器逐渐替代电磁式继电器了。固态继电器用可控硅或晶体管替代了普通继电器的开关,它的输入部分实际上是一个光电隔离器。继电器具有体积小、开关速度快、输入控制电流小等优点。 空调是大功率电机,它产生的电磁干扰信号会影响其他器件的正常工作,为了避免单片机误动或者损坏,在空调的单片机和执行器的接口电路中需要用到继电器来隔离保护系统正常工作。 本次设计采用了簧片继电器作为驱动控制电路的开关,用三极管放大控制电流。电路图如下图3.12所示。 图3.12 驱动控制电路图 3.7 显示电路设计 本系统显示模块采用LCM1602液晶显示器,LCM1602是一种专门用来显示数字、字母和一些常用 符号的点阵型显示器,可以显示16*2字符数字。 LCM1602显示器采用作为HD44780控制器,它的指令集比较简单,而切指令集的功能齐全。字符能够设置为移动或者闪烁状态。LCM1602和单片机采用8位连接或者四位并行连接方式。LCM1602有16个引脚,实物图如下图3.13所示。 图3.13 LM018L实物图 其引脚功能如下表3.5所示。 表3.5 LCM1602接口部分引脚功能 引脚号 符号 状态 功能 1 VSS 接地 2 VDD 接+5V电源 3 VEE 驱动电源 4 RE 输入 寄存器功能选择(1:数据,0:指令) 5 RW 输入 选择读写操作(1:读,0:写) 6 E 输入 使能信号 7~17 DX 三态 数据总线 本系统中LCM1602的各引脚与单片机的连接是:RS连接P1.2,RW连接P1.1,E连接P1.0,VDD接+5V电源,VSS和VEE接地。8位数据线通过10K排阻与单片机的P0端口并行连接。其中使用排阻即可以分压,也节省了电路空间,保证焊接质量。电路图如下图3.14所示。 图3.14 LCM1602液晶模块连接电路图 3.8 模拟执行电路设计 空调上电工作后。通过控制制冷剂的汽化和液化来吸收室内热量。压缩机首先将制冷剂压缩为汽态剂,然后送入冷凝器中散热,汽态制冷剂液化成液态剂,液态剂进入蒸发器,再次变为汽态,这个过程吸收室内大量的热能,空调内置风扇把室内空气从蒸发器中吹出,所以空调吹出的是冷风。空调机制热原理和制冷原理恰好相反。把制冷过程倒过来就是制热。空调的送风过程就是把室内和室外的空气互相交换并形成一定的气流。本设计方案通过不同颜色的LED灯的亮灭来模拟实现系统工作过程, 该部分是根据单片机发出的指令执行相应操作,空调控制系统具有对室内空气制冷、送风、加热等功能。当前温度低于设置温度时,能够驱动加热器件工作。设置温度低于当前温度时,驱动制冷系统工作,两者温度相等时,驱动送风系统工作。执行电路用红色LED灯模拟加热过程,蓝色LED灯模拟制冷过程,绿色LED灯模拟送风过程。通过点亮三个不同颜色的灯模拟实现空调对温度的控制过程。执行电路如下图3.15所示。 图3.15 执行电路 3.9 蜂铃器电路模块 本设计加用一个蜂铃器用于警报功能。蜂铃器在系统中的作用就是发出警报声音提示用户,由程序设定一个空调正常工作范围(50℃~5℃),当室内温度上升至50℃以上时,而制冷系统暂时无法降低温度,蜂铃器会一直铃响,直至温度降低至50℃以下或者关闭蜂铃器电源。造成温度突然升高的原因有可能是室内起火或者制冷系统出现故障等原因,铃响蜂铃器可以提醒用户注意。当温度降低至5℃以下时,蜂铃器同样能发出提醒声音。 用户由于操作失误设置温度过高或者过低时,蜂铃器也会发出蜂铃声提醒用户从新设置,本设计的正常设置温度范围是:40℃~10℃。当设置温度超过40℃或者低于10℃时,蜂铃器将发出提示声音。蜂铃器的工作与否可以通过开关按键控制。用户也可以关闭蜂铃器提示功能。 蜂铃器模块电路电路图如图3.16所示。 图3.16 蜂铃器电路原理图 3.10 PWM控制技术 3.10.1 PWM简介 PWM是脉冲宽度调制的简称。它对执行电路的控制是利用单片机的数字输出来实现的,PWM是将模拟量变为为数字量的形式,改变信号能始终保持数字形式,不需要进行数模转换。因此PWM广泛应用于工程测量等领域。 脉冲宽度调制的控制方式就是控制电路开关器件的闭合,可以使输出端得到幅值相等的脉冲信号。 3.10.2 AT89C52单片机生成PWM方法 由于AT89系列单片机没有内置的PWM控制器,所以需要通过软件的方法在I/O端口上模拟PWM输出。软件设计一般有软件延时和定时/计数器产生时钟信号。 软件延时方法就是通过反复调用一个延时子函数。要使单片机某个引脚输出PWM信号,只要反复执行:置高输出位,延时,置低输出位,延时。就可以产生用于控制的PWM信号。 利用定时器方法获得PWM信号可分为定时时间固定和定时时间不固定两种,定时时间法和延时法相似,本次设计采用定时时间固定的定时方式获取对执行电路作用的PWM信号。其定时时间10ms, 3.12 本章总结 本章从硬件设计角度介绍了单片机、电源电路、显示电路、键盘电路、驱动执行电路、执行电路、温度采集电路、蜂铃器电路等模块的设计,简单介绍了设计所用到的主要芯片,并以此为核心设计相应的扩展电路。概要介绍了AT89C52单片机的PWM信号的产生办法。最后给出总电路设计图以及设计所需要的元件清单。 4 系统软件设计 4.1 主程序设计 系统上电后,单片机开始运行,首先进行系统复位。系统从复位后的初始的状态开始运行。然后执行系统初始化操作,DS18B20初始温度为20.0℃,设置温度初始化为20.0℃。接着读取当前室内温度并显示。比较当前室温和设置温度,初始状态下两者温度相等,送风系统开始工作,绿灯亮。当外界温度变化时,单片机通过定时/计数器功能定时采样温度变化,定时比较温度大小。并由定时器产生PWM信号驱动相关电路工作。用户可随时通过键盘设置需求温度。若当前温度大于设置温度,制冷系统开始工作,蓝灯亮。若当前温度小于设置温度,制热系统工作,红灯亮。整个过程都是基于单片机的实时自动控制。系统流程图如下图4.1所示。 开始main 系统初始化 T>50℃或者T<5℃ DS18B20采样当前温度 T>40℃或者T<10℃ 设置温度 是 是否高于当前温度 蜂铃器响 否 是 制热 是否低于设置温度 制冷 送风 图4.1 主程序流程图 4.2 初始化程序设计 初始化程序主要是设置P3=0x0f,P2=0xf0,设置外部中断0,选择定时/计数器0。外部中断服务子程序的功能是:当有按键按下时,通过与门触发中断。获取按键键值并处理该按键对应的功能函数。定时/中断服务子程序功能是:产生PWM控制信号和定时获取当前温度并显示出来。外部中断函数和定时计数函数名称及功能如下表4.1所示。 表4.1 中断/定时函数表 序号 函数名 功能 1 void time0(void) interrupt 1 定时器函数,计数 2 void Compare_S_N_Temper(void) 外部中断0中断函数 初始化流程图如下图4.2所示。 开始 返回 开总中断 开外部中断0 开定时/计数器0 设置P2、P3端口 图4.2 初始化程序流程图 4.3 DS18B20温度采样程序设计 首先初始化DS18B20传感器。再进行读写命令操作,最后才能对显示数据操作。DS18B20的部分操作指令如表4.2所示。 表4.2 DS18B20的部分操作指令 序号 指令 说明 2 0x44H 温度转换指令 3 0xCCH 跳过ROM序列号指令 4 0xBEH 读数据指令 5 Ox4EH 写数据 DS18B20的工作流程图如下图4.3所示。 开始 否 是否初始化成功 是 发跳过ROM命令 发温度转换命令(0x44H) 否 是否转换完成 是 初始化DS18B20 读暂存器命令(0xBEH) 读转换后的数据 送单片机 返回 图4.3 DS18B20的工作流程图 本设计DS18B20模块使用的函数如下表4.3所示。 表4.3 传感器模块函数列表 序号 函数名 功能 1 void delay_ds18b20(uint useconds) 延时函数 2 void Write_One_Bit(uchar value) 写入一位值 3 void Write_One_Byte(uchar value) 写入字节数据 4 uchar Read_One_Bit(void) 读取一位值 5 uchar Read_One_Byte(void) 读取一个字节数据 6 uchar DS18B20_Init(void) 初始化传感器 7 void TransAndDisplayTemp(void) 转换并显示温度 8 void Get_Temperature(void) 传感器获取外界温度 4.4 LCD显示程序设计 首先初始化LCM1602液晶模块,然后写命令到显示器,再发送待显示温度给显示器。LCM1602液晶模块内部已经存储了阿拉伯数字、英文字母的大小写、常用的符号等不同的点阵字符图形,能够满足空调温度控制系统需要的人机交互界面的显示工作。程序中用到LCM1602的如下表4.4中的几个命令: 表4.4 LCM1602的常用命令 序号 命令 功能 1 0x01 显示清屏,数据指针=0 2 0x02 显示回车,数据指针=0 3 0x0C 显示开关及光标设置 4 0x06 移动光标设置 5 0x38 设置两行十六位的显示,5*7点阵,八个数据接口引脚 LCM1602可以显示2*16个字符,本系统中,显示字符从0x03H开始,从0x08H开始显示温度,其显示地址如下表4.5所示。 表4.5 LCM1602显示地址 1 2 3 4 5 6 7 8 00H 01H 02H 03H 04H 05H 06H 07H 40H 41H 42H 43H 44H 45H 46H 47H 9 10 11 12 13 14 15 16 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH 48H 49H 4AH 4BH 4CH 4DH 4EH 4FH LCM1602工作显示流程图如下图4.4所示。 开始 初始化LCM1602 写命令到LCM1602 发送显示数据 显示 图4.4 显示程序流程图 本设计LCM1602模块使用的函数如下表4.6所示。 表4.6 显示模块函数列表 序号 函数名 功能 1 void delay_lcd(uint temp) 延时函数 2 void Write_Cmd_LCD(uchar cmd) 写指令到LCD 3 void Write_Date_LCD(uchar date) 写显示数据到LCD 4 void Init_LCD(void) 初始化LCD 5 void DisplayToLCD(void) 在液晶屏上显示温度 4.5 按键程序设计 矩阵非编码键盘的处理流程:首先单片机向键盘接口输出0xF0,然后再读取列检测信号。若有一列信号为“1”,则表示有键按下,反之,没有键按下。然后判断按键所在行和列,计算该按键的键码。其中行扫描码HM是:0xFE、0xFD、0xFB、0xF7,列扫描码LM是:0xE0、0xD0、0xB0、0x70。键值计算公式是:KEY=(HM)(取反)+(LM | 0x0f)(取反),根据这个公式计算按键的键值如下表4.7所示。 表4.7 4x4矩阵键盘键值表 0x11 0x12 0x14 0x18 0x21 0x22 0x24 0x28 0x41 0x42 0x44 0x48 0x81 0x82 0x84 0x88 本设计中按键处理函数作为外部中断服务子程序放置在外部中断函数中运行,键扫描流程图如下图4.5所示。 开始 否 由键号转至操作 查表确定键号 查列号 逐行扫描 有键按下吗 是 图4.5 按键扫描流程图 本设计按键处理模块使用的函数如下表4.8所示。 表4.8 按键处理模块函数列表 序号 函数名 功能 1 void Delay_Key(void) 延时函数 2 uchar Key_Scan(void) 写指令到LCD 3 void Key_Functional_treatment(void) 按按键并实现该按键的功能 4.6 本章小结 本章详细介绍了设计中的的系统流程图。概要介绍了显示部分、按键部分、温度传感器部分等几个重点模块的设计流程和工作步骤。列出了实现各部分功能的函数清单。通过对应的流程图,可以较为快速的了解程序的执行过程,也可以明白各模块在系统中所负责执行的功能。 5系统调试与仿真 5.1 系统调试 调试分为硬件调试和软件调试两部分。本次软件编程在Keil uVision4中编写,电路原理图在Proteus ISIS环境中画的。 5.1.1 编程与画原理图 1. 建立程序文件 (1)打开Keil uVision4,新建Graduation项目,选择AT89C52单片机作为CPU; (2)新建C源文件,保存并将其导入到Source Group1中; (3)设置生成.hex文件输出,成功后程序运行将生成能导入单片机的.hex文件。 (4)编写功能程序。多次重复“运行——调试——运行——调试”步奏。直到程序运行正确。 使用Keil uVision4编写程序(C语言)如下图5.1所示。 图5.1 Keil uVision4编程界面 2. 画原理图 (1)打开Proteus ISIS,新建Graduation文件并和Keil程序工程保存在同一个文件中, (2)设置原理图界面图纸大小。查找并选择设计图需要的元件。 (3)放置、连接、编辑元器件。 (4)对完成的原理图综合检测。 使用Proteus ISIS所画原理图如下图5.2所示。 图5.2 Proteus ISIS画原理图界面 3. 加载目标代码文件: (1)在原理图中,双击AT89C52,在打开的对话框“Edit Component”中设置单片机的频率为12MHz; (2)在“Project File”栏中选择之前在Keil中生成的.HEX文件,点击OK,即可。 (3)点击“Debug”,在其下拉菜单中选择“Use Remote Debug Monitor”选项,使 Keil程序和Proteus软件联调。 5.1.2 进行调试与仿真 导入目标文件后,开始调试,执行程序,在Proteus中单击按钮开始仿真。程序中默认设置温度是28.0℃,DS18B20传感器的温度同样设置在28.0℃,所以仿真开始之后,显示屏上显示的当前温度和设置温度都是20.0℃,此时绿灯亮,表示空调系统开始送风,仿真效果图如下图5.3所示。 图5.3 当前温度等于设置温度时的电路仿真效果图 通过键盘设置一个温度值,比如设置温度为30.0℃,大于当前温度(280.0℃)时,红灯亮,空调系统开始制热,仿真效果图见图5.4所示。 图5.4 当前温度小于设置温度时的电路仿真效果图 当设置温度(28.0℃)小于当前温度(30.0℃)时蓝灯亮,空调系统开始制冷,仿真效果图见图5.5所示。 图5.5 当前温度大于设置温度时的电路仿真效果图 当由于特殊原因使室温突然升高,比如着火、制冷系统坏掉等,室内温度高于50.0℃时,蜂铃器就会发出警报声,提醒用户注意安全。当室温突然降低至5.0℃时,蜂铃器同样发出警报声。 家用空调一般不需要设置很高或者很低的温度。当设置温度高于40℃或低于10℃时,蜂铃器会发出警报声,提醒用户设置合适温度。用户也可以通过蜂铃器开关按键关闭蜂铃器。 单击 结束仿真。 5.2 硬件调试 硬件调试,首先要检测所用的元器件是否都是合格的,电阻电容大小的选择是否适合电路正常工作。在焊接电路前先用万能表检测一下电阻电容的值是否符合标值,检测开关按键是否短路,晶振、三极管、二极管、继电器等都需要事前检测一遍。电路焊接好之后,就要仔细观察有无漏贴的器件,有没有虚焊的情况,电容、二极管、NPN管以及其他芯片是否接反。焊接是否会造成短路等。然后对照原理图一步一步检测电路连线是否正确。 上电前要确定外接电源是否是满足系统工作所需电压。正负极是否正确。在确定无短路现象后开始上电调试。系统运行时仔细观察有无异常现象,如冒烟、元器件异常发热等,如果有上述现象,则应该马上关掉电源,查找故障。如此反复检测。直到电路系统无明显故障。把程序烧写进单片机。 然后就是静态调试。先不要输入信号。检测系统在初始化状态下运行结果是否和预期一样。检测各级电流电压是否正常。接着输入信号,进行动态调试。输入各种不同温度和当前温度比较,查看电路系统是否正常执行。如果硬件测试都正常,则表明此次空调温度控制系统设计基本成功。 5.3 实物图 图5.6 实物图 5.4 本章小结 本章介绍了Proteus ISIS和Keil uVision4两种软件在本设计中的使用方法。分别用两款软件完成编程和画原理图。把在Keil中生成的.hex文件导入Proteus原理图中进行仿真。简要介绍了硬件测试的办法和注意事项。做实物时要认真对照仿真图连线,做到不虚焊,不接错。 结束语 现代科学技术的飞速发展。使智能设备的自动控制技术的功能、性能和精度越来越高。空调系统的主动控制技术也得到了迅速发展。从最初的人工操作,到单片机在空调控制中的应用。从当初的为设备服务扩大到今天给大家的生产生活提供舒适的环境。空调也由简单的制冷或者制热功能。发展成现在制冷制热送风等各种功能集一身的智能设备。 本设计以AT89C52单片机作为本系统处理器,综合利用了DS18B20、1602字符型LCM等芯片,基本实现了主要的温度控制功能,通过仿真调试,运行结果也比较稳定。单片机做为中枢控制系统,DS18B20采集温度传输给单片机,单片机经过智能分析,发出显示信号和执行信号,完成对室温的实时调节。 本次设计,首先进一步熟悉了单片机应用系统的功效。结合这次的设计把以前没理解的知识原理从新梳理一次。既加深了专业知识的了解,同时也把学到的理论知识应用到这次的实践中。通过完成这小应用控制系统设计,增加了对专业知识学习的兴趣。虽然设计中还有许多不足之处,有些地方还有很大的改进空间。以后的工作中将会更加努力的在嵌入式设计方面有所发展。 本设计还存在以下一些不完善之处: 1.没有零下温度设置功能,只能设置00.0℃~99.9℃之间的温度。 2.编写的程序不够简洁,有bug。 3.本系统仅实现了空调的温度控制和送风功能。没有实际空调中的模式选择功能。 参考文献 [1]. 唐颖. 单片机原理与应用[M]. 北京:北京大学出版社,2008. [2]. 赵建领,崔昭霞. 精通51单片机开发技术与应用实例[M]. 北京:电子工业出版社,2012. [3]. 谭浩强. C语言程序设计(第三版)[M].北京:清华大学出版社,2005 [4]. 求是科技. 单片机典型模块设计实例导航[M]. 北京:人民邮电出版社,2006. [5]. 谢维成,杨加国. 单片机原理与应用及C51程序设计[M]. 北京:清华大学出版社,2006. [6]. 楼然苗,李飞光. 51系列单片机设计实例[M]. 北京:北京航空航天大学出版社,2003. [7]. 毛谦敏. 单片机原理及应用系统设计[M]. 国防工业出版社, 2008. [8]. 李金川,郑智慧. 空调制冷自控系统运行于管理[M]. 北京:中国建材工业出版社,2002 [9]. 潘新民,王燕芳. 微型计算机控制技术实用教程[M]. 北京:电子工业出版社,2005. [10]. 郁有文,常键,程继红. 传感器原理及工程应用(第三版)[M]. 西安:西安电子科技大学出版社,2008. [11]. 朱清慧,张凤蕊,霍天嵩. Proteus教程[M]. 北京:清华大学出版社,2008. [12]. 康华光. 电子技术基础 模拟部分(第五版)[M]. 北京:高等教育出版社,2007. [12]. 阎石. 数字电子技术基础(第五版)[M]. 北京:高等教育出版社,2006. [13]. 刘大茂. 单片机应用系统监控主程序的设计方法[J].上海:上海人民出版社,2000. [14]. 于珍珠,赵娜,赵刚. 基于51单片机的温度测量系统[J]. 2007. 23(1-2):146-148. [15]. 齐建家,胡天明. 基于DS18B20的数字温度设计及其应用. 黑龙江工程学院学报. 2008. 22(2):59-62. [16]. 宋亚伟. 基于DS18B29的温度控制采集系统[M]. 机电工程技术. 2008. 37(09):89-91. [17]. 赵佩华. 单片机接口技术及应用[M]. 北京:机械工业出版社,2003. [18]. 雷伏容,张小林. 51单片机常用模块设计查询手册[M]. 北京:清华大学出版社,2010. [19]. 沈红卫. 基于单片机的智能系统设计与实现[M]. 北京:电子工业出版社,2005. [20]. 张庆双. 常用元器件的选用与检测[M]. 北京:机械工业出版社,2004. [21]. 周丽娜. Protel 99 SE电路设计技术(基础案例篇)[M]. 北京:中国铁道出版社,2009. [22]. 王平. 单片机应用设计与制作——基于Keil和Proteus开发仿真平台[M]. 北京:清华大学出版社,2012. [23]. Paul Horowitz, Winfield Hill. The Art of Electronics[M]. Cambridge University Press: University of Cambridge, Cambridge CB2 1TN, UK,2006. [24]. Donald A. Neamen. Electronic Circuit Analysis and Design, 2nd Ed.[M](电子电路分析与设计(第2版). 北京:清华大学出版社, 2008. [25]. Guo Tianxiang. The 51 single-chip C language tutorial. Beijing: Publishing House of electronics industry, 2009 [26]. 51单片机学习网 http://www.51bs51.com [27]. 电子元器件查询 http://www.chinadz.com/ [28]. 中国电子网. http://www.21ic.com 致 谢 经过六个月时间的设计,从选题到查找资料,从方案预备到方案论证,再到器件选择,整个系统的硬件和软件系统已初步成型。从原来对单片机应用项目不熟悉到现在对项目的基本框架和某些细节有了比较清楚的认识。其间不少人给了我许多无私的帮助,在此真诚地向他们说声谢谢。 衷心感谢我的指导老师XXX教授。感谢刘老师认真倾听我的问题,感谢老师的耐心指导以及真诚的鼓励。刘老师渊博的知识、丰富科研经验、兢兢业业的治学精神使我受益非浅。至此论文完成之际,谨向老师表示由衷的感谢。 感谢XXX等同学给予我的帮助,在我遇到一些不懂的地方,是他们细心给我讲解,协助我完成了部分工作。 最后,谨以此文献给我挚爱的父母以及所有关心帮助过我的亲人和朋友! 作者: 年 月 日 附录1 系统总电路图1 附录1 系统总电路图1 附录2 系统总电路图2 附录2 系统总电路图2 附录3 元件清单列表 本系统所用的元器件清单如表附件6.1所示。 附件6.1 元件清单 序号 元件名称 数量 1 AT89C52单片机 1 2 LCM1602显示器 1 3 DS18B20温度传感器 1 4 点触式按键 16 5 开关 3 6 74LS21与门 1 8 30pF瓷片电容 2 9 10uF电解电容 1 10 12MHz晶振 1 11 10K排阻 1 12 10K电阻 10 16 NPN三极管 4 17 二极管 3 18 继电器 3 19 红色LED 1 20 蓝色LED 1 21 绿色LED 1 22 220欧姆电阻 3 23 蜂铃器 1 附录4 程序源代码 Main.c文件 /************************************************************** * 文件名称: 主源程序文件() * 作者: LLQ * 日期: 2013-4-29 *功能简介:该项目具有采样温度并显示,设置温度,通过温 * 度比较控制LED灯亮灭,灯的模拟含义: * 红灯--制热,蓝灯--制冷,绿灯--吹风 * 键盘扫描--中断扫描方式 **************************************************************/ #include #include #include "global.h" #include "lcd.h" #include "ds18b20.h" #include "key.h" float Current_Temp=0; //定义当前温度变量,赋初值0度 float Set_Temp=20.0; //定义设置的温度变量,初值为0度 //温度传感器采样温度寄存器数组 uchar Current_Disp_Temp_Buf[]={" Now: 20.0 "}; //用户设置温度寄存器数组 uchar Set_Critical_Temp_Buf[]={" Set: 20.0 "}; uint Cnt_T=0; //温度采样间隔计时变量 uint Cnt_P=0; //比较计时变量 uint flag_1=1; //比较标志位1 uint flag_2=0; //比较标志位2 uint bits=0; //显示位设置标示0,1,2,3,4 void delay(uint cnt) //延时函数 { for(cnt;cnt>0;cnt--); } /***************************************************************** * 函数名称:Beep() * 功能:警报功能,当温度超出或低于一定 * 范围时发出警报声 * 参数:无 * 返回值:无 *****************************************************************/ void Beep() { uint i=0; if(Current_Temp>50||Current_Temp<5||Set_Temp>40||Set_Temp<10) { beep=1; delay(40); beep=0; delay(25); } } void Compare_S_N_Temper(void); //函数 /********************************************************* * 函数名称:Init_timer0() * 功能:开启外部中断0和定时器中断0 * 参数:无 * 返回值:无 *********************************************************/ void Init_timer0(void) { TMOD = 0x01; //设置定时器0的工作方式1 /10ms定时要求 TH0 =0xD8; //X=65536-10000=0XD8F0H TL0 =0xF0; IE=0x82; ET0 =1; //允许定时器中断 TR0 =1; //启动定时器计数器 IT0 = 1; //设置为边沿触发方式的外部中断0 EX0 = 1; //开外部中断 EA =1; //开总中断 } /********************************************************** * 函数名称:time0() * 功能:定时器函数,计数 * 参数:无 * 返回值:无 * 利用定时/计数器方式获得PWM信号 **********************************************************/ void time0(void) interrupt 1 { TH0 =0xD8; TL0 =0xF0; Compare_S_N_Temper(); //温度比较,长生PWM信号控制灯的亮灭 Beep(); //警报函数 if(++Cnt_T==200) //0.2s温度采样一次 { TR0=0; Get_Temperature(); TransAndDisplayTemp(); Cnt_T=0; if(++Cnt_P==5) { flag_2=1; } TR0=1; } } void time1(void) interrupt 0 //外部中断0中断函数 { Key_Functional_treatment(); //按键功能实现函数 } /********************************************************** * 函数名称:Compare_S_N_Temper() * 功能:比较当前温度和设置的温度 * 根据比较结果制冷或制热或吹风 * 参数:无 * 返回值:无 **********************************************************/ void Compare_S_N_Temper(void) { if(flag_1&&flag_2) { //当前温度小于设置温度,制热,红灯亮 if(Current_TempSet_Temp) { warm_gas=0; cold_gas=1; wind=0; } //当前温度等于设置温度,吹风,绿灯亮 if(Current_Temp==Set_Temp) { warm_gas=0; cold_gas=0; wind=1; } } } int main(void) { Init_timer0(); //初始化计数器外部中断 Init_LCD(); //初始化LCD显示器 Init_DS18B20(); //初始化温传感器 P3=0x0f; while(1) { P2=0xf0; DisplayToLCD(); //显示 } } Global.c文件 #ifndef _GLOBAL_H_ #define _GLOBAL_H_ #include #include #define uchar unsigned char #define uint unsigned int extern float Current_Temp; extern float Set_Temp; extern uint flag_1; extern uint flag_2; extern uchar Current_Disp_Temp_Buf[]; extern uchar Set_Critical_Temp_Buf[]; extern uint bits; sbit LCD_RS = P1^2; sbit LCD_EN = P1^0; sbit LCD_RW = P1^1; sbit DS18B20_DQ = P1^7; sbit warm_gas = P3^5; //接暖气引脚 sbit cold_gas = P3^6; //接冷气引脚 sbit wind = P3^7; //扫风引脚 sbit beep = P1^5; //蜂铃器引脚 #endif DS18B20.c文件 /************************************************************** * 函数名称: DS18B20源程序文件 * 功能: 处理温度传感器的温度获取,数据传递 * 作者: LLQ * 日期: 2013-4-28 **************************************************************/ #include "global.h" //定义数组用于存放获取的温度 uchar temp_value[]={0x00,0x00}; //定义数组用于存放由温度转换的数字显示 uchar Disp_Digit[]={0,0,0,0}; //数字表 uchar code Digit_table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; uchar tempT =0; //中间变量 void delay_ds18b20(uint useconds) //延时函数 微秒 { while(--useconds); } /************************************************************** * 函数名称: WriteOneBit() * 功能: 向1-Wire 总线上的DS18B20写入一位值 * 参数: val--待写入位 * 返回值: 无 **************************************************************/ void Write_One_Bit(uchar value) { DS18B20_DQ =0; //拉低数据线DQ开始写时间间隙 if(value==1) DS18B20_DQ =1; //数据线DQ置1,写1 else DS18B20_DQ =0; //数据线DQ置0,写0 delay_ds18b20(5); //延时,在时间间隙内保持电平值 DS18B20_DQ =1; //拉高数据线DQ } /************************************************************** * 函数名称: Write_One_Byte() * 功能: 向1-Wire 总线上的DS18B20写入字节数据 采用循环移位的方式写入 * 参数: byte--待写入数据 * 返回值: 无 **************************************************************/ void Write_One_Byte(uchar value) { uchar i; uchar temp; for(i=0;i<8;i++) //循环写入字节,每次写入一位 { temp =value>>i; //移位 temp &=0x01; Write_One_Bit(temp); } delay_ds18b20(5); } /************************************************************** * 函数名称: ReadOneBit() * 功能: 从1-Wire 总线上的DS18B20读取一位值 * 参数: 无 返回值: DS18B20_DQ--位数据 **************************************************************/ uchar Read_One_Bit(void) { uint i=0; DS18B20_DQ =0; //拉低数据总线DQ,开始读时间间隙 DS18B20_DQ =1; //DQ置1 for(i=0;i<5;i++); //延时 return DS18B20_DQ; //返回数据总线上的位数据 } /************************************************************** * 函数名称: ReadOneByte() * 功能: 从1-Wire 总线上的DS18B20读取一个字节数据 * 采用循环移位的方式读取 * 参数: 无 * 返回值: value--读取的字节 **************************************************************/ uchar Read_One_Byte(void) { uint i=0; uchar value=0; for(i=0;i<8;i++) //循环读取字节,每次读取一位 { if(Read_One_Bit()) value |=0x01<>4)|((temp_value[1]&0x07)<<4); Disp_Digit[3] = tempT/100; //符号位 Disp_Digit[2] = tempT%100/10; //十分位 Disp_Digit[1] = tempT%10; //个位 Current_Disp_Temp_Buf[11]=Disp_Digit[0]+'0'; //小数位 Current_Disp_Temp_Buf[10]='.'; //小数点 Current_Disp_Temp_Buf[9]=Disp_Digit[1]+'0'; //个位 Current_Disp_Temp_Buf[8]=Disp_Digit[2]+'0'; //十分位 Current_Disp_Temp_Buf[7]=Disp_Digit[3]+'0'; //符号位显示 Current_Temp = Disp_Digit[2]*10 +Disp_Digit[1] +Disp_Digit[0]*0.1; if(Disp_Digit[3] ==0) //温度显示十分位 Current_Disp_Temp_Buf[7] = ' '; if((Disp_Digit[2] ==0&&Disp_Digit[3] ==0)) //温度显示个位 Current_Disp_Temp_Buf[8] = ' '; if(flag) { Current_Temp =-(Disp_Digit[2]*10+Disp_Digit[1]+Disp_Digit[0]*0.1); if(Current_Disp_Temp_Buf[8] == ' ') Current_Disp_Temp_Buf[8] = '-'; else if(Current_Disp_Temp_Buf[7] == ' ') Current_Disp_Temp_Buf[7] = '-'; else Current_Disp_Temp_Buf[6] = '-'; } } DS18B20.h文件 #ifndef _DS18B20_H_ #define _DS18B20_H_ extern uchar DS18B20_Init(void); extern void Get_Temperature(void); extern void TransAndDisplayTemp(void); #endif LCD.c文件 /************************************************************** * 函数名称: LCD源程序文件(LM0162) * 功能: 显示屏处理 * 作者: LLQ * 日期: 2013-4-27 **************************************************************/ #include "global.h" #include void delay_lcd(uint temp) //延时函数 N--延时毫秒 { uint x,y; for(x=useconds;x>0;x--) for(y=50;y>0;y--); } /************************************************************** * 函数名称: Write_Cmd_LCD() * 功能: 写指令到LCD * 参数: cmd--指令 * 返回值: 无 **************************************************************/ void Write_Cmd_LCD(uchar cmd) { LCD_RS=0; //选择指令寄存器,写命令模式 LCD_RW=0; LCD_EN=0; _nop_(); //执行空操作 占1us _nop_(); P0=cmd; //将要写的命令字送到数据总线上 delay_lcd(3); //稍作延时以待数据稳定 LCD_EN=1; //使能端给一高脉冲,因为初始化函数中已经将LCD_EN置零 delay_lcd(3); //稍作延时 LCD_EN=0; //将使能端置0完成高脉冲 } /************************************************************** * 函数名称: Write_Date_LCD() * 功能: 写显示数据到LCD * 参数: data--显示数据 * 返回值: 无 **************************************************************/ void Write_Date_LCD(uchar date) { LCD_RS=1; //选择数据寄存器,写数据模式 LCD_EN=0; LCD_RW=0; P0=date; delay_lcd(3); LCD_EN=1; delay_lcd(3); LCD_EN=0; } /************************************************************** * 函数名称: Init_LCD() * 功能: 初始化LCD * 参数: cmd--指令 * 返回值: 无 **************************************************************/ void Init_LCD(void) { LCD_EN=0; LCD_RW=0; delay_lcd(5); //延时15ms Write_Cmd_LCD(0x01); //清除LCD显示内容 Write_Cmd_LCD(0x38); //设置16*2显示,5*7点阵,8位数据接口 delay_lcd(3); Write_Cmd_LCD(0x0c); //设置开显示,关光标 delay_lcd(3); Write_Cmd_LCD(0x06); //移动光标设置 delay_lcd(3); Write_Cmd_LCD(0x01); //清除LCD显示内容 delay_lcd(3); } /************************************************************** * 函数名称: DisplayToLCD() * 功能: 显示温度 * 参数: 无 * 返回值: 无 **************************************************************/ void DisplayToLCD(void) { uchar num; Write_Cmd_LCD(0x80); //上排显示当前温度 for(num=0;num<15;num++) { Write_Date_LCD(Current_Disp_Temp_Buf[num]); } Write_Cmd_LCD(0x80+0x40); //下排显示设置温度 for(num=0;num<13;num++) { Write_Date_LCD(Set_Critical_Temp_Buf[num]); } } LCD.h文件 #ifndef _LCD_LCM1602_H_ #define _LCD_LCM1602_H_ extern void Init_LCD(void); extern void DisplayToLCD(void); #endif KEY.c文件 /********************************************************************* * 文件名称: 矩阵键盘源程序文件 * 功能: 显示当前温度和设置的温度 * 开发者: LLQ * 日期: 2013-4-29 ********************************************************************/ #include #include #include "Key.h" #include "global.h" void Delay_Key(void) //键盘文件中的延时函数 ,延时10ms { uchar i; for(i=200;i>0;i--); } /************************************************************** * 函数名称: Scan_Key() * 功能: 键盘扫描 * 参数: 无 * 返回值: 扫描获得的键值 * 键值表: *{0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42, * 0x44,0x48,0x81,0x82,0x84,0x88}; **************************************************************/ uchar Key_Scan(void) { uchar codes; //定义扫描码变量 uchar keyvalue; //定义键值变量 uchar i; if((P2&0xf0)!=0xf0) //判断是否有键按下 { Delay_Key(); //延时去抖动 if((P2&0xf0)!=0xf0) //再次判断是否有键按下 { codes = 0xfe; //行扫描码0xfe,0xfd,0xfb,0xf7 for(i=0;i<4;i++) { P2 = codes; if((P2&0xf0)!=0xf0) { keyvalue = ~P2; //键码 switch(keyvalue) { case 0x11: return K_ONE; break; //1 case 0x12: return K_TWO; break; //2 case 0x14: return K_THREE; break; //3 case 0x18: return K_FOUR; break; //4 case 0x21: return K_FIVE; break; //5 case 0x22: return K_SIX; break; //6 case 0x24: return K_SEVEN; break; //7 case 0x28: return K_EIGHT; break; //8 case 0x41: return K_NINE; break; //9 case 0x42: return K_ZERO; break; //0 case 0x44: return K_EMPTY; break; //EMPTY case 0x48: return K_ADD; break; //UP case 0x81: return K_OK; break; //0K case 0x82: return K_SHIFT; break; //SET case 0x84: return K_CLEAR; break; //CLEAR case 0x88: return K_MINUS; break; //DOWN default: break; } } else codes = _crol_(codes,1); //换行扫描 } } } return -1; } /************************************************************** * 函数名称: Key_Functional_treatment() * 功能: 按按键并实现该按键的功能 * 参数: 无 * 返回值: 无 *备注:数字0,1, 2, 3, 4, 5, 6, 7, 8, 9 的ASCII码值分别是: * 48,49,50,51,52,53,54,55,56,57, **************************************************************/ void Key_Functional_treatment(void) { uchar key; if(bits==0) { key = Scan_Key(); if(K_ONE == key) { while(Scan_Key() == K_ONE); //再次判断是否按键值相等 Set_Critical_Temp_Buf[8]='1'; bits++; } if(K_TWO == key) { while(Scan_Key() == K_TWO); Set_Critical_Temp_Buf[8]='2'; bits++; } if(K_THREE == key) { while(Scan_Key() == K_THREE); Set_Critical_Temp_Buf[8]='3'; bits++; } if(K_FOUR == key) { while(Scan_Key() == K_FOUR); Set_Critical_Temp_Buf[8]='4'; bits++; } if(K_FIVE == key) { while(Scan_Key() == K_FIVE); Set_Critical_Temp_Buf[8]='5'; bits++; } if(K_SIX == key) { while(Scan_Key() == K_SIX); Set_Critical_Temp_Buf[8]='6'; bits++; } if(K_SEVEN == key) { while(Scan_Key() == K_SEVEN); Set_Critical_Temp_Buf[8]='7'; bits++; } if(K_EIGHT == key) { while(Scan_Key() == K_EIGHT); Set_Critical_Temp_Buf[8]='8'; bits++; } if(K_NINE == key) { while(Scan_Key() == K_NINE); Set_Critical_Temp_Buf[8]='9'; } if(K_ZERO == key) { while(Scan_Key() == K_ZERO); Set_Critical_Temp_Buf[8]='0'; bits++; } if(K_CLEAR == key) { while(Scan_Key() == K_CLEAR); Set_Critical_Temp_Buf[11]='0'; Set_Critical_Temp_Buf[10]='.'; Set_Critical_Temp_Buf[9]='0'; Set_Critical_Temp_Buf[8]='0'; flag_1=0; //比较标志位 cold_gas=0; warm_gas=0; wind=0; } if(K_ADD == key) { while(Scan_Key() == K_ADD); if((Set_Critical_Temp_Buf[11]>47)&&(Set_Critical_Temp_Buf[11]<57)) { Set_Critical_Temp_Buf[11]+=1; } else if(Set_Critical_Temp_Buf[11]==57) { Set_Critical_Temp_Buf[11]=48; if((Set_Critical_Temp_Buf[9]>47)&&(Set_Critical_Temp_Buf[9]<57)) { Set_Critical_Temp_Buf[9]+=1; } else if(Set_Critical_Temp_Buf[9]==57) { Set_Critical_Temp_Buf[9]=48; if((Set_Critical_Temp_Buf[8]>47)&&(Set_Critical_Temp_Buf[8]<57)) { Set_Critical_Temp_Buf[8]+=1; } else if(Set_Critical_Temp_Buf[8]==57) { Set_Critical_Temp_Buf[8]=48; } } } } if(K_MINUS == key) { while(Scan_Key() == K_MINUS); if((Set_Critical_Temp_Buf[11]>48)&&(Set_Critical_Temp_Buf[11]<58)) { Set_Critical_Temp_Buf[11]-=1; } else if(Set_Critical_Temp_Buf[11]==48) { Set_Critical_Temp_Buf[11]=57; if((Set_Critical_Temp_Buf[9]>48)&&(Set_Critical_Temp_Buf[9]<58)) { Set_Critical_Temp_Buf[9]-=1; } else if(Set_Critical_Temp_Buf[9]==48) { Set_Critical_Temp_Buf[9]=57; if((Set_Critical_Temp_Buf[8]>48)&&(Set_Critical_Temp_Buf[8]<58)) { Set_Critical_Temp_Buf[8]-=1; } else if(Set_Critical_Temp_Buf[8]==48) { Set_Critical_Temp_Buf[8]=57; } } } } if(K_SHIFT == key) { while(Scan_Key() == K_SHIFT); bits++; } if(K_OK == key) { while(Scan_Key() == K_OK); Set_Critical_Temp_Buf[10]='.'; Set_Temp=(Set_Critical_Temp_Buf[8]-48)*10 +(Set_Critical_Temp_Buf[9]-48) +(Set_Critical_Temp_Buf[11]-48)*0.1; bits=0; flag_1=1; } } if(bits==1) { key = Scan_Key(); if(K_ONE == key) { while(Scan_Key() == K_ONE); Set_Critical_Temp_Buf[9]='1'; bits++; } if(K_TWO == key) { while(Scan_Key() == K_TWO); Set_Critical_Temp_Buf[9]='2'; bits++; } if(K_THREE == key) { while(Scan_Key() == K_THREE); Set_Critical_Temp_Buf[9]='3'; bits++; } if(K_FOUR == key) { while(Scan_Key() == K_FOUR); Set_Critical_Temp_Buf[9]='4'; bits++; } if(K_FIVE == key) { while(Scan_Key() == K_FIVE); Set_Critical_Temp_Buf[9]='5'; bits++; } if(K_SIX == key) { while(Scan_Key() == K_SIX); Set_Critical_Temp_Buf[9]='6'; bits++; } if(K_SEVEN == key) { while(Scan_Key() == K_SEVEN); Set_Critical_Temp_Buf[9]='7'; bits++; } if(K_EIGHT == key) { while(Scan_Key() == K_EIGHT); Set_Critical_Temp_Buf[9]='8'; bits++; } if(K_NINE == key) { while(Scan_Key() == K_NINE); Set_Critical_Temp_Buf[9]='9'; bits++; } if(K_ZERO == key) { while(Scan_Key() == K_ZERO); Set_Critical_Temp_Buf[9]='0'; bits++; } if(K_CLEAR == key) { while(Scan_Key() == K_CLEAR); Set_Critical_Temp_Buf[8] ='0'; Set_Critical_Temp_Buf[9] ='0'; Set_Critical_Temp_Buf[10]='.'; Set_Critical_Temp_Buf[11]='0'; flag_1=0; cold_gas=0; warm_gas=0; bits=0; } if(K_ADD == key) { while(Scan_Key() == K_ADD); if((Set_Critical_Temp_Buf[9]>47)&&(Set_Critical_Temp_Buf[9]<57)) { Set_Critical_Temp_Buf[9]+=1; } else if(Set_Critical_Temp_Buf[9]==57) //9 { Set_Critical_Temp_Buf[9]=48; //0 if((Set_Critical_Temp_Buf[8]>47)&&(Set_Critical_Temp_Buf[8]<57)) { Set_Critical_Temp_Buf[8]+=1; } else if(Set_Critical_Temp_Buf[8]==57) { Set_Critical_Temp_Buf[8]=48; } } } if(K_MINUS == key) { while(Scan_Key() == K_MINUS); if((Set_Critical_Temp_Buf[9]>48)&&(Set_Critical_Temp_Buf[9]<58)) { Set_Critical_Temp_Buf[9]-=1; } else if(Set_Critical_Temp_Buf[9]==48) { Set_Critical_Temp_Buf[9]=57; if((Set_Critical_Temp_Buf[8]>48)&&(Set_Critical_Temp_Buf[8]<58)) { Set_Critical_Temp_Buf[8]-=1; } else if(Set_Critical_Temp_Buf[8]==48) { Set_Critical_Temp_Buf[8]=57; } } } if(K_SHIFT == key) { while(Scan_Key() == K_SHIFT); bits++; } if(K_OK == key) { while(Scan_Key() == K_OK); Set_Critical_Temp_Buf[10]='.'; Set_Temp=(Set_Critical_Temp_Buf[8]-48)*10 +(Set_Critical_Temp_Buf[9]-48) +(Set_Critical_Temp_Buf[11]-48)*0.1; bits=0; flag_1=1; } } if(bits==2) { key = Scan_Key(); if(K_ONE == key) { while(Scan_Key() == K_ONE); Set_Critical_Temp_Buf[11]='1'; } if(K_TWO == key) { while(Scan_Key() == K_TWO); Set_Critical_Temp_Buf[11]='2'; } if(K_THREE == key) { while(Scan_Key() == K_THREE); Set_Critical_Temp_Buf[11]='3'; } if(K_FOUR == key) { while(Scan_Key() == K_FOUR); Set_Critical_Temp_Buf[11]='4'; } if(K_FIVE == key) { while(Scan_Key() == K_FIVE); Set_Critical_Temp_Buf[11]='5'; } if(K_SIX == key) { while(Scan_Key() == K_SIX); Set_Critical_Temp_Buf[11]='6'; } if(K_SEVEN == key) { while(Scan_Key() == K_SEVEN); Set_Critical_Temp_Buf[11]='7'; } if(K_EIGHT == key) { while(Scan_Key() == K_EIGHT); Set_Critical_Temp_Buf[11]='8'; } if(K_NINE == key) { while(Scan_Key() == K_NINE); Set_Critical_Temp_Buf[11]='9'; } if(K_ZERO == key) { while(Scan_Key() == K_ZERO); Set_Critical_Temp_Buf[11]='0'; } if(K_ADD == key) { while(Scan_Key() == K_ADD); if((Set_Critical_Temp_Buf[8]>47)&&(Set_Critical_Temp_Buf[8]<57)) { Set_Critical_Temp_Buf[8]+=1; } else if(Set_Critical_Temp_Buf[8]==57) //9 { Set_Critical_Temp_Buf[8]=48; //0 } } if(K_MINUS == key) { while(Scan_Key() == K_MINUS); if((Set_Critical_Temp_Buf[8]>48)&&(Set_Critical_Temp_Buf[8]<58)) { Set_Critical_Temp_Buf[8]-=1; } else if(Set_Critical_Temp_Buf[8]==48) { Set_Critical_Temp_Buf[8]=57; } } if(K_CLEAR == key) { while(Scan_Key() == K_CLEAR); Set_Critical_Temp_Buf[8] ='0'; Set_Critical_Temp_Buf[9] ='0'; Set_Critical_Temp_Buf[10]='.'; Set_Critical_Temp_Buf[11]='0'; flag_1=0; cold_gas=0; warm_gas=0; bits=0; } if(K_OK == key) { while(Scan_Key() == K_OK); Set_Critical_Temp_Buf[10]='.'; Set_Temp=(Set_Critical_Temp_Buf[8]-48)*10 +(Set_Critical_Temp_Buf[9]-48) +(Set_Critical_Temp_Buf[11]-48)*0.1; bits=0; flag_1=1; } if(K_SHIFT == key) { while(Scan_Key() == K_SHIFT); bits--; } } } KEY.h文件 #ifndef _KEY_H_ #define _KEY_H_ #include "global.h" //定义键值 #define K_ONE 0x31 //1 #define K_TWO 0x32 //2 #define K_THREE 0x33 //3 #define K_FOUR 0x34 //4 #define K_FIVE 0x35 //5 #define K_SIX 0x36 //6 #define K_SEVEN 0x37 //7 #define K_EIGHT 0x38 //8 #define K_NINE 0x39 //9 #define K_ZERO 0x30 //0 #define K_ADD 0x2B //+ #define K_MINUS 0x2D //- #define K_OK 0x50 //确定 #define K_SHIFT 0x51 //切换 #define K_CLEAR 0x52 //清除 #define K_EMPTY 0x2E //.空操作 extern void Key_Functional_treatment(void); #endif 本文档由香当网(https://www.xiangdang.net)用户上传

    下载文档到电脑,查找使用更方便

    文档的实际排版效果,会与网站的显示效果略有不同!!

    需要 10 香币 [ 分享文档获得香币 ] 0 人已下载

    下载文档