资讯动态

单片机空调温控器:DS18B20采集+Proteus仿真到PCB设计全解析

发布时间:2026/10/18 0:40:08 来源:尧图企业网站定制
简介这是一份基于89C52单片机的空调温度控制器设计文档适用于电子、自动化类专业学生的课程设计或毕业设计也是单片机入门者了解温度测控系统完整流程的实用参考。文档围绕普通环境下的温度采集与空调制冷/制暖控制展开系统梳理了温控器的发展历程、温度传感器选型采用DS18B20以及硬件电路、软件实现与仿真验证等核心环节。资源为单个doc文件压缩包大小422KB内容涵盖系统方案论证、Proteus 7.1仿真说明及Protel DXP 2004原理图绘制和PCB制作结构清晰完整。目前已有230人学习下载。读者可据此掌握以单片机为核心的温度测控系统设计思路具体包括温度采集、LED显示与控制逻辑的实现方法同时文档中对第一代电气式、第二代电子式温控器的对比分析也有助于理解智能温控器由模拟向数字、网络化演进的方向对后续同类项目开发具有较好的借鉴意义。1. 单片机空调控制器从课程设计到可运行温控系统的一套完整资料做温度测控类嵌入式设计时最容易在两件事上翻车一是传感器选型拍脑袋二是代码和硬件电路对不上。这套以 89C52 为核心的空调控制器设计资料恰好把这两条链路都走通了——从 DS18B20 温度采集到 74HC138 译码驱动数码管显示再到制冷制热执行控制最后用 Proteus 7.1 做了仿真验证、Protel DXP 2004 出了原理图和 PCB。适合正在做单片机课程设计、毕业设计或者想快速搭一套家用级温度控制Demo的从业者。它不是那种只给结论的文档而是把传感器选型理由、电路设计方案、各模块管脚分配都拆开讲清楚了照着复现能少走很多弯路。2. 温度采集链路DS18B20 单总线协议与驱动时序实现2.1 为什么在众多温度传感器里单选 DS18B20文档里对传感器选择做了比较完整的对比分析。传统方案里热敏电阻 NTC 灵敏度高但非线性严重、互换性差后续还得自己搭信号调理电路做线性补偿热电阻精度尚可但响应慢热电偶测温范围宽但需要冷端补偿且输出的是微弱电势信号要经过放大和线性化才能进 ADC。这些方案用在工业高温场景没问题但放在常温空调控制里成本和电路复杂度都不划算。模拟集成传感器虽然外围电路简单但输出的是模拟电压89C52 内部不带 ADC还得外扩一块 ADC 芯片接线和软件处理都多一层。DS18B20 的优势在文档里写得很明确单总线接口数据线和时钟线合一根线从 CPU 到传感器只需要一条信号线加地线数字输出直接给单片机不需要额外 ADC测量范围 -55℃ 到 125℃在 -10℃ 到 85℃ 这个日常区间内精度是 ±0.5℃足够普通环境下的空调温控需求。分辨率可配置这一点也实用。DS18B20 支持 9 到 12 位分辨率默认 12 位对应转换时间 750ms。如果系统对刷新速度要求高可以降到 9 位或 10 位转换时间缩短到 93.75ms 和 187.5ms精度损失在 0.5℃ 以内对空调这种大惯性被控对象完全够用。2.2 单总线通信的初始化时序复位脉冲与存在脉冲DS18B20 的单总线协议是这套资料里软件实现的核心难点。所有通信都从初始化开始——主机拉低总线至少 480μs然后释放总线DS18B20 检测到下降沿后等 15~60μs会主动拉低总线 60~240μs 作为存在脉冲响应。主机在这个窗口期读总线电平读到低电平说明传感器在线。// DS18B20 复位与存在检测 bit DS18B20_Reset(void) { bit presence; DQ 1; // 总线拉高 delay_us(2); DQ 0; // 主机拉低总线 delay_us(480); // 复位脉冲持续 480us DQ 1; // 释放总线 delay_us(60); // 等待从机响应窗口 presence DQ; // 读总线0 表示存在1 表示无设备 delay_us(420); // 补足整个复位时隙时长 return presence; }这段代码的关键在时序窗口的把握。480μs 的低电平时间不能缩水DS18B20 对复位脉冲有最小时间要求短了传感器不认存在脉冲检测必须在释放总线后的 60μs 左右读取读早了总线还没被从机拉低读晚了从机已经释放总线都会误判。实际调试时如果发现presence一直为 1先拿示波器看复位波形确认低电平宽度和释放后的窗口期是否满足规格。2.3 读写时序写 1 和写 0 的微妙差别写时序比复位时序更考验代码精度。单总线的写时隙是 60~120μs 的窗口写 0 时主机在整个时隙内保持低电平写 1 时主机先拉低 1~15μs然后在剩余时间里释放总线拉高。DS18B20 在主机拉低后的 15~60μs 窗口内采样总线电平所以这个拉低时间必须在 15μs 之内完成。// 写一个字节先写低位 void DS18B20_WriteByte(unsigned char dat) { unsigned char i; for (i 0; i 8; i) { DQ 0; // 每个时隙起始拉低 delay_us(2); // 保持低电平 2us DQ dat 0x01; // 发送当前位1 则拉高0 则继续低 delay_us(60); // 保持到时隙结束 DQ 1; // 释放总线 dat 1; } }读时序同理每个读时隙由主机拉低 1~15μs 发起然后释放总线DS18B20 如果要发送 1 就保持高电平发送 0 就拉低总线。主机必须在拉低后的 15μs 内读取数据否则可能读到下一个时隙的状态。这里最容易踩的坑是用_nop_()空指令凑延时。不同编译器和优化等级下_nop_()的实际延时不同换一个编译器或改优化选项时序就可能差出几个微秒。我一般在写驱动时把延时函数单独封装并用逻辑分析仪实测确认。2.4 温度转换与数据读取流程DS18B20 读取温度的标准流程是复位 → 发送 ROM 指令 0xCC跳过 ROM 匹配→ 发送温度转换指令 0x44 → 等待转换完成 → 复位 → 再次发送 0xCC → 发送读暂存器指令 0xBE → 连续读取两个字节温度低字节和高字节。// 读取温度值返回实际温度单位0.1℃ int DS18B20_ReadTemperature(void) { unsigned char low, high; int temp; DS18B20_Reset(); // 复位 DS18B20_WriteByte(0xCC); // 跳过 ROM DS18B20_WriteByte(0x44); // 启动温度转换 // 12 位分辨率时需等待 750ms也可用轮询判断转换完成 delay_ms(750); DS18B20_Reset(); // 再次复位 DS18B20_WriteByte(0xCC); // 跳过 ROM DS18B20_WriteByte(0xBE); // 读暂存器 low DS18B20_ReadByte(); // 温度低字节 high DS18B20_ReadByte(); // 温度高字节 temp (high 8) | low; // 合成 16 位温度数据 temp 4; // 去掉低 4 位小数部分12 位分辨率时 return temp * 10; // 返回 0.1℃ 精度 }代码里temp 4这一步是对 12 位分辨率做的取整处理。DS18B20 温度寄存器低 4 位是小数位高位包含符号位正负温度。如果想要 0.0625℃ 的完整分辨率就不能右移而是要用浮点或定点数方式处理小数部分。文档里的系统做的是普通环境下的空调控制显示只需要整数部分右移 4 位最简单可靠。如果要多显示一位小数把低 4 位单独取出乘以 0.0625 即可。3. 显示与驱动74HC138 译码选通与数码管动态扫描实现3.1 显示链路各器件的角色分工这套系统的显示部分没有直接用单片机的 P0/P1 口去驱动数码管而是中间加了两级芯片74HC138 做位选译码74HC245 做段选功率放大。原因很实际——89C52 的 IO 驱动能力有限P0 口虽然能吸收较大灌电流但推挽驱动能力弱一个数码管的段选就需要 8 个引脚四个数码管如果每位都单独占一组引脚P1 和 P2 口就全被占满了传感器、按键、继电器就没地方接。74HC138 是 3-8 译码器用 3 根线控制 8 路输出。文档里用 P1.0、P1.1、P1.2 三个引脚接 138 的 A、B、C 输入输出端 Y0~Y7 接各数码管的位选端。这样三个 IO 就能控制最多 8 个数码管的选通省下的引脚留给温度采集和控制信号。74HC245 是八路总线收发器在这里当段选驱动用。文档里说明 DIR 接高电平时信号从 A 端输入、B 端输出相当于起了功率放大和隔离缓冲的作用。89C52 的 P0 口输出数据经 245 放大后驱动数码管的段引脚保证段电流充足、显示亮度稳定。3.2 四位一体共阴数码管的位选与段选逻辑四位一体共阴数码管的公共端对应 1、4、5、7 脚低电平选通。段选脚 a~g 和 dp 接 74HC245 的输出高电平点亮对应段。显示一个数字的完整条件是先选中某一位的公共端输出低电平再给该位对应的段引脚送高电平。动态扫描的原理是人眼视觉暂留效应——轮流点亮四个数码管每个管亮 2~5ms循环刷新看起来就像四个管同时显示。刷新频率太低会闪烁太高则占用 CPU 时间。128Hz 左右每个管刷 32Hz是个比较稳的频率既能消除闪烁感又不会让主循环卡顿。// 数码管动态扫描显示 void Display(unsigned char *buf) // buf[3]~buf[0] 分别存百十个位的段码 { unsigned char code sel_code[4] {0xFE, 0xFD, 0xFB, 0xF7}; // 位选码对应 Y0~Y3低电平选通 unsigned char i; for (i 0; i 4; i) { P1 (P1 0xF8) | i; // P1.0~P1.2 输出位选索引其余位不变 P0 buf[i]; // P0 输出段码 delay_ms(2); // 点亮时间 P0 0x00; // 消隐避免拖影 } }这里有个细节容易忽略位选切换和段码输出之间必须隔一个短暂延迟不然上一个位的段码可能会残留在下一个位上出现拖影。常见的做法是在切换位选之前先清空 P0段码清零选通后再送新段码也就是代码里最后两行做的事。段码表要根据共阴数码管连接方式确定。共阴管是段引脚高电平点亮数字 0 的段码是 0x3F二进制 0011 1111a~g 为 1数字 1 是 0x06以此类推。如果硬接线时把段位的顺序调换了段码表也要跟着换这个在 PCB 布线阶段就得定好不然做板回来再跳线非常痛苦。3.3 温度显示的量程边界与溢出处理测温范围 -55℃ 到 125℃但四位数码管能显示的范围是 -99℃ 到 9999℃带符号时更窄。文档里的系统主要工作在 0℃~99℃ 区间所以显示逻辑只需要处理两位整数加一个符号位。我在复现时加了量程保护if (temp 0) 显示负号 绝对值if (temp 99) 显示 “HI” 作为超限提示。这个处理在空调系统里实际用不太到但作为课程设计答辩时的加分项能体现出对边界情况的考虑。4. 控制执行链路继电器驱动制冷制热与按键交互设计4.1 双位控制逻辑为什么空调温控不搞 PID这篇文档采用的是双位控制Bang-Bang 控制——设定目标温度后实测温度高于上限就启动制冷低于下限就启动制热中间设置一个回差区间防止频繁启停。空调是大惯性系统房间温度变化很慢用 PID 反而容易因为积分饱和产生超调双位控制配合 1~2℃ 回差是最务实的方案。具体逻辑是假设设定温度 25℃回差 2℃则温度 ≥27℃ 时开制冷、关制热温度 ≤23℃ 时开制热、关制冷23~27℃ 之间保持当前状态不变。这个回差能有效避免继电器在临界点反复吸合延长继电器寿命。// 制冷制热控制逻辑 void ControlOutput(int current_temp, int set_temp) { int upper set_temp HYSTERESIS; // 上限 设定值 回差 int lower set_temp - HYSTERESIS; // 下限 设定值 - 回差 if (current_temp upper) { COOL_RELAY 1; // 启动制冷 HEAT_RELAY 0; // 关闭制热 } else if (current_temp lower) { COOL_RELAY 0; // 关闭制冷 HEAT_RELAY 1; // 启动制热 } // 处于回差区间内维持当前状态 // 这里默认用一个全局状态位保存继电器上次的动作状态 }继电器控制信号从单片机输出到真正驱动负载中间必须有隔离和功率放大的环节。常用的做法是 PNP 三极管或达林顿管驱动继电器线圈继电器触点接压缩机或加热器的供电回路。89C52 的 IO 直接接继电器线圈是带不起来的线圈吸合电流通常在 30~70mA而单片机的 IO 最大灌电流也就 20mA 左右不加驱动管必烧 IO 口。4.2 P3.0~P3.5 的复用功能分配与按键接法文档中 P3 口的分配方案很典型P3.0 接手动升温按钮P3.1 接手动降温按钮P3.2 接确认按钮P3.3 接 DS18B20 数据线P3.4 接高温报警 LEDP3.5 接低温报警 LED。P3 口内部带弱上拉按键可以做成低电平有效的接法——按键一端接地另一端接 IO 口按下时 IO 被拉低检测到低电平即认为按下。这里有个调试时容易遇到的问题P3.3 同时是 DS18B20 的单总线接口而 P3.2 是外部中断 INT0。如果 P3.3 的总线驱动或按键检测逻辑和 P3.2 的中断服务有竞争条件可能导致温度读取被按键中断打断。做课程设计时一般无伤大雅但工程上建议把 DS18B20 数据线挪到 P1 口或者 P2 口的普通 IO 上避开复用功能的潜在冲突。按键消抖也是必须处理的。机械按键按下和释放时存在约 5~20ms 的抖动期直接用读 IO 电平的方式判断按下状态轻则一次按键触发多次动作重则调温时数字跳好几个值。常规做法是读到一个低电平后延时 10~20ms 再读一次确认仍是低电平才算真正按下。4.3 晶振电路与复位电路的参数选择文档里提到 89C52 的 18、19 脚接 12MHz 晶振两个电容通常取 30pF。这个参数不是随意定的——12MHz 晶振的负载电容典型值在 20~33pF 之间30pF 是常规取值。电容大小会影响晶振起振的稳定性和频率精度太大起振慢太小频率容易偏移。如果没有特殊要求按文档给的 30pF 直接照抄即可。复位电路用的是上电复位加手动复位按键。上电瞬间电容充电RST 引脚保持高电平一段时间让单片机完成内部复位手动复位则是按下按键直接给 RST 拉高。文档里复位电路是 10μF 电容配 10kΩ 电阻这个时间常数的复位脉冲宽度大约在 100ms 左右足够满足 89C52 至少两个机器周期的高电平复位要求。Proteus 仿真时晶振电路一般不出问题但做实物时要注意晶振的负载电容和 PCB 走线。晶振引脚走线要短两侧的电容要靠近晶振放置尽量对称不然容易出现起振不稳定或者频率偏移的情况。如果程序在仿真里跑得好好的实物就是不动先查晶振是否起振。5. 常见问题与避坑DS18B20 通信失败、数码管乱码、仿真与实物不一致5.1 DS18B20 检测不到存在脉冲现象程序运行后温度显示固定值 0xFF 或者直接不显示复位函数返回的 presence 一直是 1单总线上永远看不到从机的响应。原因最常见的有三种——总线缺少上拉电阻、接线顺序接错、延时参数不匹配。DS18B20 的数据线必须接一个 4.7kΩ 左右的上拉电阻到 VCC因为单总线协议是开漏结构主机释放总线后靠上拉电阻维持高电平。很多初学者在面包板上直接拿杜邦线连接 DS18B20 的 DQ 和单片机引脚漏掉了这个上拉电阻通信自然失败。解决在 DQ 引脚和 VCC 之间焊一个 4.7kΩ 电阻。另外确认 GND 和 VDD 不要接反。如果用的是寄生供电模式VDD 和 GND 短接对供电要求更高调试时建议优先用外部 5V 供电模式排除电源因素。5.2 温度读取值始终是 85℃现象DS18B20 能正常响应复位但读取到的温度恒定为 85℃不管实际温度怎么变化。原因85℃ 是 DS18B20 上电后暂存器 ROM 的默认值。读到这个值通常说明温度转换指令 0x44 没有被正常执行或者转换还没完成就去读暂存器了。解决检查代码里 0x44 之后的等待时间。12 位分辨率下转换需要 750ms如果等待时间不够读取到的还是旧数据或默认值。可以在发送 0x44 后轮询总线状态——DS18B20 转换期间总线被拉低转换完成后释放总线检测到高电平再继续读暂存器这样不用死等 750ms 也能保证数据有效性。5.3 数码管显示乱码或亮度不均现象数码管显示的数字乱跳、缺笔画或者四位亮度明显不一致某一位特别暗。原因动态扫描频率不够或位选切换时序不对。如果扫描频率低于 50Hz人眼能明显感知到闪烁如果位选切换后没有消隐上一位的段码残留会造成残影。四位亮度不一致往往是某一位的选通时间比其他位短或者位选驱动能力不足。解决把每位点亮时间控制在 1~3ms总刷新周期控制在 8ms 以内约 125Hz。切换位选前先清零段选数据再选通下一位。如果某一位始终偏暗检查对应位选端和 74HC138 输出脚之间的连线以及该位公共端是否接触良好。5.4 Proteus 仿真正常实物不工作现象Proteus 里温度显示、继电器切换都正常做成实物后程序不跑或者跑飞。原因Proteus 是理想化仿真环境——电源纹波、负载效应、信号噪声全都不存在而且仿真模型对 IO 时序的模拟是理想化的。实物不工作的常见原因有晶振没起振、复位电路异常、电源滤波不足导致单片机频繁复位。解决按优先级排查——先用示波器确认晶振引脚有振荡波形再用万用表测 RST 引脚在上电瞬间有没有短暂高电平最后检查 VCC 引脚电压是否稳定在 4.5~5.5VVCC 和 GND 之间加 104 去耦电容尽量靠近单片机引脚。仿真正常只说明逻辑对实物还得靠电源和时钟说话。5.5 Protel DXP 画的原理图转 PCB 时网络丢失现象原理图转 PCB 时报错或者部分元件的引脚没有网络连接手工布线时发现连接关系缺失。原因原理图里元件引脚编号和 PCB 封装引脚编号不匹配。比如原理图库里某元件引脚标为 1、2、3但 PCB 封装里对应引脚标成 A、K、C网络表就对应不上。尤其是数码管、三极管这类多引脚元件最常出这个问题。解决做 PCB 之前先对每个元件执行封装检查——打开 PCB 封装库逐个核对引脚编号和原理图符号一致。文档里的四位一体数码管引脚定义和 74HC245、74HC138 的引脚图都贴了照着核对即可。6. 从 Proteus 仿真到 Protel PCB布线与验证的几个实用手法先仿真后画板这个顺序不要颠倒。Proteus 7.1 里有 DS18B20 和 89C52 的仿真模型可以先搭出一版最小系统把驱动代码烧进去跑通显示和温控逻辑再动 Protel。仿真阶段能发现绝大部分逻辑错误比如时序不对、控制逻辑方向反了这时候改代码只要几分钟等 PCB 做好再改代码就要焊板子跳线了。Proteus 里做仿真时有个技巧在 DS18B20 旁边放一个虚拟温度调节器Proteus 里叫 DSignal 或直接用滑动变阻器模拟运行仿真时动态改变温度值观察数码管显示和继电器的切换动作。文档里说“利用 Proteus 7.1 进行了可行性的仿真”核心就是验证三件事——初始化复位和存在脉冲能过、温度读取值随模拟温度线性变化、设定阈值处制冷制热继电器正确动作且继电器状态之间存在回差。Protel DXP 2004 画 PCB 时优先排布的是三块电路——晶振电路、复位电路、DS18B20 接口电路。晶振两个电容要尽量贴近 18、19 脚走线宽度不用很粗但路径要短。复位电路的电容和电阻靠近 9 脚走线同样要求短直。DS18B20 的信号线从 89C52 的 P3.3 出来尽量远离继电器驱动电路和电源走线避免电机启停时的电磁干扰影响单总线通信。继电器线圈两端记得加续流二极管方向是二极管阴极接 VCC、阳极接线圈驱动端否则继电器断电瞬间的反向电动势可能打坏三极管甚至单片机的 IO 口。74HC245 和 74HC138 在布局上需要靠近数码管。数码管的段选和位选线数量不少走线太多太长会影响显示质量——段选线之间平行长距离走线会有串扰导致显示噪声。做双面板的话建议数码管的段选线和位选线走在不同层交叉处用过孔过渡做单面板的话尽量把数码管放在 245 和 138 旁边让走线短而直。四位数码管的 PCB 封装是这次设计里最容易画错的地方。Protel 库里自带的数码管封装引脚顺序和文档里图的引脚顺序不一定一致。我的习惯是先自己在 Protel 里建一个四位一体共阴数码管的封装对照文档里的引脚图1、4、5、7 为位选脚其余为段数据脚逐个把引脚标好然后在原理图里把这个封装对应的网络关系再核对一遍。这个检查如果跳过了PCB 回来数码管显示一定错乱到时候飞线补就非常费劲。当初我照着这套资料做复现时在 DS18B20 的时序上卡了差不多一天后来用逻辑分析仪抓波形才发现是编译器优化等级的锅。从那以后我每次写单总线驱动的第一件事就是先确认延时函数的实际长度再跑复位时序测试这个习惯一直保留到现在。这套文档的价值也正在于此——它把每个器件选型的逻辑、每根信号线的走向、每个模块的管脚分配都交代清楚了你只需要按章节复现遇到问题也知道往哪排查。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑