ANYANG INSTITUTE OF TECHNOLOGY 专 科 毕 业 论 文
基于AT89S52的智能电风扇控制系统设计
The Control System Design of Intelligent Fan Based on
AT89S52
院 系 名 称: 电子信息与电气工程学院 专 业 班 级: 08电气自动化1班 学 生 姓 名: 李占伟 学 号: 200802070055 同 组 成 员: 江经坤、史 宣 指导教师姓名: 卢春华 指导教师职称: 讲 师
2011年5月
目 录
摘 要 .................................................................... I Abstract ................................................................. II 引 言 .................................................................. III 第一章 系统方案设计 .................................................... 1 第二章 硬件设计 ......................................................... 5
2.1 控制模块 ........................................................... 5
2.1.1 AT89S52概述 ................................................. 5 2.1.2 单片机最小系统设计 .......................................... 7 2.2 温度检测反馈模块 ................................................... 8
2.2.1 DS18B20基础知识 ............................................. 8 2.2.2 温度检测电路的设计 ......................................... 11 2.3 人体检测模块 ...................................................... 11
2.3.1热释电红外传感器原理 ........................................ 11 2.3.2 人体检测电路的设计 ......................................... 12 2.4 电风扇测速模块 .................................................... 13
2.4.1 霍尔传感器简述 ............................................. 13 2.4.2 电风扇测速电路的设计 ....................................... 13 2.5 电风扇调速模块 .................................................... 14
2.5.1 电风扇调速原理 ............................................. 14 2.5.2 电风扇调速电路的设计 ....................................... 15 2.6 显示模块 .......................................................... 15
2.6.1 数码管显示原理 ............................................. 15 2.6.2 显示电路设计 ............................................... 17
I
2.7 键盘模块 .......................................................... 18
2.7.1 键盘的工作原理 ............................................. 18 2.7.2 独立式键盘的设计 ........................................... 18 2.8 计时模块 .......................................................... 19
2.8.1 AT89S52的内部定时器/计数器 ................................. 19 2.8.2 继电器控制电路的设计 ....................................... 20 2.9 状态标志模块 ...................................................... 20
2.9.1 电源指示 ................................................... 20 2.9.2 电风扇启动提示 ............................................. 21
第三章 软件设计 ........................................................ 22
3.1 温度检测子程序 .................................................... 22
3.1.1 程序流程图 ................................................. 22 3.1.2 子程序设计 ................................................. 22 3.2调速、测速子程序 ................................................... 25
3.2.1 程序流程图 ................................................. 25 3.2.2 子程序设计 ................................................. 25 3.3 显示子程序 ........................................................ 29
3.3.1 程序流程图 ................................................. 29 3.3.2 子程序设计 ................................................. 29 3.4 定时子程序 ........................................................ 31
3.4.1 程序流程图 ................................................. 31 3.4.2 子程序设计 ................................................. 32
第四章 系统测试 ........................................................ 36
4.1 测试系统的组成 .................................................... 36 4.2 测试步骤与方法 .................................................... 36
II
4.2.1 单片机最小系统 ............................................. 36 4.2.2 温度检测模块 ............................................... 36 4.2.3 人体检测模块 ............................................... 36 4.2.4 电风扇测速模块 ............................................. 36 4.2.5 电风扇调速模块 ............................................. 37 4.2.6 定时模块 ................................................... 37 4.3 整体测试 .......................................................... 37
结 论 .................................................................... 38 致 谢 .................................................................... 39 参考文献 ................................................................. 40 附 录 .................................................................... 41
附录A 元件清单 ........................................................ 41 附录B 系统原理图 ...................................................... 43 附录C 系统PCB图 ...................................................... 44 附录D 实物图 .......................................................... 45 附录E 源程序 .......................................................... 46
III
基于AT89S52的智能电风扇控制系统设计
摘 要:
本系统设计以AT89S52单片机为核心、通过温度传感器和热释电红外传感器实时采集环境信息、建立控制系统,实现当室温达到设定开启风扇的温度并且人出现在热释电红外传感器可测范围时,电风扇自动开启、以初始风力运行,当温度变化时由系统控制双向可控硅实现智能调速;人离开一段时间后则会自动关闭电风扇;当室温低于设定温度时,即使人在热释电传感器可测范围内,电风扇也处于关闭状态。 关键词:温度传感器 热释电红外传感器 双向可控硅
I
The Control System Design of Intelligent Fan Based on AT89S52
Abstract:
This system design with AT89S52 SCM as core, through the temperature sensor and pyroelectric infrared sensor real-time data acquisition environment information, establishing control system, realize when room-temperature reach a set of temperature and open fan man appeared in pyroelectric infrared sensor measurable range, electric fan automatic open, with initial wind run, When temperature changes by system control bidirectional thyristor intelligent speed ;People to leave a period of time after will shut down automatically electric fan, When the room temperature below the set temperature, even when people in pyroelectric sensor measurable range, electric fan is closed.
Key words:Temperature sensor;Pyroelectric infrared sensor;Bidirectional thyristor
II
引 言
电风扇曾一度被认为是空调产品冲击下的淘汰品,其实并非如此,市场人士称,家用电风扇并没有随着空调的普及而淡出市场,近两年反而出现了市场销售复苏的态势。其主要原因:一是电风扇和空调的降温效果不同——空调有强大的制冷功能,可以快速有效地降低环境温度,但电风扇的风更温和,更加适合老人儿童和体质较弱的人使用;二是电风扇价格低廉且相对省电,低碳环保,安装和使用都非常简单。
尽管电风扇有其市场优势,但传统电风扇还是有许多地方应当进行改良的,最突出的缺点是它不能根据温度的变化实时适量调节风力大小,对于夜间温差较大的地区,人们在夏夜使用电风扇时可能会遇到这样的问题:当凌晨降温的时候电风扇依然在工作,可是人们因为熟睡而无法察觉,既浪费资源又容易引起感冒,传统的机械定时虽然能够控制电风扇在工作一定后关闭,但定时范围有限,且无法对温度变化灵活处理;或者白天人们因事离开后而忘记关闭电风扇,长时间的工作很容易损坏电器甚至引发火灾。
鉴于以上诸多方面的考虑,我们需要设计一种实用的智能电风扇控制系统来解决和改善这些问题。
本系统设计以单片机为核心、通过温度传感器和热释电红外传感器实时采集环境信息、建立控制系统,实现当室温达到设定开启风扇的温度并且人出现在热释电红外传感器可测范围时,电风扇自动开启、以初始风力运行,当温度变化时由系统控制双向可控硅实现智能调速;人离开一段时间后则会自动关闭电风扇;人离开一段时间后则自动关闭电风扇;当室温低于设定温度时,即使人在热释电传感器可测范围内,电风扇也处于关闭状态。
III
第一章 系统方案设计
温度检测与反馈模块 人体检测模块
图1-1系统组成框图
键盘模块 控制模块 电风扇测速模块 显示模块 电风扇调速模块 计时模块 状态标志模块 1. 控制模块
方案一:单片机控制系统。以ATMEL公司生产的AT89S52单片机为核心的最小系统,配有稳压电源、复位电路、蜂鸣器、温度传感器、热释电红外传感器、霍尔传感器、显示模块、风扇调速模块等外围模块。
方案二:FPGA最小系统。采用一块Xinlinx公司生产的Spartan-3系列的XC3S200-4PQ208芯片,配有稳压电源、蜂鸣器、复位电路、温度传感器、热释电红外传感器、霍尔传感器、显示模块等外围模块。
根据题目要求,控制器主要用于各个传感器信号的接收和辨认、定时功能、显示以及各部分功能的时序分配等,综合比较实现的控制功能的简易性与可行性,同时考虑到单片机与FPGA系统的性价比,最后选择AT89S52单片机为核心的最小系统作为本设计控制系统。
2. 温度检测反馈模块
方案一:选用LM324A运算放大器,将其设计成比例控制调节器,输出电压与热敏电阻
1
的阻值成正比,再用A/D转换器将模拟信号转换为数字信号。但这种方案电路复杂、成本较高,且需要多次检测后方可使采样精确,过于烦琐。
方案二:采用DALLAS公司生产的单总线数字温度传感器DS18B20,其直接输出数字式
温度信息,方便、抗干扰性强,独特的单线接口方式,使其在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。测量温度范围为-55~+125℃,在-10~+85℃范围内,精度为±0.5℃。
综合各方面考虑,本系统采用采用更为优秀的DS18B20数字温度传感器,降低了成本和电路的复杂程度,提高了电路的运行质量。
3. 人体检测模块
为使电风扇更具人性化、智能化,遂采用热释电红外传感器,循环扫描采集人体红外
信息,以实现当室温达到设定开启风扇的温度并且人出现在热释电红外传感器可测范围时,电风扇自动开启,当人离开可测范围一段时间后关闭电风扇。
4. 电风扇测速模块
方案一:采用霍尔转速传感器A3144E。 方案二:采用电磁感应式无缘传感器。
霍尔转速传感器在稳定性、抗干扰能力、测量频率范围等方面都优于电磁感应式无源传感器,且其安装简单,实用方便,故本系统采用方案一。
5. 电风扇调速模块
方案一:抽头法。抽头调速的电动机有主绕组、中间绕组、和副绕组三种线圈,根据中间绕组的接线位置不同分为L型、T型和H型。台扇、壁扇、落地扇多采用抽头法。然而随着原材料价格的波动,造成风扇电机的绕组匝数不足,影响了低档位绕组的每伏匝数,导致调速比达不到标准要求。
方案二:电抗器法。通过串入不同感抗值的电抗器从而改变绕组每伏匝数来调速,特
点是各档速度调节容易,绕线简单,维修方便,但是却不能随心所欲的调速。
方案三:电容法。通过改变加在副绕组的电压相角关系间接改变副绕组的电压实现控
制电机绕组产生转矩的大小达到调速目的,其中主绕组时恒压,副绕组是变量。电容调速成本较低电磁噪声小,但是用寿命短且低档难启动吧,
2
方案四:电子调速。利用可控硅的半导体原理,通过改变加到双向可控硅控制极触发
脉冲的占空比来控制双向可控硅的导通时间,进而实现可能告知电机绕组的产生转矩的时间,来控制、改变风扇转速的。其风速的大小不受限制、无档次,可实现无级调速。
比较分析,方案四的无级调速更适合本系统的智能温控电风扇设计,故采用此方案。
6. 显示模块
在系统工作过程中,需要对定时时间和当前环境信息进行显示,有如下两种显示方案: 方案一:使用液晶显示屏显示时间和当前环境信息。液晶显示屏(LCD1602)具有轻薄,短小,耗电量低,无辐射危险,平面直角显示及影像稳定不闪烁,可视面积大,画面效果好,分辨率高,抗干扰能力强等特点。
方案二:使用传统的数码管显示。数码管具有低能耗、低损耗、低压、长寿命、耐老化、防晒、防潮、防火、防高(低)温的特点;对外界环境要求低,易于维护,同时其精度比较高,测量快,精确可靠,操作简单。数码管采用BCD编码显示数字,程序编译容易,资源占用较少。
综合考虑,由于液晶显示可视距离太近,故本设计方案二实现显示功能。
7. 键盘模块
方案一:采用4*4矩阵键盘。
方案二:采用独立式键盘。
由于设计中用到的按键数目不多,所以可以直接用AT89S52的通用I/O端口P1口作为键盘接口。按键只需一端经限流电阻接至+5V、另一端接P1口即可,电路简单且易于编程。故系统采用方案二。
8. 定时模块
本系统在需要时会对电风扇进行定时运行,有以下定时方案:
方案一:采用DALLAS公司生产的DS1302时钟芯片。芯片内含有一个实时时钟/日历和31字节静态RAM,采用同步串行通信,仅需用到三个口线:RES(复位)、I/O(数据)、SCLK(串行时钟),可提供秒、分、时、日、月、年的信息,每月的天数和闰年的天数可自动调整。
3
方案二:采用单片机内部定时器/计数器。本系统采用的AT89S52单片机内部含有三个
定时器/计数器,可实现精确定时/计时。其计数脉冲的频率为所选晶振频率的1/12,本系统使用的晶振频率为12MHz,则计数脉冲频率为1MHz,通过对定时器/计时器的溢出控制,可容易地实现系统所需最小单位为1s的定时/计时功能。
综合考虑,本系统采用方案二,在有效地利用系统资源的同时,又减少了单片机的外围电路。
9. 状态标志模块
状态标志模块的设计旨在系统上电工作和风扇启动时发出声光信号提示。在发光方面,考虑到电路的简易程度、功耗和电源的因素,系统采用发光二极管显示;在发声方面,考虑到体积和功耗的因素,使用蜂鸣器代替普通的扬声器。
4
第二章 硬件设计
2.1 控制模块
2.1.1 AT89S52概述 1. AT89S52 单片机简介
AT89S52 是一种带8K字节闪存可编程可擦除只读存储器(FPEROM)、256B片内RAM的低电压,高性能CMOS 8位微处理器。该器件采用ATMEL 高密度非易失存储器制造技术制造,与工业标准的MCS-51 指令集和输出管脚相兼容。由于将多功能8 位CPU 和闪烁存储器组合在单个芯片中,ATMEL 的AT89S52 是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。 2. AT89S52单片机封装类型
图2-1 AT89S52单片机双列直插封装
3. AT89S52单片机各管脚功能
VCC:接+5V电源。 GND:接地。
XTAL1:片内反向振荡放大器的输入端。当使用片内时钟时,此端接外部石英晶体和微调电容的一端;当使用外部时钟时,对于HMOS单片机,此引脚接地,对于CHMOS单片机,
5
此引脚作为外部振荡信号的输入端。
XTAL2:片内反向振荡放大器的输出端。当使用片内时钟时,此端接外部石英晶体和微调电容的另一端;当使用外部时钟时,对于HMOS单片机,此引脚接外部振荡源,对于CHMOS单片机,此引脚悬空。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8个TTL门电流。当P1口的管脚第一次写“1”时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。在FLASH 编程时,P0口作为原码输入口,当FLASH 进行校验时,P0输出原码,此时P0外部必须被拉高。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4个 TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。
此外,P1.0还作为定时器计数器
2的外部计数输入(P1.0/T2),P1.1作为定时器/计数器2的触发输入(P1.1/T2EX)。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收/输出4个TTL 门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。当P2口用于外部程序存储器或16位地址外部数据存储器进行存取时,输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口是一带内部带上拉电阻的8位双向I/O口,每脚可接收/输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。P3 口也可作为AT89S52的一些特殊功能口。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(外部数据存储器写选通);P3.7:/RD(外部数据存储器读选通)。P3口同时为闪烁编程和编程校验接收一些控制信号。
6
RST/VPD:RST是复位信号输入端,高电平有效。当单片机运行时,在此引脚加上持续时间大于2个机器周期(24个时钟振荡周期)的高电平时,即可完成复位操作。在单片机正常工作时,此引脚应为≤0.5V低电平。 VPD为此引脚第二功能,即备用电源的输入端。当主电源VCC发生故障,降低到某一规定值的低电平时,将+5V电源自动接入RST端,为内部RAM提供备用电源,以保证片内RAM中的信息不丢失,从而使单片机在复位后能继续正常运行。
ALE/PROG:ALE引脚输出为地址锁存允许信号,当单片机访问外部存储器时,用于锁存地址的低位字节。当单片机上电正常工作后,即使不访问外部锁存器,ALE端仍有正脉冲信号输出,此频率为时钟振荡器频率fosc的1/6,可用于初步判断单片机芯片的好坏。ALE端可以驱动8个LS型TTL负载。应当注意的是,当访问外部数据存储器时,在1个机器周期中ALE只出现1次,即丢失1个ALE 脉冲。因此,严格来说,不宜用ALE作精确的时钟源或定时信号。如想禁止ALE的输出可在SFR 8EH地址上置0。此时,只有在执行MOVX,MOVC指令时ALE才起作用。 作为编程输入端。
________
________
________
PROG为此引脚第二功能,在对片内EPROM型单片机编程时,
PSEN:外部程序存储器选通端,接外部程序存储器的OE(输出允许)端。在单片机访问外部程序存储器时,此引脚输出脉冲负跳沿作为读外部程序存储器的选通信号。
____
____
EA/VPP:EA为外部程序存储器选择控制端。当EA保持低电平时,单片机在此期间只访问外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。当EA 端保持高电平时,单片机在此间访问内部程序存储器,但在PC(程序计数器)值超过1FFFH时,即超出片内程序存储器的8KB地址范围时,将自动转向执行外部程序存储器内的程序。 在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。 2.1.2 单片机最小系统设计
单片机最小系统是单片机能正常工作的所必须的最基本电路,包括复位和晶体振荡电
7
____
________
路,为方便今后本系统扩展功能,所以最小系统采用双排针单独引出I/O口的方式,其电路设计如图2-2所示。
图2-2 最小系统设计电路
2.2 温度检测反馈模块
2.2.1 DS18B20基础知识
DS18B20单线数字温度传感器是DALLAS半导体公司开发的世界上第一片支持“一线总线”接口的温度传感器。它具有3引脚TO-92小体积封装形式。温度测量范围为-55℃~+125℃,可编程为9~12位A/D 转换精度,测温分辨率可达0.0625℃。被测温度用符号扩展的16 位数字量方式串行输出。工作电压支持3V~5.5V的电压范围,既可在远端引入,也可采用寄生电源方式产生。DS18B20还支持“一线总线”接口,多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与诸多DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。它还有存储用户定义报警温度等功能。
DS18B20 内部结构及管脚:
DS18B20内部结构如图2-3所示,主要由4部分组成:64位ROM、温度传感器、非挥发的温度报警触发器TH 和TL、配置寄存器。其管脚排列如图2-4所示,DQ为数字信号输入/输出端,GND为电源地,VDD为外接供电电源输入端,采用寄生电源方式时,该引脚接地。
8
DQ
VDD 64位 ROM 和 电源检单线 接口 存储器和控制器 温度灵敏元件 低温触发器TL 高温触发器TH 配置寄存器 8位CRC生成器 高速缓存 存储器 GND 测
图2-3 DS18B20 内部结构
图2-4 DS18B20外形及管脚
由于DS18B20只有一根数据线,因此它和主机(单片机)通信是需要串行通信,而AT89S52有两个串行端口,所以可以不用软件来模拟实现。经过单线接口访问DS18B20必须遵循如下协议:初始化、ROM操作命令、存储器操作命令和控制操作。要使传感器工作,一切处理均从序列开始。
主机发送(Tx)--复位脉冲(最短为480μs的低电平信号)。接着主机便释放此线并进入接收方式(Rx)。总线经过4.7K的上拉电阻被拉至高电平状态。在检测到I/O引脚上的上升沿之后,DS18B20等待15-60μs,并且接着发送脉冲(60-240μs的低电平信号)。然后以存在复位脉冲表示DS18B20已经准备好发送或接收,然后给出正确的ROM命令和存储操作命令的数据。DS18B20通过使用时间片来读出和写入数据,时间片用于处理数据位和进行何种指定操作的命令。它有写时间片和读时间片两种。
写时间片:当主机把数据线从逻辑高电平拉至逻辑低电平时,产生写时间片。有两种
9
类型的写时间片:写1时间片和写0时间片。所有时间片必须有60微秒的持续期,在各写周期之间必须有最短为1微秒的恢复时间。
读时间片:从DS18B20读数据时,使用读时间片。当主机把数据线从逻辑高电平拉至逻辑低电平时产生读时间片。数据线在逻辑低电平必须保持至少1微秒;来自DS18B20的输出数据在时间下降沿之后的15微秒内有效。为了读出从读时间片开始算起15微秒的状态,主机必须停止把引脚驱动拉至低电平。在时间片结束时,I/O引脚经过外部的上拉电阻拉回高电平,所有读时间片的最短持续期为60微秒,包括两个读周期间至少1μs的恢复时间。
一旦主机检测到DS18B20的存在,它便可以发送一个器件ROM操作命令。所有ROM操作命令均为8位长。
DS18B20芯片功能命令表如下:
表2-1 DS18B20功能命令表
命令 功能描述 命令代码 CONVERT 开始温度转换 44H READ SCRATCHPAD 读温度寄存器(共9字节) BEH READ ROM 读DS18B20序列号 33H WRITE SCRATCHPAD 将警报温度值写如暂存器第2、3字节 4EH MATCH ROM 匹配ROM 55H SEARCH ROM 搜索ROM F0H ALARM SEARCH 警报搜索 ECH SKIP ROM 跳过读序列号的操作 CCH READ POWER SUPPLY 读电源供电方式:0为寄生电源,1为外电源 B4H
DS18B20是用12位存储温度,最高位为符号位,下表为它的温度存储方式:
10
表2-1 DS18B20温度存储地址分配
2^3 2^2 Bit6 S Bit14 2^1 Bit5 S Bit13 2^0 Bit4 S Bit12 2^-1 Bit3 S Bit11 2^-2 Bit2 2^6 Bit10 2^-3 Bit1 2^5 Bit9 2^-4 Bit0 2^4 Bit8 LSBYTE Bit7 S MSBYTE Bit15 这是12位转化后得到的12位数据,存储在DS18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。 2.2.2 温度检测电路的设计
DS18B20为单总线数字温度传感器,其与单片机的连接很简单,电路如图2-5所示。
图2-5 DS18B20温度检测电路
2.3 人体检测模块
2.3.1热释电红外传感器原理
人体热释电红外检测模块是一种能够感应人体靠近或远离的传感器,模块将对人体的人体红外热辐射的信号转化成电信号,人体都有恒定的体温,一般在37℃左右,会辐射出中心波长为9~10um的特定红外线,而探测元件的波长灵敏度在0.2~20um范围内几乎稳定不变。在传感器顶端开设了一个装有菲涅尔透镜的窗口,可通过光的波长范围为7~10um,正好适合于人体红外辐射的探测,这样便形成了一种专门用作探测人体辐射的红外线传感器。
人体热释电红外检测模块的菲涅尔透镜将热释电红外信号折射在PIR(热释电红外传感器)上,探测区域内红外线能量的变化,由PIR将其转换成电信号,即热电转换。实质上热释电红外传感器是对温度敏感的传感器。它由陶瓷氧化物或压电晶体元件组成,在元件两个表面做成电极。在环境温度有ΔT的变化时,由于有热释电效应,在两个电极上会
11
产生电荷ΔQ,即在两电极之间产生微弱的电压ΔV。
因此在被动红外探测器的可测范围内,当无人体移动时,热释电红外感应器感应到的只是背景温度,当人体进入探测区时,通过菲涅尔透镜,热释电红外感应器感应到的是人体温度与背景温度的差异,信号被采集到伺服系统以后,由软件对新采集的数据与系统内存中已经存在的前期探测数据进行延时比较,以判断是否真的有人等红外线源进入探测区。
本系统采用的市售人体热释电红外采集模块,外形如图2-6所示。内部集成了热释电红外传感器和红外传感信号处理器BISS0001。有VCC(+5V)、OUT和GND三个引脚。模块上电后,当有人进入探测区域时,其信号端口便产生一个电平跳变,并维持数秒钟,我们就是利用这个跳变来判断是否有人在可测区内。 2.3.2 人体检测电路的设计
本系统采用的市售人体热释电红外采集模块,有VCC(+5V)、OUT和GND三个引脚,接入电路如图2-7所示。
模块上电后,当有人进入探测区域时,其信号端口便产生一个电平跳变,并维持数秒钟,我们就是利用这个跳变来判断是否有人在可测区内。
图2-6 人体热释电红外采集模块外形图
图2-7 人体热释电红外检测电路
12
2.4 电风扇测速模块
2.4.1 霍尔传感器简述
根据霍尔效应,人们用半导体材料制成的元件叫霍尔元件。它具有对磁场敏感、结构简单、体积小、频率响应宽、输出电压变化大和使用寿命长等优点,因此,在测量、自动化、计算机和信息技术等领域得到广泛的应用。
霍尔传感器A3144是Allegro MicroSystems公司生产的宽温、开关型霍尔效应传感器,其工作温度范围可达-40℃~150℃。它由电压调整电路、反相电源保护电路、霍尔元件、温度补偿电路、微信号放大器、施密特触发器和OC门输出极构成,通过使用上拉电阻可以将其输出接入CMOS逻辑电路。其输入为磁感应强度,输出是一个数字电压讯号。该芯片具有尺寸小、稳定性好、灵敏度高等特点,有两种封装形式,一种是3脚贴片微小型封装,后缀为“LH”;另一种是3脚直插式封装,后缀为“UA”。
霍尔传感器的外形图和管脚图如图2-8所示。磁场由磁钢提供,所以霍尔传感器和磁钢需要配对使用。
霍尔元件和磁钢 管脚图
图2-8 霍尔传感器的外形图
2.4.2 电风扇测速电路的设计
转速的测量方法很多,根据脉冲计数来实现转速测量的方法主要有M法(测频法)、T法(测周期法)和MPT法(频率周期法),该系统采用了M法(测频法)。由于转速是以单位时间内转数来衡量,在变换过程中多数是有规律的重复运动实际测量时,要把霍尔传感器固定在电风扇后的隔离架上,与霍尔探头相对的电风扇的扇叶边沿固定一块磁钢,电风扇每转一周,受磁钢所产生的磁场的影响,霍尔传感器便发出一个脉冲信号,其频率和转速成
13
正比。将此脉冲信号接到AT89S52单片机的P3.2[INT0]上,设定T0定时,每分钟所计的进入P3.2的脉冲个数即为电机的转速。
霍尔传感器为输出端开路元件,所以需外接上拉电阻,其电路如图2-9所示。
图2-9 霍尔测速电路
2.5 电风扇调速模块
2.5.1 电风扇调速原理
电风扇调速是整个控制系统中的一个重要的方面。电风扇的调速方法有很多种,如抽头法、电抗器法、电容法、电子调速法等。
本系统采用电子调速法。通过控制双向可控硅的导通时间,使输出端电压发生改变,从而使施加在电风扇的输入电压发生改变,以调节风扇的转速,实现各档位风速的无级调速。
可控硅的导通条件如下: 1)阳-阴极间加正向电压;
2)控制极-阴极间加正向触发电压;
3)阳极电流IA 大于可控硅的最小维持电流IH。
本系统采用了过零双向可控硅型光耦MOC3041,集光电隔离、过零检测、过零触发等功能于一身,避免了输入输出通道同时控制双向可控硅触发的缺陷, 简化了输出通道隔离驱动电路的结构。其工作原理是:单片机根据响应的参数设置, 在单片机的P1.7口输出一个低电平,使光电耦合器导通, 同时触发双向可控硅, 使工作电路导通工作。给定时间内,负载得到的功率为:
14
PnUIN (2-1)
式中: P 为负载得到的功率/kW; n 为给定时间内可控硅导通的正弦波个数; N 为给定时间内交流正弦波的总个数; U 为可控硅在一个电源周期全导通时所对应的电压有效值/V; I 为可控硅在一个电源周期全导通时所对应的电流有效值/A。由式(2-1)可知,当U, I, N为定值时,只要改变n值的大小即可控制功率的输出,从而达到调节电机转速的目的。 2.5.2 电风扇调速电路的设计
本体统所设计的可控硅触发电路如图2-10所示。
图2-10 电风扇调速电路
2.6 显示模块
2.6.1 数码管显示原理
常用的数码管为8段式,其每一段对应一个发光而二极管,分为共阳极和共阴极两种。如图2-11所示为共阴极数码管内部结构。其所有二极管阴极连在一起并接地,当某个发光二极管的阳极为高电平时,此发光二极管被点亮,相应的段被显示。同样,共阳极数码管则是所有阳极相连并接高电平,当某个发光二极管的阴极为低电平时,即被点亮,相应的段被显示。将每段按一定的顺序分别命名为a、b、c、d、e、f、g、dp,为其提供刚好一个字节的不同的段码(即字型码)即可控制数码管相应的段被点亮显示出不同的字型。
15
图2-11 共阴极数码管结构
由N个数码管按一定的方式连在一11起即可形成一个N位的数码管,也分为共阳极和共阴极,其显示方式可分为静态显示和动态显示。如图2-12所示为4位数码管的构成。
图2-12 4位数码管结构
N位数码管工作于静态显示方式时,各个数码管的共阴极(或共阳极)连在一起并接地(或接+5V),各个段选端分别连接不同的8位I/O口或经不同的锁存器与I/O口相连。各个数码管的显示字符已经确定则将维持不变,指导送入另一个字符的段码为止,在同一时间里,每一位显示的字符可以各不相同,因此,静态显示的亮度都较高。这种显示方式编程容易,但占用I/O口或锁存器较多,随着显示位数的增多,资源浪费将会更严重。因此,在显示位数较多的情况下,一般不采用静态显示,而是采用动态显示。
N位数码管动态显示时,其所有的段选端都连在一起,有1个8位I/O口控制,形成段码线的多路复用,而各位的共阳极(或共阴极)也即位选端则由不同的I/O线控制,形成各位的分时选通。因此,在同一时刻,如果各位的位选端都处于选通状态,则各个数码管将显示相同的字符。若要各位都够同时显示出与本位相应的显示字符,就必须采用动态
16
显示,即在某一时刻,只让某一位的位选端处于选通状态,而其他各位都不选通,同时段码线上输出相应位要显示的字符的段码;在下一时刻只让下一位的位选端处于选通状态,在段码线上再输出其要显示的字符的段码。如此循环下去,只要每位显示的间隔时间足够短,利用发光二极管的余晖效应和人眼的视觉暂留作用,就可以造成多位同时亮的假象,达到同时显示不同字符的效果。这种显示方式节省硬件资源,但占用CPU时间较多,适于显示位数较多的情况。 2.6.2 显示电路设计
本系统采用4位共阳极数码管动态显示的方案以节省硬件资源,降低电路复杂度。设计电路如图2-13所示。
图2-13 4位数码管动态显示连接电路
单片机的P0口输出段选码,其位选端经过4个9012 PNP三极管驱动与电源端Vcc相连,而9012的通断则通过编程对P2.4~P2.7输出高低电平来控制。其中,当某位输出为低电平时对应的与之连接那个9015导通,当单片机输出段选码时,对应的那位数码管就会显示相应的段码的内容,当P2.4~P2.7轮流不断的输出低电平,并且P0口在不同的位选中时输出段码时,4位数码管就会轮流显示不同的值,如果扫描时间足够的短,那么利
17
用其余晖和我们的视觉暂留效应,就会看到4位数码管同时在发亮而且在显示不同的内容。
2.7 键盘模块
2.7.1 键盘的工作原理
键盘在单片机应用系统中能实现向单片机输入数据、传送命令等功能,是人工干预单片机工作的主要手段,可分为独立式键盘和行列式(矩阵)键盘。
独立式键盘就是各按键相互独立,每个按键各接一根输入线,通过检测输入线上电平的状态就可以很容易地判断出哪个键被按下。易识别且编程简单,但在按键数目较多时,独立式键盘就需要较多的输入口线且电路结构复杂。故此种键盘适用于按键较少或操作速度较高的场合。
行列式(矩阵)键盘用于按键较多的场合,有行线和列线组成,按键位于行、列的交叉点上。最常用的4*4的行、列结构的键盘即可提供16个按键,与独立式键盘相比可节约大量I/O口线。行列式键盘中行、列为多键共用,各按键均影响该键所在行和列的电平,因此各按键彼此将相互发生影响,所以必须将行、列信号配合起来并作适当处理,才能确定按下键的位置。 2.7.2 独立式键盘的设计
由于本系统为智能化设计,需要的按键数目很少,所以系统采用简单的独立式键盘,与单片机的P1口相连,电路如图2-14所示。
图2-14 独立式键盘电路
18
2.8 计时模块
2.8.1 AT89S52的内部定时器/计数器
一.定时器/计数器
AT89S52单片机内部有三个16位的可编程定时器/计数器,定时器0(T0) 、定时器1(T1)和定时器2(T2),可编程选择其作为定时器或计数器使用。此外,工作方式、定时时间、计数值、启动、中断请求等都可以由程序设定。
定时/计数器由定时器0、定时器1、定时器方式寄存器TMOD和定时器控制寄存器TCON组成。
定时器0,定时器1是16位加法计数器,分别由两个8位专用寄存器组成:定时器0由TH0和TL0组成,定时器1由TH1和TL1组成。TL0、TL1、TH0、TH1的访问地址依次为8AH8DH,每个寄存器均可单独访问。定时器0或定时器1用作计数器时,对芯片引脚T0(P3.4)或T1(P3.5)上输入的脉冲计数,每输入一个脉冲,加法计数器加1;其用作定时器时,对内部机器周期脉冲计数,由于机器周期是定值,故计数值确定时,时间也随之确定。
TMOD、TCON与定时器0、定时器1间通过内部总线及逻辑电路连接,TMOD用于设置定时器的工作方式,TCON用于控制定时器的启动与停止。
二.定时器/计数器的初始化
由于定时/计数器的功能是由软件编程确定的,所以,一般在使用定时器/计数前都要对其进行初始化。初始化骤如下:
(1)确定工作方式——对TMOD或T2MOD赋值。
(2)预置定时或计数的初值——直接将初值写入TH0、TL0或TH1、TL1或TH2、TL2。 定时/计数器的初值因工作方式的不同而不同。设最大计数值为M,则各种工作方式下的M值如下:
方式0:M=213=8192
19
方式1:M=2=65536 方式2:M=28=256
方式3:定时器0分成两个8位计数器,所以两个定时器的M值均为256。
因定时/计数器工作的实质是做“加1”计数,所以,当最大计数值M值已知时,初值X可计算如下:
X=M计数值
(3)根据需要开启定时/计数器中断——直接对IE寄存器赋值。 (4)启动定时/计数器工作——将TR0或TR1置“1”。
GATE=0时,直接由软件置位启动;GATE=1时,除软件置位外,还必须在外中
断引脚处加上相应的电平值才能启动。 2.8.2 继电器控制电路的设计
本系统中由单片机内部定时器T2设置定时时间,由继电器做开关控制电路。当定时时间到时,单片机即控制继电器切断风扇电机的电源,风扇停止转动。继电器控制电路的设计如图2-15所示。
16
图2-15 继电器控制电风扇开断电路
2.9 状态标志模块
2.9.1 电源指示
当电风扇从手动模式调至智能模式时,系统上电,采用发光二极管作为提示,说明切
20
换模式成功。其电路设计如图2-16所示。
图2-16 电源指示灯
2.9.2 电风扇启动提示
当环境达到开启温度且人在探测范围内时,单片机控制电风扇开始以初始速度运行,
并由蜂鸣器发声以提示电风扇启动成功。其电路如图2-17所示。
图2-17 电风扇启动发声电路
21
第三章 软件设计
3.1 温度检测子程序
3.1.1 程序流程图
开始
DS18B20初始化
初始化成功 N Y
读一个字节
写一个字节 读取并显示程序 结束 图3-1 温度检测模块流程图
3.1.2 子程序设计
#include sbit DQ = P3^0; //定义18B20端口DQ sbit wei1 =P2^4; sbit wei2 =P2^5; sbit wei3 =P2^6; sbit wei4 =P2^7; unsigned char code LEDData1 [ ] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};//0-9数字 unsigned char code LEDData2 [ ] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //0-9带点数字 22 unsigned char T; //定义变量保存当前温度值 /////////////////////////////////////////////////// void Delay(unsigned int time)//延时函数 { while( time-- ); } /////////////////////////////////////////////////// Init_18B20()//初始化18B20 { unsigned char x = 0; DQ = 1; //DQ复位 Delay(10); //稍做延时 DQ = 0; //单片机将DQ拉低 Delay(80); //延时大于480us DQ = 1; //拉高总线 Delay(10); Delay(20); x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败} /////////////////////////////////////////////////// unsigned char ReadOneChar()//读一个字节 { 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(15); } return (dat); } /////////////////////////////////////////////////// void WriteOneChar(unsigned char dat)//写一个字节 { unsigned char i = 0; for (i = 8; i > 0; i--) { DQ = 0; DQ = dat&0x01; Delay(5); DQ = 1; } dat>>=1; } 23 /////////////////////////////////////////////////// void Read_Display()//读取并显示温度 { unsigned int a = 0, b = 0, c = 0, t = 0; float tt = 0; Init_18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 Init_18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器 a = ReadOneChar(); b = ReadOneChar(); t = b; t <<= 8; t = t | a; tt = t * 0.0625; t = tt * 10 + 0.5; //放大10倍输出并四舍五入 T = t / 10; //保存当前温度 a = t / 100; //十位 b = t / 10 - a * 10; //个位 c = t - a * 100 - b * 10; //小数位 P0 = 0xc6; //显示\"C\"字符 wei1 = 0; Delay(100); wei1 = 1; P0 = LEDData1[c]; //显示小数位 wei2 = 0; Delay(100); wei2 = 1; P0 = LEDData2[b]; //显示个位 wei3 = 0; Delay(100); wei3 = 1; P0 = LEDData1[a]; //显示十位 wei4 = 0; Delay(100); wei4 = 1; } /////////////////////////////////////////////////// void main() { wei1=1;wei2=1;wei3=1;wei4=1; while(1) { } Read_Display(); } /////////////////////////////////////////////////// 24 3.2调速、测速子程序 3.2.1 程序流程图 开始 初始化计时器T0,T1,外部中断INT0 启动定时器 风扇转动一圈, INT0 产生一 根据温度变化,调节定时器初 次中断 值,以调节PWM占空比 10s内中断的次数乘以6,即 平均转速 PWM控制可控硅导通时间以 调节有效电压,使转速变化 显示转速 结束 图3-2 调速、测速模块程序流程图 3.2.2 子程序设计 #include /////////////////////////////////////////////////////// //宏定义 #define uchar unsigned char #define uint unsigned int #define ulong unsigned long int #define HI_T0 (65536-10000)/256 //给定时器T0高8位赋值,定时10ms #define LO_T0 (65536-10000)/256 //给定时器T0低8位赋值 #define HI_T1 (65536-10000)/256 //给定时器T1高8位赋值 #define LO_T1 (65536-10000)/256 //给定时器T1低8位赋值 ////////////////////////////////////////////////////// //位定义 sbit wei1=P2^0;//位定义数码管用到的片选,高电平有效 sbit wei2=P2^1; sbit wei3=P2^2; sbit wei4=P2^3; sbit wei5=P2^4; sbit wei6=P3^3; 25 sbit K1 = P1^0; //位定义 sbit PWM = P3^7; //sbit buzzer=P3^7; //sbit cesu=P3^2; sbit su=P3^6; ///////////////////////////////////////////////////// //定义全局变量 uint M=2; //T0中断次数,M*10ms即输出低定平维持时间 uint N=2; //T1中断次数,20ms,即输出高电平维持时间 ulong M_V=1000; //定时10s,用于测取10s内风扇平均速度 ulong V,VV; // uchar code SEG_TAB[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};//共阳极数码管0-9数字段码 uchar code SEG_TAB_1[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};//共阳极数码管0-9带点数字段码 /////////////////////////////////////////////////////////// //函数提前声明 void init_wei(void); //初始化位选 void show(uchar date,uchar wei); //在哪一个(wei)数码管上显示什么数据(date) void disp_v (void); //速度显示函数 /////////////////////////////////////////////////////////// void delay(uint x) //延时子函数,延时约 x ms { uint i,j; for(i=x;i>0;i--) for(j=120;j>0;j--); } /////////////////////////////////////////////////////////// void EX_int0Init(void) //初始化外部中断0 { IT0=0; //设置外部中断0为电平触发方式 EX0=1; //INT0中断开 EA=1; //总中断开 } /////////////////////////////////////////////////////////// void Timer0Init(void) //初始化定时器0程序 { TMOD = 0x01; //设置定时器0 工作方式1 TH0=HI_T0; //高位赋初值 TL0=LO_T0; //低位赋初值 TR0 = 1; //启动定时器0 ET0 = 1; //定时器0中断开 EA = 1; //总中断开 } /////////////////////////////////////////////////////////// void Timer1Init(void) //初始化定时器1程序 { TMOD = 0x01; //设置定时器1 工作方式1 TH1=HI_T1; //高位赋初值 TL1=LO_T1; //低位赋初值 ET1 = 1; //定时器1中断开 EA = 1; //总中断开 } /////////////////////////////////////////////////////////// 26 void main() { EX_int0Init(); Timer0Init(); Timer1Init(); while(1) { if(K1==0) { delay(10); if(K1==0) { M += 2; if(M==198) { M=2; } while(!K1); } } disp_v(); //显示速度 } } //////////////////////////////////////////////////////// void EX_int0(void) interrupt 0 //INT0中断服务程序 { V++; } //////////////////////////////////////////////////////// void Timer0(void) interrupt 1 //定时器0中断服务程序 { static uchar count0; // static ulong count00; TH0=HI_T0; //高位重装初值 TL0=LO_T0; //低位重装初值 PWM=0; count0++; count00++; if(count00==M_V)//10s时间到 { count00=0; VV=V*6; V=0; su=~su; } if (count0==M) { count0=0; TR1=1; //启动定时器1,输出高定平 PWM=1; //TR0=0; } } /////////////////////////////////////////////////////// void Timer1(void) interrupt 3 //定时器1中断服务程序 { 27 static uchar count1; // TH0=HI_T0; //高位重装初值 TL0=LO_T0; //低位重装初值 PWM=1; count1++; if (count1==N) { count1=0; //TR0=1; //启动定时器0,输出低定平 PWM=0; TR1=0; } } //////////////////////////////////////////////////////// void disp_v (void) //速度显示函数 { uchar a,b,c,d; a=VV/1000; //速度的千位 b=VV%1000/100; //速度的百位 c=VV%100/10; //速度的十位 d=VV%10; //速度的个位 init_wei(); //显示速度个位 show(d,1); delay(5); init_wei(); //显示速度十位 show(c,2); delay(5); init_wei(); //显示速度百位 show(b,3); delay(5); init_wei(); //显示速度千位 show(a,4); delay(5); } void init_wei(void) //初始化位选 { wei1=0;wei2=0;wei3=0;wei4=0;wei5=0;wei6=0; } void show(uchar date,uchar wei)//在哪一个(wei)数码管上显示什么数据(date) { P0=SEG_TAB[date]; switch(wei) { case 1:wei1=1;wei2=0;wei3=0;wei4=0;wei5=0;wei6=0;break; case 2:wei1=0;wei2=1;wei3=0;wei4=0;wei5=0;wei6=0;break; case 3:wei1=0;wei2=0;wei3=1;wei4=0;wei5=0;wei6=0;break; case 4:wei1=0;wei2=0;wei3=0;wei4=1;wei5=0;wei6=0;break; case 5:wei1=0;wei2=0;wei3=0;wei4=0;wei5=1;wei6=0;break; case 6:wei1=0;wei2=0;wei3=0;wei4=0;wei5=0;wei6=1;break; } } ///////////////////////////////////////////////////////////// 28 3.3 显示子程序 3.3.1 程序流程图 开始 初始化 送段码“ 1 ”,选通第一位数码管 延时约 5毫秒 送段码“ 2 ”,选通第二位数码管 延时约5毫秒 送段码“3”,选通第三位数码管 延时约 5毫秒 送段码“ 4” ,选通第四位数码管 延时约 5毫秒 结束 图3-3 显示模块流程图 3.3.2 子程序设计 #include #define uchar unsigned char #define uint unsigned int sbit wei1=P2^4; sbit wei2=P2^5; sbit wei3=P2^6; 29 sbit wei4=P2^7; /////////////////////////////////////////////////// void delay(uint x) { uint i,j; for(i=x;i>0;i--) for(j=120;j>0;j--); } ////////////////////////////////////////////////// void LEDdisplay(uchar numb,uchar wei)//显示子函数 { switch(numb) { case 0:P0=0xC0;break; case 1:P0=0xF9;break; case 2:P0=0xA4;break; case 3:P0=0xB0;break; case 4:P0=0x99;break; case 5:P0=0x92;break; case 6:P0=0x82;break; case 7:P0=0xF8;break; case 8:P0=0x80;break; case 9:P0=0x90;break; } switch(wei) { case 1:wei1=0;wei2=1;wei3=1;wei4=1;break; case 2:wei1=1;wei2=0;wei3=1;wei4=1;break; case 3:wei1=1;wei2=1;wei3=0;wei4=1;break; case 4:wei1=1;wei2=1;wei3=1;wei4=0;break; } } ////////////////////////////////////////////////// void main(void) { while(1)//动态显示 { LEDdisplay(1,1);delay(5); LEDdisplay(2,2);delay(5); LEDdisplay(3,3);delay(5); LEDdisplay(4,4);delay(5); } } 30 3.4 定时子程序 3.4.1 程序流程图 开始 初始化 初始化定时器 T0 ,定时 50ms 启动T0 Y 定时时间为 0 N 中断 20 次, 1s时间到,秒减 1 秒减至 0 定时时间为 N 0 Y N 分减1,秒赋值59 分减至 0 Y 定时时间为 0 N 小时减 1,分赋值 59 小时减至0 定时时间到,控制继电器切断电源 图3-4 定时模块程序流程图 31 3.4.2 子程序设计 ************************************************** 函 数 名: 倒计时器 器件参数: AT89S52 ,12.000MHZ 功能说明: K0启动/关闭风扇定时器 k1暂停/继续计时 k2分加1 k3分减1 *************************************************/ ////////////////////////////////////////////////// #include #define uchar unsigned char //宏定义 #define uint unsigned int #define _TH0_TL0_ (65536 - 50000) #define HI (_TH0_TL0_ / 256) //给高8位赋值 #define LO (_TH0_TL0_ % 256) //给低8位赋值 #define M 20 //(1000/50)1秒要20个中断的累计 sbit relay=P2^2; //位定义继电器端口 sbit buzzer=P2^3; //位定义蜂鸣器端口 sbit wei1=P2^4; //位定义数码管位选通端 sbit wei2=P2^5; sbit wei3=P2^6; sbit wei4=P2^7; sbit K0=P1^4; //位定义按键 sbit k1=P1^0; sbit k2=P1^1; sbit k3=P1^2; void key(); //函数声明 void Disp(); uchar hour = 0, min = 1, sec = 5; //初始化时分秒的值 uchar code SEG_TAB[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};//共阳极数码管0-9数字段码 /////////////////////////////////////////////////// void delay(uint x) //延时子函数,延时x ms { uint i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } ////////////////////////////////////////////////// void Timer0Init(void) //初始化定时器0程序 { TMOD = 0x01; //设置模式1 定时器0 工作方式0 TH0 = HI; //给TH0,TL0赋初始值 TL0 = LO; 32 TR0 = 1; //启动定时器0 ET0 = 1; //定时器0中断开 EA = 1; //总中断开 } //////////////////////////////////////////////////////// void main()//主函数 { Timer0Init();//初始化定时器0 relay=1; buzzer=1; while(1) { key();//手动调整时间 Disp();//显示时间 } } ////////////////////////////////////////////////////////////////////////////////////////// void IsrTimer0(void) interrupt 1 //定时器0中断服务程序 { static uchar count = 0; //定义静态变量count TR0 = 0; //以下调整出栈入栈的时间误差 TL0 += (_TH0_TL0_ + 9) % 256; TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY; TR0 = 1; if(K0==0) //启动风扇定时器功能 { count++; if(sec || min || hour !=0) //时间不为零 {if(count==M) //中断20次,1秒时间到 { count=0; //重新复位count变量 if(sec--==0) //当秒减至零时,1分钟时间到 { if(min || hour !=0) //所剩时间大于1分钟 { sec=59; //秒赋值59 if(min--==0) //分减至零时, { if(hour !=0) //所剩时间大于1小时 { min=59; //分赋值59 hour--; } } } } } } else //时间为零,定时时间到,风扇停止 33 { buzzer=0; //sec=min=hour=0; } } else //关闭风扇定时器 { hour = 0, min = 1, sec = 5; //初始化时分秒的值 } } /////////////////////////////////////////////////////////////////////////////////////////// void key() //按键调整倒计时时间 { if(k1==0) //k1 启动/停止计时 { delay(10); if(k1==0) { TR0=~TR0; while(!k1); } } if(k2==0) //k2 每按下一次分钟加1 { delay(10); if(k2==0) { min++; if(min==60) { min=0; if(hour++==23){hour=0;} } while(!k2); } } if(k3==0) //k3 每按下一次分钟减1 { delay(10); if(k3==0) { if(min--==0) { min=59; if(hour--==0) { hour=0; min=0; } } while(!k3); } } } ///////////////////////////////////////////////////////////////////////////// void Disp()//数码管显示 { 34 /******************************************* wei4 = 0;//第4个数码管显示时的十位 P0 = SEG_TAB[ hour / 10 ]; delay(5); wei4 = 1; wei3 = 0;//第3个数码管显示时的个位 P0 = SEG_TAB[ hour % 10 ]&0x7F; delay(5); wei3 = 1; wei2 = 0;//第2个数码管显示分的十位 P0 = SEG_TAB[ min / 10 ]; delay(5); wei2 = 1; wei1 = 0;//第1个数码管显示分的个位 P0 =SEG_TAB[ min % 10 ]&0x7F; delay(5); wei1 = 1; ***********************************************/ if(K0==0) //当启动定时器时才显示倒计时 { wei4 = 0;//第4个数码管显示分的十位 P0 = SEG_TAB[ min / 10 ]; delay(5); wei4 = 1; wei3 = 0;//第3个数码管显示分的个位 P0 =SEG_TAB[ min % 10 ]&0x7F; delay(5); wei3 = 1; wei2 = 0;//第2个数码管显示秒的十位 P0 = SEG_TAB[ sec / 10 ]; delay(5); wei2 = 1; wei1 = 0;//第1个数码管显示秒的各位 P0 = SEG_TAB[ sec % 10 ]; delay(5); wei1 = 1; } } ///////////////////////////////////////////////////////////////////////////// 35 第四章 系统测试 4.1 测试系统的组成 1) 单片机最小系统 2) 温度检测反馈模块 3) 人体检测模块 4) 电风扇测速模块 5) 电风扇调速模块 6) 定时模块 4.2 测试步骤与方法 4.2.1 单片机最小系统 当单片机上电正常工作后,其ALE引脚不断输出频率为时钟振荡器频率fosc 1/6的正 脉冲信号,可用于初步检测芯片质量。因此,可用示波器查看ALE端的输出信号,来简单判断单片机的好坏。 4.2.2 温度检测模块 按要求连接好硬件电路,把该模块子程序写入控制器,系统可检测环境温度、并在数 码管上显示。分别用装有冰水和热水的杯子放在DS18B20上,以模拟环境温度的变化,观察到数码管上显示的温度值也随着变化,说明温度检测模块功能基本实现。 4.2.3 人体检测模块 按要求连接好硬件电路,把该模块子程序写入控制器,用蜂鸣器和发光二极管模拟检 测到人体时状态的变化。可观察到当人未进入热释电红外探测范围内时,发光二极管不亮、蜂鸣器不响;当人进入其探测范围内时,发光二极管亮、蜂鸣器鸣响。说明人体检测模块功能基本实现。 4.2.4 电风扇测速模块 按要求连接好硬件电路,把该模块子程序写入控制器,把磁钢固定在风扇一扇叶的边 36 缘处,把霍尔传感器固定在与磁钢相对应处。随着风扇转动,可观察到数码管上显示出风扇转速值,说明测速模块功能基本实现。 4.2.5 电风扇调速模块 按要求连接好硬件电路,把该模块子程序写入控制器,分别用装有凉水和热水的杯子 放在DS18B20上,模拟环境温度变化,可观察到风扇转速随温度而变化,温度升高转速增大,温度降低转速减小,基本实现无级调速。 4.2.6 定时模块 按要求连接好硬件电路,把该模块子程序写入控制器,可在数码管上观察到倒计时秒 表,按键K0可继续/暂停定时器,按键K1可使定时时间增加1分钟,按键K2可使定时时间减1分钟。 4.3 整体测试 连接好系统硬件电路,把系统综合源程序写入控制器,经测试,各模块均能正常运行, 基本实现系统所要求的功能。 37 结 论 经过一段时间的不懈努力,本系统设计工作已然就绪,基本达到了所预期的要求和效果。但由于自身水平有限及一些客观因素,本设计仍存在很多不足和待改进之处。例如热释电红外传感器容易受各种光源、热源干扰,红外线穿透力较差、容易被遮挡,环境温度和人体温接近时、探测灵敏度明显下降。预想亦可为电风扇加上小车底座,通过红外或无线遥控,控制电风扇的自由移动,以更满足人性化需求。 通过这次毕业设计,检验了大学三年的学习成果,但同时,也使我深刻地认识到自身存在的不足和知识点的严重欠缺,认识到学好专业知识的重要性,也理解了理论联系实际的含义和重要性。虽然在这次设计中对于知识的运用和衔接还不够熟练,但是我将在以后的工作和学习中继续努力、不断完善。 38 致 谢 籍此论文结束之际,我要向我所有的良师益友表以深深的谢意。 首先要感谢我的指导老师——卢春华老师。在本系统的方案设计、整体制作和调试及本论文的谋篇布局、编写、修改等方面卢老师都给了我甚多的宝贵指导和建议,才能使我顺利完成此次设计。 同时,卢老师严谨的治学理念和一丝不苟的工作态度也深深地感染和启发了我,对我今后的人生之旅也会有莫大的帮助。 其次,我要感谢我的合作伙伴史宣和江经坤,是我们的共同不懈努力才有今天的成绩。感谢我的同学郑瑞杰、逯亚峰,在电机控制和系统调试等方面无私地予我帮助。 再次,我要感谢我生活学习了三年的母校——安阳学院,感谢我的学院——电子信息与电气工程学院。给了我一个宽阔的学习平台,让我在三年的时间里不断地汲取新知,不断地充实和提高自我。感谢我身边曾给予我帮助的每一位老师、同学和朋友。 最后,我要以感恩的心再一次感谢我认识的每一个人,是你们让我的人生变得更加丰富精彩! 在此,请允许我深深地鞠一个躬,谢谢!谢谢你们! 39 参考文献 [1] 彭伟.单片机C语言程序设计实训100例[M].北京:电子工业出版社.2009 [2] 张毅刚.单片机原理及应用[M].北京:高等教育出版社.2003 [3] 侯玉宝、陈忠平、李成群等.基于Proteus的51系列单片机设计与仿真[M].北京:电子工业出版 社.2008 [4] 兰吉昌.51单片机应用设计百例[M].北京:化学工业出版社.2008 [5] 杨素行.模拟电子技术基础简明教程[M].北京:高等教育出版社.2006 [6] 余孟尝.数字电子技术基础简明教程[M].北京:高等教育出版社.2006 [7] 杨绪东、刘行景、杨兴瑶.实用电子电路精选[M].北京:化学工业出版社.1999 [8] 周惠潮、孙晓峰.常用电子器件及典型应用[M].北京:电子工业出版社.2007 [9] 谭浩强.C程序设计(第三版)[M].北京:清华大学出版社.2005 [10] 许建国.电机与拖动基础[M].北京:高等教育出版社.2004 [11] 王兆安、黄俊.电力电子技术[M].北京:机械工业出版社.2000 [12] 刘小伟、刘宇、温培和.Altium Designer 6电路设计实用教程[M].北京:电子工业大学出版社.2007 [13] 沈红卫.单片机应用系统设计实例与分析[M].北京:北京航空航天大学出版社.2003 [14] 韩志军、刘新民.数字温度传感器DS18B20及其应用[J].南京工程学院学报.2003.1(1):9-14 [15] 李鑫、曾光 等.基于AT89S52智能温度控制器的设计[J].现代电子技术.2006.29(2):93-96 [16] 王冬星.风扇智能控制系统设计[B].电脑学习报.2008.6 [17] 范灵芝.基于单片机的无线温控电风扇调速器设计[J].2009全国计算机网络与通信学术会议论文集.2009 [18] http://www.xie-gang.com [19] http://www.dxsdz.cn 40 附 录 附录A 元件清单 表A-1 系统所需元件清单 名称 型号/参数 数量 单片机 AT89S52 1 蜂鸣器 5V 1 晶振 12MHz 1 轻触按键 0.6*0.6*0.5 4 单刀双掷开关 \\ 1 发光二极管 0.5mm 1 瓷片电容 30p 2 安规电容 0.01uF,400V 1 电解电容 0.1uF 1 电解电容 0.33uF 1 电解电容 10uF 1 电解电容 2200uF 1 变压器 12V 1 桥式整流 3A 1 三端稳压管 L7805 1 三极管 9012 PNP 6 排阻 4.7K 1 电阻 330 2 电阻 470 9 电阻 1K 8 电阻 2K 1 电阻 4.7K 4 电阻 10K 1 二极管 1N4007 1 数码管 4位共阳极 1 温度传感器 DS18B20 1 人体热释电红外 集成模块 1 霍尔传感器 A3144 1 磁钢 4mm 3 单刀双掷继电器 220V/50Hz 1 41 双向可控硅 BT136-600E 1 光电耦合器 MOC3041 1 排针 20*1 2 排针 12*1 2 插针 2插针 4 插针 3插针 2 PIC底座 DIP40 1 PIC底座 DIP6 1 42 附录B 系统原理图 图B-1 系统原理图 43 C 系统PCB图 图C-1 系统PCB图 44 附录 实物图 图D-1 控制系统实物图 图D-2 智能风扇实物图 45 附录D 附录E 源程序 /****************************************************** 基于AT89S52的智能电风扇控制系统设计 江经坤、史 宣、李占伟 器件参数:AT89S52 12MHZ DS18B20 BT136 MOC3041 A3144 实现功能:显示环境温度、风扇测速、倒计时、温控调速 编写日期: 2011.5.17 *******************************************************/ #include /////////////////////////////////////////////////////// //宏定义 #define uchar unsigned char #define uint unsigned int #define HI_T0 (65536-10000)/256 //给定时器T0高8位赋值,定时10ms #define LO_T0 (65536-10000)/256 //给定时器T0低8位赋值 #define HI_T1 (65536-10000)/256 //给定时器T1高8位赋值 #define LO_T1 (65536-10000)/256 //给定时器T1低8位赋值 #define _TH2_TL2_ (65536 - 50000) //定时50ms #define HI (_TH2_TL2_ / 256) //给定时器T2高8位赋值 #define LO (_TH2_TL2_ % 256) //给定时器T2低8位赋值 #define M_1s 20 //(1000/50)1秒要20个中断的累计 ////////////////////////////////////////////////////// //位定义 sbit wei1=P2^0; //位定义数码管用到的片选,高电平有效 sbit wei2=P2^1; sbit wei3=P2^2; sbit wei4=P2^3; sbit wei5=P2^4; sbit wei6=P3^3; sbit K0=P1^4; //位定义按键 sbit K1=P1^0; sbit K2=P1^1; sbit K3=P1^2; sbit DQ = P3^0; sbit PWM = P3^7; //sbit buzzer=P3^7; sbit su=P3^6; ///////////////////////////////////////////////////// //定义全局变量 uint M=0; //T0中断次数,M*10ms即输出低定平维持时间 uint N=2; //T1中断次数,20ms,即输出高电平维持时间 uint M_V=1000; //定时10s,用于测取10s内风扇平均速度 uint V,VV; // uchar TT=25; //定义电风扇开启温度 uchar TT0; uchar TT1; //定义变量保存上一时刻和当前温度值 uchar hour = 0, min = 1, sec = 5; //定时器的初始值 uchar code SEG_TAB[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};//共阳极数码管0-9数字段码 uchar code SEG_TAB_1[] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};//共阳极数码管0-9带点数字段码 /////////////////////////////////////////////////////////// //函数提前声明 void init_wei(void); //初始化位选 46 void show(uchar date,uchar wei); //在哪一个(wei)数码管上显示什么数据(date) void disp_v (void); //速度显示函数 void key(); // void disp_js(); //倒计时显示函数 /////////////////////////////////////////////////////////// void delayms(uint x) //延时子函数,延时约 x ms { uint i,j; for(i=x;i>0;i--) for(j=120;j>0;j--); } /////////////////////////////////////////////////////////// void Delay(uint time)//延时函数 { while( time-- ); } ////////////////////////////////////////////////////////// void EX_int0Init(void) //初始化外部中断0 { IT0=0; //设置外部中断0为电平触发方式 EX0=1; //INT0EA=1; //总中断开中断开 } /////////////////////////////////////////////////////////// void Timer0Init(void) //初始化定时器0程序 { TMOD = 0x01; //设置定时器0 工作方式1 TH0=HI_T0; //高位赋初值 TL0=LO_T0; //低位赋初值 TR0 = 1; //启动定时器0 ET0 = 1; //定时器0中断开 EA = 1; //总中断开 } /////////////////////////////////////////////////////////// void Timer1Init(void) //初始化定时器1程序 { TMOD = 0x01; //设置定时器1 工作方式1 TH1=HI_T1; //高位赋初值 TL1=LO_T1; //低位赋初值 ET1 = 1; //定时器1中断开 EA = 1; //总中断开 } /////////////////////////////////////////////////////////// void Timer2Init(void) //初始化定时器2程序 { T2CON=0x00;//实现16位自动重载定时 T2MOD = 0x01; //设置定时器2 工作方式1 RCAP2H=HI;//自动重载寄存器赋值 RCAP2L=LO; TH2 = HI; //给TH0,TL0赋初始值 TL2 = LO; TR2 = 1; //ET2 = 1; //启动定时器定时器0中断开0 EA = 1; //总中断开 } 47 //////////////////////////////////////////////////////// Init_18B20()//初始化18B20 { uchar x = 0; DQ = 1; //DQ复位 Delay(10); //稍做延时 DQ = 0; //单片机将DQ拉低 Delay(80); //延时480us DQ = 1; //拉高总线 Delay(10); x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 Delay(20); } /////////////////////////////////////////////////// uchar ReadOneChar()//读一个字节 { uchar i = 0; uchar dat = 0; for (i = 8; i > 0; i--) { DQ = 0; // 给脉冲信号 dat >>= 1; DQ = 1; // 给脉冲信号 if(DQ) dat |= 0x80; Delay(15); } return (dat); } /////////////////////////////////////////////////// void WriteOneChar(uchar dat)//写一个字节 { uchar i = 0; for (i = 8; i > 0; i--) { DQ = 0; DQ = dat&0x01; Delay(5); DQ = 1; dat>>=1; } } /////////////////////////////////////////////////// void disp_t()//读取并显示温度 { uint a = 0, b = 0, c = 0, t = 0; float tt = 0; 48 Init_18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 Init_18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器 a = ReadOneChar(); b = ReadOneChar(); t = b; t <<= 8; t = t | a; tt = t * 0.0625; t = tt * 10 + 0.5; //放大10倍输出并四舍五入 TT0=TT1; TT1= t / 10; //保存当前温度 a = t / 100; //b = t / 10 - a * 10; //十位个位 c = t - a * 100 - b * 10; //小数位 init_wei(); //初始化位选 P0 = 0xc6; //显示温度\"C\"字符 wei1 = 1; delayms(5); wei1 = 0; init_wei(); //显示温度小数位 show(c,2); delayms(5); P0 = SEG_TAB_1[b]; //显示温度个位 wei3 = 1; delayms(5); wei3 = 0; init_wei(); //显示温度十位 show(a,4); delayms(5); } ////////////////////////////////////////////////////////// void main() { EX_int0Init(); Timer0Init(); Timer1Init(); Timer2Init(); TT1=TT0=TT; while(1) { if(TT1-TT0==0.1) //温度变化,则pwm变化,以实时调节风扇转速 { 49 M += 2; if(M==198){M=2;} } if(TT0-TT1==0.1) { M -=2; If(M==0){M=200;} } key();//手动调整定时时间 disp_js();//显示倒计时时间 //disp_t(); //显示温度 //disp_v(); //显示速度 } } //////////////////////////////////////////////////////// void EX_int0(void) interrupt 0 //INT0中断服务程序 { V++; } //////////////////////////////////////////////////////// void Timer0(void) interrupt 1 //定时器0中断服务程序 { static uchar count0; // static uint count00; TH0=HI_T0; //高位重装初值 TL0=LO_T0; //低位重装初值 PWM=0; count0++; count00++; if(count00==M_V)//10s时间到 { count00=0; VV=V*6; V=0; su=~su; } if (count0==M) { count0=0; TR1=1; //启动定时器1,输出高定平 PWM=1; //TR0=0; } } /////////////////////////////////////////////////////// void Timer1(void) interrupt 3 //定时器1中断服务程序 { static uchar count1; // TH0=HI_T0; //高位重装初值 TL0=LO_T0; //低位重装初值 PWM=1; count1++; if (count1==N) { 50 count1=0; //TR0=1; //启动定时器0,输出低定平 PWM=0; TR1=0; } } //////////////////////////////////////////////////////// void IsrTimer2(void) interrupt 5 //定时器2中断服务程序 { static uchar count = 0; //定义静态变量count /*TR0 = 0; //以下调整出栈入栈的时间误差 TL0 += (_TH0_TL0_ + 9) % 256; TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY; TR0 = 1;*/ TF2=0;//清零T2溢出标志位 if(K0==0) //启动风扇定时器功能 { count++; if(sec || min || hour !=0) //时间不为零 {if(count==M_1s) //中断20次,1秒时间到 { count=0; //重新复位count变量 if(sec--==0) //当秒减至零时,1分钟时间到 { if(min || hour !=0) //所剩时间大于1分钟 { sec=59; //秒赋值59 if(min--==0) //分减至零时, { if(hour !=0) //所剩时间大于1小时 { min=59; //分赋值59 hour--; } } } } } } else //时间为零,定时时间到,风扇停止 { //buzzer=0; //sec=min=hour=0; } } else //关闭风扇定时器 { hour = 0, min = 1, sec = 5; //初始化时分秒的值 } } /////////////////////////////////////////////////////////////////////////////////////////// void key() //按键调整倒计时时间 { if(K1==0) //K1 启动/停止计时 51 { delayms(10); if(K1==0) { TR0=~TR0; while(!K1); } } if(K2==0) //K2 每按下一次分钟加1 { delayms(10); if(K2==0) { min++; if(min==60) { min=0; if(hour++==23){hour=0;} } while(!K2); } } if(K3==0) //K3 每按下一次分钟减1 { delayms(10); if(K3==0) { if(min--==0) { min=59; if(hour--==0) { hour=0; min=0; } } while(!K3); } } } ///////////////////////////////////////////////////////////////////////////// void disp_js() //倒计时显示 { /******************************************* wei4 = 0;//第4个数码管显示时的十位 P0 = SEG_TAB[ hour / 10 ]; delay(5); wei4 = 1; wei3 = 0;//第3个数码管显示时的个位 P0 = SEG_TAB[ hour % 10 ]&0x7F; delay(5); wei3 = 1; wei2 = 0;//第2个数码管显示分的十位 P0 = SEG_TAB[ min / 10 ]; delay(5); wei2 = 1; 52 wei1 = 0;//第1个数码管显示分的个位 P0 =SEG_TAB[ min % 10 ]&0x7F; delay(5); wei1 = 1; ***********************************************/ if(K0==0) //当启动定时器时才显示倒计时 { uchar a,b,c,d; a = min/10; //分的十位 b = min%10; //分的个位 c = sec/10; //秒的十位 d = sec%10; //秒的个位 init_wei(); //显示秒的个位 show(d,1); delayms(5); init_wei(); //显示秒的十位 show(c,2); delayms(5); init_wei(); //显示分的个位 show(b,3); delayms(5); init_wei(); //显示分的十位 show(a,4); delayms(5); /* wei4 = 0;//第4个数码管显示分的十位 P0 = SEG_TAB[a]; delayms(5); wei4 = 1; wei3 = 0;//第3个数码管显示分的个位 P0 =SEG_TAB[b]&0x7F; delayms(5); wei3 = 1; wei2 = 0;//第2个数码管显示秒的十位 P0 = SEG_TAB[c]; delayms(5); wei2 = 1; wei1 = 0;//第1个数码管显示秒的各位 P0 = SEG_TAB[d]; delayms(5); wei1 = 1; */ } } //////////////////////////////////////////////////////////////////////////////////// void disp_v (void) //速度显示函数 { 53 uchar a,b,c,d; a=VV/1000; //速度的千位 b=VV%1000/100; //速度的百位 c=VV%100/10; //速度的十位 d=VV%10; //速度的个位 init_wei(); //显示速度个位 show(d,1); delayms(5); init_wei(); //显示速度十位 show(c,2); delayms(5); init_wei(); //显示速度百位 show(b,3); delayms(5); init_wei(); //显示速度千位 show(a,4); } delayms(5); void init_wei(void) //初始化位选 { wei1=0;wei2=0;wei3=0;wei4=0;wei5=0;wei6=0; } void show(uchar date,uchar wei)//在哪一个(wei)数码管上显示什么数据(date) { P0=SEG_TAB[date]; switch(wei) { case 1:wei1=1;wei2=0;wei3=0;wei4=0;wei5=0;wei6=0;break; case 2:wei1=0;wei2=1;wei3=0;wei4=0;wei5=0;wei6=0;break; case 3:wei1=0;wei2=0;wei3=1;wei4=0;wei5=0;wei6=0;break; case 4:wei1=0;wei2=0;wei3=0;wei4=1;wei5=0;wei6=0;break; case 5:wei1=0;wei2=0;wei3=0;wei4=0;wei5=1;wei6=0;break; case 6:wei1=0;wei2=0;wei3=0;wei4=0;wei5=0;wei6=1;break; } } ///////////////////////////////////////////////////////////// 54 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务