摘要:
在当前社会,随着大家对生活质量的追求和环保意识的加强,温控风扇作为一种节能产品备受社会的关注。温控风扇广泛应用于工业生产、家用电器、医疗美容设备和公共场所,提高了人们的生活效率和生活上的便利。这篇文章是根据单片机来构建的一个温度调节风扇冷却系统。这个系统使用了高精度的集成式温度传感器,通过单片机进行操作,可以实时监测和显示温度。同时,它会根据用户设定的温度,自动调整风扇的转速,以实现小风、大风和停机的功能,具有极高的精确性和准确性。因本系统使用的硬件较少,且能人为调整风速档位,因此具有操作简单,使用方便等优点。
关键词:温控;风冷;单片机;DS18B20
1 引言
在我们的日常生活里,电扇被广泛使用以进行冷却,从最初的悬挂式空调,到现在的USB空调,它的存在已经遍布了每一个角落。尽管现在空调已经普及到每个家庭,但风扇的地位依然是不可替代的。电风扇以其节省能源、爱护环境的特点和经济实惠、使用方便之优势,在众多住户中扮演着其无可替代的角色。随着时代的发展,功能丰富多样的现代风扇正逐步取代老式的传统型号。但是,微型计算机价格昂贵,并不是大部分工业控制所必须的,因为它们不需要如此高性能的功能,因此单片机应运而生。与微型计算机相比,单片机成本较低,并且非常适用于简易控制环境中,以减少开支。
随着现代社会的生活水平越来越高,以及工农业生产的需求增长,对环境气温的监测与调节的需求亦日益频繁。当周遭气候的热度高出预先设想的范围,便须要引入多样的制冷装置,以期实现减少温度的效果。通常采用的散热系统包括水循环散热、油循环散热以及空气对流散热等方式。每一类散热装置都具备独立的运作机制和相应的优缺点。采用冷却系统中的水冷却方式作为说明,其作用机制是这样的:冷冻液扮演降温媒介的角色,机械部件首先将热能传递给液体,依靠液体的循环作用将热能释放至周围空气中,之后已经降温的液体再次流向需要散热的机械部分。它的长处在于具有出色的散热性能,抵抗灰尘污染能力强,且可以根据需要调整冷却水流量和降温效率,有助于维持引擎的常规运作温度;然而,它的短板在于水冷系统需配备冷却塔和水泵,造价过高,对普通用户而言并不适宜。冷却方式采用的是气冷技术,主要通过空气作为降温媒介,依靠风扇产生的强制气流,将发热元件所产生的热能有效扩散至周围环境中。它的优势在于构造简单,避免了渗水、结冰或积垢之类的问题,同时具备重量轻盈、生产成本降低、能效表现出众、便于操作保养,且对环境适应力强,开机后迅速进入工作状态等特点。
老式的电扇通常是通过机械方式操控,其功能相对单一,运转时产生较明显的噪音,设置的定时关闭时间较短,且摇摆角度无法手动改变,风速档位调节时的变化幅度较剧烈。面对这些不足之处,论文中选择了一种具有优良性能价格比、低能耗特性的STM32微控制器—它基于ARMCortexM3架构—来构建了一种智能型电扇。这款电扇巧妙融入了温度感测和液晶展示技术,将智能化控制理念融入日常家电制品的操控系统,能够依据外界温度的波动自动调节风速,并将检测到的温度数值显示在液晶屏幕上。所选用的微处理器具备多种作用,便于后续功能的增强。
2 系统总体设计
本系统以单片机为主要控制芯片设计一个可以调节转速的温控风扇。该设计的功能实现依赖于硬件的中心逻辑与边缘电路的精密操控以及软件端对延迟处理与视觉输出程序的编制,主要涉及四个关键组成:键控电路、温度检测装置、脉冲激发系统以及液晶展示模块。总体硬件设计如图1所示:
图 1 系统总体结构框图
3 单元电路
3.1 单片机的选择
方案一:以电压比较电路充当控制元件。温度感应器利用如热敏电阻或者热电偶之类的元件来检测温度,将其变化转换成电流信号,再经过集成的运算放大器形成的比较器进行比较处理,进而调节冷却扇的转速。当检测到的温度超出或低于预设的特定数值时,将自动调整风扇到适宜的档位运作。
方案二:以STM32微控制器为主控芯片。采取编程手段实现对温度的判定,并通过接口发出控制指令。
针对方案一来说,选用比较电压的电路设计表现出其线路构造基础、实施操作简便以及不须要开发相关软件程序等优势,然而其调控手段显得比较单调,并不支持对启停温度极限的自由设定,这限制了它无法适应不一样需求者或者各种环境所需的多样化温控要求,因此此方案未被本系统所选用。
采用第二个方案时,将STM32微控制单元作为主控芯片,编程控制不仅可让传感器侦测的温度值透过显示模块呈现,还允许用户透过键盘输入端,灵活地调整设定温度的上限与下限,以迎合各项使用上的要求。此外,软件能以极致的精确性对温度进行评估,并能精准捕捉周遭气温的细微波动。因此,本系统选择实施第二个方案。
3.2 STM32 简介
STM32 系列采用专门为满足嵌入式系统应用所需的高效能、经济成本、低能耗而设计的 ARM Cortex-M 处理器作为其核心。在该系列中,STM32F1 分支包括:STM32F103 属于“高级”系列,STM32F10 归为“标准”系列,而 STM32F105 和 STM32F107 则构成了“网络连接”系列。
提升版系列的工作时脉速率高达72兆赫,居于类似商品之巅峰;而标准版的时脉则为36兆赫,以一般16位商品的成本实现了远超同位数商品的功能强化,堪称追求32位商品的消费者的首选之选。每个系列均配备了32K至128K的内部闪存,但它们之间的区别体现在SRAM的最高存储容量以及外部设备接口的不同配置上。在72兆赫的时钟速度下,STM32在运行闪存中的程序时,其耗电量仅为36毫安,这一数值在32位微控制器产品领域中属于最低水平,折合每兆赫功耗仅为0.5毫安。
核心组成:采用32位ARM架构的Cortex-M3处理器,最大运行速度可达72兆赫,每兆赫处理性能达到1.25 DMIPS。仅一周期完成的乘法操作与内建硬件的除法功能。
内置存储:集成电路内嵌有 32至512千字节的快闪存储芯片。采用 6-64千字节静态随机存取存储器、时序控制、重启功能及能量控制,该系统支持2.0至3.6伏特的供电电压以及I/O端口所需的驱动电势。上电复位(POR)、功率下降复位(PDR)以及可编程电压检测器(PVD)。4到16兆赫的振荡器。集成了预先设定的8兆赫兹电阻电容振荡器。内置的40千赫兹的电阻电容振荡器电路。服务于CPU时钟信号的锁相环。用于实时时钟校正的32千赫兹振荡器。
节能特性:三级降耗模式设计:睡眠状态、中止状态及待命状态。为实时时钟和后备存储寄存器提供电力的VBAT。
配置模式:支持SWD串行调试及JTAG端口。直接存储器访问:具备12个通道的DMA控制单元。兼容的硬件设备包括:计时器、模数转换器、数模转换器、串行外设接口、二线制串行总线和通用异步收发器。
三个具有12位分辨率的微秒级别模数转换器,各含16个输入通道,模拟信号输入范围为零至三点六伏特。采集和维持信号的双重功能。芯片内嵌入了一枚温度检测器。
双通道十二位数模转换器:仅STM32F103xC、STM32F103xD和STM32F103xE型号配备,具备至多高达112个快速输入/输出接口:不同型号分别提供了26、37、51、80以及112个输入/输出接口,而这些接口均能对应映射至16个外部中断向量上。在模拟输入之外,其余各项均能承受不超过5伏的输入电压。
最高可达11个计时器配置:包含4组16位计时器,每个均配备4路输入捕获/输出比较/PWM功能或是脉冲计数功能。两个拥有六个频道的16位高阶控制计时器:这些频道最多有六个能够用作脉冲宽度调制输出。两种类型的计时守护程序——分别为独立型和窗口式守护犬。Systick 计时器拥有一个24位逆序倒数功能。两个十六位的基础计时器被用来控制数字到模拟转换器的工作[3]。
高达13个的通讯端口数量,包括两个用于SMBus/PMBus的IIC端口。具备5个通用同步异步收发器接口,包括ISO7816标准接口、LIN总线协议、与IrDA兼容的红外数据接口以及用于调试的控制功能。含有三个SPI端口(速度为18Mbps),其中两个与IIS端口共用。CAN 总线接口遵循2.0版B协议规范。USB 2.0接口支持快速数据传送。SDIO端口。
STM32F103xx系列的微控制器使用了符合ECOPACK标准的封装方式。
3.3 温度传感器
温度传感器可由以下几种方案可供选择:
方案一:将热敏电阻作为检测温度的主要元器件,利用运算放大器将温度变动造成的热敏电阻阻值的微小变化放大成较大的电压变化信号,随后采用AD转换器ADC0809把这一模拟信号转换成数字信号,以便由微控制器进行相应处理。
方案二:利用热电偶作为检测温度的主要部件,并结合桥式电路、放大器电路及模数转换电路,把温度的变动信号转交给微控制器进行分析处理。
方案三:以数码型一体化温度感应器DS18B20为主要检测元器件,它能够直接提供数字化的温度信息以供微控制器进行处理。
针对第一个方案,选择热敏电阻因其成本低廉且易于购得而具有一定吸引力。然而,热敏电阻对温度轻微波动的感知度较低,在进行信号的捕捉、放大及转化时容易产生变形和偏差。此外,由于热敏电阻的温度电阻特性曲线非线性,对于温度的监控存在较显著的不精确性。尽管可以通过特定的电路设计来进行调节和修正,这不免会增加电路的复杂性和降低其稳定性,且仍难以精确捕捉到人体周围微小的温度波动。因此,此计划与本系统不匹配[4]。
针对第二个方案,我们改用了热电偶与桥梁式检测电路,这样不但提升了对温度的灵敏度,也优化了仪器的直线性误差。而且,它的测量温度区间极为广阔,从零下50度到1600度都能进行测定。然而,由于电路设计繁琐并对温度过于敏感,未能符合本系统的规范要求,因此决定不选用此计划。
对方案三来说,数字型温度感应器DS18B20高度一体化的特点极大减少了外部放大和转换电路可能引入的误差,因此其测温精度很高。另外,由于它的测温机制与前两个方案在根本上有所区别,因此它的温度分辨率非常优异。该设备将内部的温度读数转化为数字信号,并直接输出,这一过程简化了系统软件的编制工作。同时,得益于应用尖端的单总线技术(1-WIRE),其与微控制器的连接极为高效简约,并且展现出了卓越的抵抗干扰性能。所以,本次设计选定了第三个计划。
3.4 温度传感器简介
DS18B20为美国达拉斯半导体公司在DS1820型号推出后所研发的新型升级智慧温度感应器。经过升级,他在量测温度的准确性、数据转换时效、信号传递范围、以及清晰度等多个维度相较于DS1820取得了显著的进步,这为使用者提供了更加便捷的操作体验和更加令人满意的性能表现。可以分别在 93.75 ms和750 ms 内完成9位和 12 位的数字量,并且从 DS18B20 读出的信息或写入 DS18B20 的信息仅需要一根线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所挂接的DS18B20 供电,而无需额外电源,因而使用 DS18B20 可使系统结构更趋简单可靠性更高。相较于DS1820,他在温度测量的准确性、数据转换速度、信号传送范围及解析度等多个维度上实现了显著提升,为使用者提供了更便捷的操作体验和更加优越的性能成果。
(1)单一数据线连接特性:DS18B20在与微控制单元建立联系时,仅需用一根信号线就能够完成微处理器与 DS18B20 的双向通讯。
(2)在使用中不需要任何外围元件。
(三)支持通过数据线进行供电,其工作的电压区间为正3.0至正5.5伏特。
(4)温度检测区间:负五十五度至正一百二十五度摄氏。本测温设备具备的最小分辨率能力达到了0.5摄氏度。
(5)利用程序设计能够达到九至十二位数的阅读模式。
(6)使用者能够自行设定防丢失报警的最高和最低阈值。
(7)具备联合多地点构建网络的能力,众多DS18B20可共同连接于单独的三导线系统中,完成多位置的温度检测。
温。
(8)负极保护性能,当电源正负端反接时,温度测量仪不会因加热作用导致损毁,但无法正常运行。
单线(1—wire)技术:
此技术通过一条信号线实现功能,不仅能够进行时钟信号的传递,还可以进行数据的互传,并且支持双向通信。适合单一主机系统的应用场景,这台主机可操纵一个或众多的辅助机器,它通过浮空输出或三态接口与数据通道相连,使得当设备暂停数据传输时便可解放此通路,从而便于其他设备进行使用。通常,单线传输需要连接一个5千欧姆的上拉电阻,以确保在无信号传输时,该线路维持高电平状态。在主从设备之间进行通信要经历三阶段:首先进行单总线设备的初始化,随后进行单总线设备的识别,最后完成单总线的数据传送工作。
1-Wire通信协议的操作包含初始化的复位信号,随后的设备响应信号,以及写入逻辑0、写入逻辑1、读取逻辑0、读取逻辑1等信号动作,除了设备的响应信号由从机产生外,其他信号都是由主控设备发出的。此外,不论是命令还是数据字节,均以最低位优先的方式传输。
DS18B20 将其检测的温度数字化后,直接向微控制器提供数据,使用时必须严格按照单总线设备的操作时序进行[5]。
3.5 显示电路的选择
选项A:温度数值通过五个共阳极数码管展示,运用动态刷新的方法进行显示。
选项B:选用液晶屏作为温度的显示介质。
选项A因其低成本特性,具备清晰而易于辨识的温度显示,且在夜晚仍清晰可见。此外,其低功耗优势和易于编写的显示驱动程序,使得该种显示技术被普遍采纳。其缺陷在于采用了逐个激活五颗LED灯的刷新模式,因此产生了闪动现象。然而,由于人眼具有20毫秒的视觉保留能力,当LED的刷新周期少于该时长时,人眼无法察觉到闪烁。所以,提高刷新速度能有效地消除人眼感知到的闪动效果。
就第二个选项而言,液晶显示屏以其美观的字符展示为特色,不仅可以展示数字,也可以展现文字乃至图案,这种优势是LED数码显示管所无法匹敌的。此外,由于硬体链接便捷,故该系统选择实施第二种选项。
3.6 LCD1602 液晶屏简介
1602型的液晶显示屏亦称作1602字符型显示屏,此种点阵式液晶显示模块的设计初衷是为了呈现文字、数码及其他符号。该设备构建自多个5X7或5X11等规格的点阵字符单元,其中每个点阵单元能够展示一个字符。字符单元之间以及行与行之间均设有一个点位的空隙,形成字间距和行间距效果。正是由于这样的结构设计,它在图形展示方面的表现并不理想。实物之形状如图展现。
图 LCD1602实物图
1602LCD指的是液晶显示屏能够展示的内容为16列和2行,即每行能够显示16个字符的液晶显示模组。1602 显示模块接入时标配16针连接端口,具体如下:
第 1 脚:GND 为电源地。
第 2 脚:VCC 接 5V 电源正极。
第三接脚:V0端用于调节液晶屏的对比度,连接正极电源会使对比度降至最低,而接通负极电源则可获得最强的对比度。
脚位4:当寄存器选择(RS)线为高电位1,则选取数据寄存器;若为低电位0,则接通指令寄存器。
第五腳位:RW 线负责传递读写信号,当电平为高(1)执行读取动作,电平为低(0)时则执行写入动作。
六号引脚作为E(或EN)即使能端,当处于高电平状态(1)时进行数据读取,在发生下降沿变化时触发指令执行。
第 7~14 脚:D0~D7 为 8 位双向数据端。
第十五至第十六足:未连接或接反了灯具的电源线。第15脚连接背光的正电极,而第16脚则接至背光的负电极[6]。
3.7 调速方式的选择
选项一:运用数字模拟转换器DAC0832进行控制,通过单片机测定当前的环境温度并发送对应的数字信号至DAC0832,该芯片进而生成匹配的模拟信号以调节晶闸管导通角度,进而利用变频调速电路自动调整风扇马达的旋转速度。
选项二:通过微控制器编写软件程序来完成脉冲宽度调制的调速控制。脉冲宽度调制通常用缩写PWM表示,其是一种通过有规律地调整一系列脉冲的宽度来操纵输出大小和波形的技术。在采用PWM技术的驱动控制系统中,广泛采用的是方波作为PWM信号,并且在控制过程中,对PWM波形的占空比进行适宜调整。指标“占空比”是指周期内高电平持续的时间占总周期时间的百分率。调节电动机转速过程中,脉宽调制的占空比增加,则电机转速提升,而当输出持续高电平,即占空比达到百分之百时,电机转速将会达到峰值[7]。当通过微控制器的输入/输出端口产生脉冲宽度调制信号时,存在以下两个选择:
(1) 通过软件实现延迟功能。当触达设定的高电平持续时间后,I/O端口的电平将被设为相反值,即转换为低电平,并维持一段预定时长;随后,在低电平的预定持续时间结束时,同样将该I/O端口电平翻转,通过这种周期性操作便能生成PWM信号。本设计采纳了该计划。
(2) 采用计时器进行控制。此策略与(1)一致,目的在于通过单片机内置的计时器来按时切换高低电平,而非使用软件来实现延迟。采纳这一计划进行编码工作时,所需的程序设计会比较繁琐。
针对第一个解决方案,其优势在于可对直流电风扇的电动机进行连续性速度调控,且响应迅速,然而,其使用的数字模拟转换器成本过高,导致与其在恒温调控时的变速效能相较,并不具备较优的成本效益。
针对第二种计划,在通过纯软件技术实施的电机调速方式方面,相较于依赖硬件或是软硬件融合策略调速,选用只使用PWM技术的方法更具弹性,同时能极大缩减投入成本,并且能够充分利用单片机的计算能力,为简易的调速系统构建提供一条高效的路径。综观众因素,决定采取第二个计划。
4 系统软件流程图
4.1 系统软件总体设计
此次开发的控制系统软件采用了C语言作为编程工具。采纳分布式的设计理念,主要程序之外,还包括负责实施直流电机控速和温度采集、展示等多项作用的独立功能模块,编程工作则是在Keil这一集成化开发平台上完成。以下为软件整体操作流程示意图:
图 程序运行流程
4.2 系统初始化程序设计
初始化过程涉及对 STM32 的系统时钟、各个通用输入输出端口以及 LCD1602 显示屏的设定。
具体设计流程图如图 :
图 初始化程序流程图
4.3 温度采集与显示程序设计
在实施DS18B20温度感测器的测温过程中,必须按顺序完成初始化、执行ROM命令、内存指令处理以及数据传递等步骤,具体的编程流程展示于图。
图 9 温度采集与显示流程图
4.4 温控风扇代码
代码见附录
5 系统原理图
5.1 温控风扇原理图
通过Proteus软件,新建工程模板,通过“P”按键根据设计原理框图,添加各个模块的元器件按照设计原理进行布线连接组织温控风扇冷却系统原理图,包括按键模块,电源模块,单片机最小系统,LCD显示模块以及接地(GND)等等,具体系统结构图如图10所示[10]。
图10 温控风扇原理图
5.2仿真结果
将代码在keil5写好后导入到proteus的电路图中,即可显示当前环境温度,并可通过按键改变设定温度,仿真图如下所示:
图 温控风扇仿真图
经测定,在不同温度下风扇的转速也不同,每降低一度,转速就会增大一个档位,当温度与外界温度基本持平甚至更高时,风扇就会停止转动从而进行冷却,其温度与档位如表所示:
表1 转速与档位关系表
温度|℃ |
转速档位 |
22 |
0 |
21 |
1 |
20 |
2 |
19 |
3 |
18 |
4 |
17 |
5 |
6 实物及功能演示
6.1实物焊接过程
在最后完成上述所有准备工作后,便可以着手进行实物图的焊接,最终实物图如下所示:
图 焊接过程图与成品展示
7 结论
本设计采用STM32微控制器为主要控制单元,使用DS18B20温度感应器来跟踪环境的温度水平,并且能够按照环境温度的变化调整风扇马达的转速。系统内置了转速可调节功能,并在一定范围内支持无级调速。同时,通过LCD1602显示屏持续且稳定地反映出周围的温度数据,完成了基于微控制器技术的温控风扇的开发设计。
该设计方案能够普及应用于多种类型的电机控制系统,用以调整电机的旋转速度。在日常生活与工作领域,该系统适用于实施基础的日用风扇智能操控,增添生活便捷性;在工业制造领域,此设备能够通过调整多样输入信号来控制电动机的运转速率,以此促成生产流程的自动化。例如,在电力行业,根据载荷差异而调节至相应的电压级别,电压信号随后操控不同发电机的旋转速度,以调整发电量,实现电力供应系统的自动化平衡。经过综合分析,这一系统的构建与探究在社会制造与日常生活领域占据着至关重要的位置[11]。
主要参考文献
[1] 童诗白, 华成英. 模拟电子技术[M],北京: 高等教育出版社, 2023.
[2] 阎石.数字电子技术基础[M],北京:高等教育出版社,2016。
[3] 黄勤.单片机原理及应用[M],北京:清华大学出版社,2018。
[4] 龙志. 基于 51单片机实现LED数码管静态与动态显示的设计浅析[J]. 产业科技创新,2020, 2(22), 33-34.
[5] 郑步生,吴渭,Multisim2001电路设计及仿真入门与应用[M],南京:电子工业出版社,2002。
[6] 潘丽,51 单片机的智能温度检测系统设计[J],电子世界,2021,43(8),162-163。
[7] 贾立新,倪洪杰,王辛刚.电子系统设计与实践[M],北京:清华大学出版社,2019。
[8] 侯忠奎,戴恒阳,大电流高精度数控直流电流源的分析与设计[J],自动化与仪器仪表, 2016, (11),191-195。
[9] 时玲珑,孙姗姗,以单片机为核心的超声波测距系统[J],福建电脑,2022,38(02),29-32。
[10] 刘伟元,廖英兰,互联网监控智能门锁设计作品[J],上海纺织科技,2020,48(2),98。
[11] Wang Kun, Leng Tao, Mao Jie, Lian Guoxuan, Design and optimization of transmitting circuit system of scanning acoustic microscope, Sensors and Actuators: A. Physical, 334, 113335.
Remote-controlled fan cooling system
Abstract
Electric fans are commonly used cooling tools in people's daily lives, from ceiling fans to USB fans now, fans can be seen everywhere. Although air conditioning has entered thousands of households today, the position of fans is still irreplaceable. As an energy-saving, environmentally friendly, and cost-effective cooling tool, electric fans are still playing their unique role in many households. In line with the trend of the times, various multifunctional fans are gradually replacing traditional fans. However, microcontrollers are expensive and do not require the same powerful functions as microcontrollers for most industrial controls, so microcontrollers have emerged. Compared to microcontrollers, microcontrollers have a lower price and are very suitable for use in simple control situations to reduce costs. This system adopts high-precision integrated temperature sensors and is controlled by a microcontroller. It can display temperature in real time and automatically control the fan speed at the corresponding temperature according to the user's set temperature, achieving low wind, high wind, and shutdown actions with high accuracy and accurate action.
Keywords:Temperature; air-cooled; single-chip microcomputer; DS18B20
附录
主程序
#include "sys.h" #include "delay.h" #include "usart.h" #include "ds18b20.h" #include "LCD1602.h" #include "key.h" #include "timer.h" #define GEAR1 90 //1档 #define GEAR2 80 //2档 #define GEAR3 70 //3档 #define GEAR4 60 //4档 #define GEAR5 50 //5档 #define GEAR6 40 //6档 #define GEAR7 30 //7档 #define GEAR8 20 //8档 #define GEAR9 10 //9档 short temperature = 0; u8 T_max = 20; u16 PWM_Val = 100;//用于PWM调节 u8 Auto_flag = 1; void display_Max()//显示上限值 { LCD_Write_Char(13,0,T_max/10+'0'); LCD_Write_Char(14,0,T_max%10+'0'); } void keyscan()//按键扫描 { static u8 key_val = 0; key_val = KEY_Scan(0);//获取按键值 if(key_val == 1)//打开和关闭风扇 { Auto_flag = ~Auto_flag; if(Auto_flag == 1) { LCD_Write_String(5,1,"on "); } else { LCD_Write_String(5,1,"off"); } } if(key_val == 2)//加键按下 { if(T_max < 99)//最大只能到99 { T_max++; } display_Max();//显示 } if(key_val == 3)//减键按下 { if(T_max > 0)//最小到0 { T_max--; } display_Max(); } } void temp_dispose(short temp)//温度控制风扇处理,总共10档 { if(temp <= T_max) { PWM_Val = 100; Motor = 0; LCD_Write_String(14,1,"--"); } else { switch(temp - T_max)//温度每超一度,风扇档位加一档 { case(1):PWM_Val = GEAR1;LCD_Write_String(14,1,"1 ");break; case(2):PWM_Val = GEAR2;LCD_Write_String(14,1,"2 ");break; case(3):PWM_Val = GEAR3;LCD_Write_String(14,1,"3 ");break; case(4):PWM_Val = GEAR4;LCD_Write_String(14,1,"4 ");break; case(5):PWM_Val = GEAR5;LCD_Write_String(14,1,"5 ");break; case(6):PWM_Val = GEAR6;LCD_Write_String(14,1,"6 ");break; case(7):PWM_Val = GEAR7;LCD_Write_String(14,1,"7 ");break; case(8):PWM_Val = GEAR8;LCD_Write_String(14,1,"8 ");break; case(9):PWM_Val = GEAR9;LCD_Write_String(14,1,"9 ");break; case(10):PWM_Val=0;Motor = 1;LCD_Write_String(14,1,"10");break; default:PWM_Val=0;Motor = 1;LCD_Write_String(14,1,"10");break; } } } int main(void) { u8 count = 0; Motor = 0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 delay_ms(500); LCD_Init();//1602初始化 KEY_Init();//按键初始化 while(DS18B20_Init())//温度初始化 { LCD_Write_String(0,0," DS18B20 Erro "); LCD_Write_String(0,1," "); } DS18B20_Get_Temp();//温度初始化 LCD_Write_String(0,0," DS18B20 Init..."); delay_ms(1000); LCD_Write_String(0,0,"Temp: C M: C"); LCD_Write_String(0,1,"Auto: Gear: "); TIM3_Int_Init(1,7199);//10kh频率计数,定时100us if(Auto_flag == 1) LCD_Write_String(5,1,"on "); else LCD_Write_String(5,1,"off"); display_Max(); while(1) { keyscan();//按键扫描 if(count++ >= 200)//延时一段时间读取温度 { count = 0; temperature = DS18B20_Get_Temp();//获取温度 if(temperature<0) { LCD_Write_Char(5,0,'-'); //显示负号 temperature=-temperature; //转为正数 }else LCD_Write_Char(5,0,' '); //去掉负号 //显示温度 LCD_Write_Char(6,0,temperature/100+'0'); LCD_Write_Char(7,0,temperature%100/10+'0'); if(Auto_flag == 1)//在开启模式下,并且温度超过上限开启风扇 { temp_dispose(temperature/10);//根据温度进行pwm调节 } else//关闭风扇 { PWM_Val = 100; Motor = 0; LCD_Write_String(14,1,"--"); } } delay_ms(1); } }
DS18B20程序
#include "ds18b20.h" #include "delay.h" //复位DS18B20 void DS18B20_Rst(void) { DS18B20_IO_OUT(); //SET PA0 OUTPUT DS18B20_DQ_OUT=0; //拉低DQ delay_us(750); //拉低750us DS18B20_DQ_OUT=1; //DQ=1 delay_us(15); //15US } //等待DS18B20的回应 //返回1:未检测到DS18B20的存在 //返回0:存在 u8 DS18B20_Check(void) { u8 retry=0; DS18B20_IO_IN();//SET PA0 INPUT while (DS18B20_DQ_IN&&retry<200) { retry++; delay_us(1); }; if(retry>=200)return 1; else retry=0; while (!DS18B20_DQ_IN&&retry<240) { retry++; delay_us(1); }; if(retry>=240)return 1; return 0; } //从DS18B20读取一个位 //返回值:1/0 u8 DS18B20_Read_Bit(void) // read one bit { u8 data; DS18B20_IO_OUT();//SET PA0 OUTPUT DS18B20_DQ_OUT=0; delay_us(2); DS18B20_DQ_OUT=1; DS18B20_IO_IN();//SET PA0 INPUT delay_us(12); if(DS18B20_DQ_IN)data=1; else data=0; delay_us(50); return data; } //从DS18B20读取一个字节 //返回值:读到的数据 u8 DS18B20_Read_Byte(void) // read one byte { u8 i,j,dat; dat=0; for (i=1;i<=8;i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat; } //写一个字节到DS18B20 //dat:要写入的字节 void DS18B20_Write_Byte(u8 dat) { u8 j; u8 testb; DS18B20_IO_OUT();//SET PA0 OUTPUT; for (j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if (testb) { DS18B20_DQ_OUT=0;// Write 1 delay_us(2); DS18B20_DQ_OUT=1; delay_us(60); } else { DS18B20_DQ_OUT=0;// Write 0 delay_us(60); DS18B20_DQ_OUT=1; delay_us(2); } } } //开始温度转换 void DS18B20_Start(void)// ds1820 start convert { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0x44);// convert } //初始化DS18B20的IO口 DQ 同时检测DS的存在 //返回1:不存在 //返回0:存在 u8 DS18B20_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能PORTA口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PORTA0 推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC,GPIO_Pin_13); //输出1 DS18B20_Rst(); return DS18B20_Check(); } //从ds18b20得到温度值 //精度:0.1C //返回值:温度值 (-550~1250) short DS18B20_Get_Temp(void) { u8 temp; u8 TL,TH; short tem; DS18B20_Start (); // ds1820 start convert DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc);// skip rom DS18B20_Write_Byte(0xbe);// convert TL=DS18B20_Read_Byte(); // LSB TH=DS18B20_Read_Byte(); // MSB if(TH>7) { TH=~TH; TL=~TL; temp=0;//温度为负 }else temp=1;//温度为正 tem=TH; //获得高八位 tem<<=8; tem+=TL;//获得底八位 tem=(float)tem*0.625;//转换 if(temp)return tem; //返回温度值 else return -tem; }
按键程序
#include "key.h" #include "delay.h" //按键初始化函数 //PA15和PC5 设置成输入 void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能PORTA,PORTC时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成上拉输入 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PORTA0 推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_8); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PORTA0 推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_9); } //按键处理函数 //返回按键值 //mode:0,不支持连续按;1,支持连续按; //返回值: //0,没有任何按键按下 //KEY0_PRES,KEY0按下 //KEY1_PRES,KEY1按下 //WKUP_PRES,WK_UP按下 //注意此函数有响应优先级,KEY0>KEY1>WK_UP!! u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按键按松开标志 if(mode)key_up=1; //支持连按 if(key_up&&(KEY0==0||KEY1==0||KEY2==0)) { delay_ms(10);//去抖动 key_up=0; if(KEY0==0)return 1; else if(KEY1==0)return 2; else if(KEY2==0)return 3; }else if(KEY0==1&&KEY1==1&&KEY2==1)key_up=1; return 0;// 无按键按下 }