
简介围绕饮水机加热系统防干烧可靠性不足的问题这份PDF论文面向电子信息、自动化及单片机课程设计的学习者与工程技术人员提供了一套从故障树分析到硬件软件优化的完整设计思路。压缩包内仅含1个PDF文件约1.27MB集中呈现系统结构、硬件电路、软件流程与Proteus仿真调试等内容篇幅紧凑便于按章节查阅。文中以故障树分析法FTA确定导致干烧的最小割集并据此优化液位传感器、温度传感器和继电器模块选用非接触式电容液位传感器并将安装位置前移至中水箱采用三单元继电器触点串联提升防干烧可靠度同时设计LCD12864显示与声光报警电路。该资料已有184人学习适合课程设计、毕业设计或相关项目借鉴其可靠性分析路径、传感器选型思路、继电器失效处理方式以及Proteus仿真验证方法。1. 从一个粘连的继电器说起这套防干烧方案到底解决什么问题饮水机干烧这件事很多人的第一反应是“加个液位传感器就完事了”。但真拆过故障案例的开发都知道液位传感器本身会失效、继电器触点会粘连、温度传感器会漂移单点保护在长期使用中迟早要出问题。这份基于单片机的饮水机防干烧控制系统设计与仿真资料做的事情不是简单堆一个传感器而是先用故障树分析法FTA把“干烧”这个顶事件往下拆找出四组最小割集和底事件的结构重要度排序再倒推硬件和软件该怎么改液位传感器前移到中水箱、三路继电器触点串联、双 DS18B20 并联、声光报警兜底。整套方案主控用 STC89C52配合 Keil C51 写程序、Proteus 做仿真验证适合正在做单片机课程设计、毕业设计或者想给家电类控制板补可靠性设计的开发者拿来对照复现。2. 系统架构拆解从 220VAC 到加热器一条控制链路怎么搭这套系统的主控不复杂难点在于“怎么把四个检测和执行模块串成一条不容易断的保护链”。硬件上分成电源、主控、传感、驱动、人机交互五块软件上则是一条从水位判断到温度判断再到继电器输出的顺序流程。2.1 硬件框图与信号流向整机以 STC89C52 为核心外围模块按信号方向可以分成三组输入组、处理组、输出组。输入组里液位检测用的是非接触式电容传感器输出高低电平直接接单片机 IO温度检测用两片 DS18B20单总线方式挂在同一个 IO 上也可以分两个 IO各自独立读电源电路把 220VAC 经过变压器降压、1N4007 桥式整流、LM7805 稳压成 5VDC给单片机、传感器、LCD 和继电器驱动电路供电。输出组里三路继电器驱动电路控制同一个加热器三组触点串联在加热器的 220V 回路里——这一点是后面可靠性设计的核心先记住“串联的是触点冗余的是保护”。LCD12864 负责显示水温和状态蜂鸣器和红黄绿三颗 LED 负责声光报警。信号流向用一句话概括中水箱液位 → 单片机 IO加热水箱温度 → 单片机 IO单片机 → 继电器驱动 → 加热器通断单片机 → LCD/蜂鸣器/LED。整个链路没有闭环反馈属于开环检测加逻辑保护所以传感器本身的可靠性直接决定防干烧能不能生效这也是为什么后面要单独做 FTA 分析。提示拿到原理图后先别急着抄引脚先用万用表把电源部分量一遍5V 输出稳定后再插单片机否则 LM7805 输入端滤波电容接反会直接把 7805 炸掉这是很多新手的第一笔学费。2.2 关键器件选型与参数表原文给的器件清单比较清楚我整理成一张表方便对照采购和替换模块型号/参数关键指标作用主控STC89C528 位12MHz 晶振32 个 IO逻辑判断与输出控制温度传感器DS18B20 ×2-55℃~125℃单总线加热水箱温度检测双路冗余液位传感器XKC-Y23A-V5V 供电±3mm 精度高低电平输出中水箱缺水检测非接触式显示AMPIRE 12864KS0108 控制器5V 驱动左右半屏各 64×64显示水温、水位、报警字样继电器单刀单掷常开5VDC 线圈最大切换电流 10A控制 220V/500W 加热器稳压LM7805输出 5V1A系统供电整流1N4007 ×41A 耐压 1000V桥式整流选型上有两个点值得说。一是液位传感器没有用传统的浮球式浮球长期泡在水里会长水垢浮球卡死之后液位信号就一直是“有水”这是干烧事故里很典型的一种失效电容式非接触传感器贴在水箱外壁不接触水体积也小。二是继电器线圈 5V、触点最大切换 10A而加热器 220V/500W 算下来工作电流约 2A余量足够不会因为触点拉弧提前失效。2.3 软件主流程与状态机设计软件没有跑 RTOS就是一个大循环加几个判断分支但对时序要求不低。上电后先初始化 LCD、DS18B20 和继电器 IO继电器默认断开然后进入主循环先读液位再读双路温度接着按优先级判断——缺水优先于干烧干烧优先于正常加热。状态可以归成四类缺水态液位低、干烧态温度 ≥110℃、加热态温度 ≤85℃、保温态85℃温度110℃。缺水态和干烧态都要切断三路继电器并启动声光报警加热态闭合继电器保温态断开继电器但保持显示。这里的关键是判断顺序不能反如果先判温度再判水位水箱已经空了但温度还没升到 110℃程序会误以为要加热继电器照样闭合防干烧就形同虚设。主循环里还加了 500ms 的采样延时目的是避开继电器频繁动作。饮水机加热有热惯性水温不会在几十毫秒内突变采样周期太短反而会让继电器“哒哒哒”地来回跳触点寿命掉得很快。3. FTA 可靠性设计四组最小割集怎么落到电路上这一章是整份资料里最有含金量的部分。很多同类设计只写到“用传感器检测、超阈值断电”就结束了但这份资料先用故障树把失效路径穷举出来再针对每条路径做硬件冗余思路值得借鉴。3.1 故障树建模与最小割集求解故障树的顶事件 T1 是“饮水机发生干烧”。往下拆中间事件有三个M1 加热水箱缺水、M2 加热器处于加热状态、M3 没有及时加水。再往下是底事件X1 液位传感器无反馈、X2 无声音提醒、X3 无警示灯光提醒、X4 温度传感器无反馈、X5 继电器无法断开。按与门/或门的逻辑展开后定性分析得到四组最小割集(X1·X4)液位传感器无反馈同时温度传感器无反馈(X1·X5)液位传感器无反馈同时继电器触点无法断开(X2·X3·X4)声光提醒都失效同时温度传感器无反馈(X2·X3·X5)声光提醒都失效同时继电器触点无法断开结构重要度排序是 I(X1) I(X5) I(X4) I(X3) I(X2)。翻译成工程语言液位传感器失效是最危险的单点继电器粘连和温度传感器失效并列第二声光报警虽然排在最后但它出现在两组割集里不能省。这个排序直接决定了后面硬件改哪里液位传感器要换型、要前移继电器要做触点冗余温度传感器要做双路声光报警要做成独立驱动不能和主控共用一条 IO 电源。3.2 液位传感器前移与选型依据原设计里液位传感器装在加热水箱等加热水箱缺水才报警此时加热器可能已经干烧了一段时间。改进方案是把传感器前移到中水箱中水箱一缺水就发信号相当于把保护动作提前了一个水箱的容量。选型上换成电容式非接触传感器型号 XKC-Y23A-V5V 供电检测精度 ±3mm输出高低电平。它贴在中水箱外壁不接触水不会结垢也不会像浮球那样被水垢卡住。安装时要注意两点传感器感应面必须紧贴箱壁中间不能有气泡或厚胶层水箱壁厚最好在 3mm 以内太厚会衰减电容变化量导致高低电平判不准。软件上对应地把液位 IO 配置成输入判断逻辑是“低电平 缺水”。如果传感器输出极性相反改一下判断条件就行但要在注释里写清楚不然后面接手的人容易搞反。3.3 三继电器串联与双温度传感器并联继电器触点粘连是防干烧失效里最常见的一种。触点烧蚀后两个簧片焊在一起线圈断电也断不开加热器一直通电。单继电器方案里这是死穴因为 X5 单独出现就能和 X1 组成割集。改进方案是用三个继电器单元触点串联在加热器回路里线圈由单片机三个 IO 分别驱动。正常加热时三个触点都闭合缺水或干烧时只要有一个触点能断开加热器就断电。三个触点全粘连的概率远低于单个触点粘连这就是用串联实现并联冗余的思路。温度传感器同理两片 DS18B20 并联挂在总线上同时对加热水箱测温。软件上取两路读数的较大值作为判断依据如果两路偏差超过 5℃直接按传感器故障处理切断加热器并报警。这样单片传感器漂移或断线时另一片还能兜底。3.4 声光报警链路的设计声光报警虽然结构重要度排最后但它出现在两组最小割集里说明“没有提醒”本身也是干烧的促成因素。原设计里蜂鸣器和 LED 直接接单片机 IOSTC89C52 单 IO 灌电流有限驱动蜂鸣器容易声音小甚至不响。改进方案是用三极管做驱动蜂鸣器用 PNP 三极管低电平导通LED 用 NPN 三极管高电平导通。R11、R12、R13 是分压电阻R4~R7 是限流电阻。报警时 LCD 显示“缺水”或“干烧”字样并提示“加水”蜂鸣器间歇鸣叫红色 LED 同步闪烁。蜂鸣器不要一直长鸣间歇响更容易引起注意也能降低一点功耗。4. 核心代码实现水位/温度采样、判断与继电器控制软件部分用 Keil μVision4 加 C51 编写代码量不大但几个时序和优先级的地方容易翻车。下面按主循环、温度读取、继电器控制、显示报警四块拆开讲。4.1 主循环与状态机框架主循环的结构是“初始化 → 采样 → 按优先级判断 → 输出”没有中断嵌套逻辑一目了然。关键是把缺水判断放在温度判断前面并且任何异常都往“切断加热器”这个安全侧靠。#include reg52.h sbit RELAY1 P1^0; // 三路继电器驱动触点串联控制加热器 sbit RELAY2 P1^1; sbit RELAY3 P1^2; sbit WATER_LOW P3^2; // 液位传感器低电平表示缺水 sbit BUZZER P1^3; // PNP 驱动低电平鸣叫 sbit LED_RED P1^4; // NPN 驱动高电平点亮 sbit LED_GREEN P1^5; sbit LED_YELLOW P1^6; #define TEMP_DRY 110 // 干烧阈值单位℃ #define TEMP_KEEP 85 // 保温下限单位℃ void main(void) { unsigned char temp; unsigned char low_flag; Init_LCD12864(); // LCD 初始化 Init_DS18B20(); // 单总线初始化 RELAY1 0; RELAY2 0; RELAY3 0; // 上电默认断开安全侧 BUZZER 1; LED_RED 0; LED_GREEN 0; LED_YELLOW 0; while (1) { low_flag (WATER_LOW 0) ? 1 : 0; // 读液位 temp Read_Temp_Max(); // 双路温度取大值 if (low_flag) { // 缺水优先级最高 Cut_Heater(); Alarm_Water_Low(); LCD_Show_String(0, 0, 缺水 请加水); } else if (temp TEMP_DRY) { // 干烧判断 Cut_Heater(); Alarm_Dry_Burn(); LCD_Show_String(0, 0, 干烧 请断电); } else if (temp TEMP_KEEP) { // 加热态 Heat_On(); LED_YELLOW 1; LED_GREEN 0; LED_RED 0; LCD_Show_Temp(temp); } else { // 保温态 Cut_Heater(); LED_YELLOW 0; LED_GREEN 1; LED_RED 0; LCD_Show_Temp(temp); } Delay_ms(500); // 采样周期 500ms } }这段代码里low_flag的判断放在最前面temp TEMP_DRY放在第二加热和保温放在最后优先级顺序和状态机设计一致。Cut_Heater()在任何异常分支里都会被调用保证失败方向是断电而不是继续加热。500ms 延时是给继电器和传感器留的缓冲实际调试时可以改成 200ms 看响应速度但不要低于 100ms。4.2 DS18B20 读取与双路校验DS18B20 是单总线器件时序要求到微秒级延时函数不准就会读出 85℃ 这个经典错误值。两路传感器可以挂同一个 IO靠 ROM 码区分也可以各占一个 IO 分别读这里按后者写逻辑更直白。unsigned char Read_Temp_One(unsigned char ch) { unsigned char tl, th; unsigned int t; DS18B20_Reset(ch); DS18B20_Write(ch, 0xCC); // 跳过 ROM单器件时可用 DS18B20_Write(ch, 0x44); // 启动温度转换 Delay_ms(750); // 12 位分辨率转换时间 750ms DS18B20_Reset(ch); DS18B20_Write(ch, 0xCC); DS18B20_Write(ch, 0xBE); // 读暂存器 tl DS18B20_Read(ch); // 低字节 th DS18B20_Read(ch); // 高字节 t ((unsigned int)th 8) | tl; return (unsigned char)(t 4); // 取整数部分精度 1℃ 够用 } unsigned char Read_Temp_Max(void) { unsigned char a Read_Temp_One(0); unsigned char b Read_Temp_One(1); unsigned char diff (a b) ? (a - b) : (b - a); if (diff 5) { return 200; // 两路偏差过大按故障处理强制走断电分支 } return (a b) ? a : b; // 正常时取较大值偏安全侧 }Read_Temp_One里 750ms 的转换等待不能省省了读出来就是上一次的旧值或者 85℃。Read_Temp_Max里偏差大于 5℃ 返回 200这个 200 会直接触发主循环的干烧分支等于把“传感器故障”当成“干烧”处理虽然粗暴但安全。注意两片 DS18B20 如果挂在同一个 IO 上0xCC跳过 ROM 会让两片同时响应读回来的数据会冲突。要么分两个 IO要么用0x55匹配 ROM 逐个读别偷懒。4.3 继电器控制与防粘连逻辑三路继电器要“依次闭合、同时断开”。依次闭合是为了避免三路线圈同时上电把 5V 电源拉垮同时断开是为了在故障时最快切断加热器不给触点粘连留时间窗口。void Cut_Heater(void) { RELAY1 0; // 三路同时断开故障时优先保证断电 RELAY2 0; RELAY3 0; } void Heat_On(void) { RELAY1 1; // 依次闭合避免线圈同时上电冲击电源 Delay_ms(50); RELAY2 1; Delay_ms(50); RELAY3 1; }Cut_Heater里三行赋值没有延时编译器生成的是连续位操作执行时间在微秒级三路几乎同时断开。Heat_On里每路之间 50ms 延时三路全闭合大约 100ms对人感觉不到但对电源友好。如果实际板子上继电器动作时 LCD 会闪说明 5V 电源余量不够可以把延时加到 100ms或者给继电器线圈单独加一路滤波电容。4.4 LCD12864 显示与报警接口LCD12864 用的是 KS0108 控制器左右半屏各 64×64靠 CS1、CS2 选片。显示内容不多主要是水温数值和“缺水/干烧”字样刷新频率不用太高跟着主循环 500ms 刷一次就够。void Alarm_Water_Low(void) { unsigned char i; BUZZER 0; // PNP 低电平导通先响一声长音 LED_RED 1; Delay_ms(500); BUZZER 1; for (i 0; i 5; i) { // 再闪 5 次提醒更明显 LED_RED 0; Delay_ms(200); LED_RED 1; Delay_ms(200); } } void Alarm_Dry_Burn(void) { unsigned char i; for (i 0; i 10; i) { // 干烧报警节奏更快 BUZZER 0; LED_RED 1; Delay_ms(150); BUZZER 1; LED_RED 0; Delay_ms(150); } }缺水报警是“一长五短”干烧报警是“十次快闪”两者节奏不同现场不用看屏幕也能分辨。LCD 显示函数里要注意 P0 口作为数据口时必须外接 10k 排阻上拉STC89C52 的 P0 口是漏极开路不上拉的话 LCD 显示的字符会缺笔画或者全屏乱码。5. Proteus 仿真联调与常见问题排查硬件没打板之前Proteus 是验证逻辑最快的方式。这套系统的仿真有几个和实物不一样的地方不注意就会以为代码写错了。5.1 仿真模型搭建步骤先在 Proteus 里放 STC89C52元件库里通常用 AT89C51 替代引脚兼容再放 DS18B20、LCD12864AMPIRE128X64、蜂鸣器、LED、三极管和继电器。液位传感器在仿真里用一位拨码开关代替因为电容式传感器输出的是开关量Proteus 里没有现成模型。继电器要选带Animated Relay model描述的否则仿真时看不到触点动作判断不了通断。电源部分在仿真里可以直接给 5V不用搭 220V 整流桥加热器用heater元件代替设好功率参数。单片机双击加载 Keil 编译出来的 hex 文件晶振频率设 12MHz和代码里的延时函数对应上。5.2 四状态调试流程仿真调试按四个状态走水温 ≤85℃ 时黄灯亮、继电器闭合85℃水温 ≤110℃ 时绿灯亮、继电器断开水温 110℃ 时红灯亮、蜂鸣器响、继电器断开拨动液位开关模拟缺水同样红灯亮、蜂鸣器响、继电器断开。调 DS18B20 的温度值时在仿真里点器件旁边的小箭头就能加减温度不用改代码。每调一个状态先看 LCD 显示对不对再看继电器触点有没有动作最后听蜂鸣器节奏。顺序不要乱先看显示能快速定位是采样问题还是逻辑问题。5.3 常见问题排查现象一LCD 只亮半屏或者满屏乱码。原因多半是 CS1、CS2 接反或者 P0 口没接上拉排阻。KS0108 是左右半屏独立选片CS1 和 CS2 对调之后写左半屏的数据跑到右半屏去了。解决方法是核对 P2.3、P2.4 的接线P0.0~P0.7 加 10k 排阻上拉到 5V再重新初始化。现象二DS18B20 读出来一直是 85℃。这是单总线最经典的翻车点。85℃ 是 DS18B20 上电默认值说明转换命令发了但没等够时间或者读写时序的微秒延时不准。检查Delay_ms(750)有没有被优化掉单总线上拉电阻是不是 4.7k晶振频率和延时函数是否匹配。Keil 里把优化等级调到 0 或 1 再试一次。现象三代码逻辑对但继电器不动作。先看三极管基极电阻是不是太大1k 到 10k 之间比较合适太大基极电流不够三极管进不了饱和区。再看 Proteus 里继电器模型是不是普通模型普通模型看不到触点动画换成Animated Relay才能观察到掷刀摆动。现象四蜂鸣器一直响断电也不停。PNP 三极管驱动时单片机 IO 上电默认是高电平PNP 截止蜂鸣器不响如果初始化时把 IO 拉低了蜂鸣器就会一直响。检查BUZZER 1有没有在初始化里执行以及 PNP 的发射极是不是接的 5V、集电极接的蜂鸣器。现象五仿真跑起来单片机不执行。九成是 hex 文件没加载或者晶振频率设成了默认的 12MHz 但代码按 11.0592MHz 写的延时。双击单片机看 Program File 路径对不对Clock Frequency 改成和代码一致重新编译再加载。6. 二次开发把这套防干烧逻辑移植到自己的板子上如果要把这套方案用到自己的项目里最直接的做法是保留 STC89C52 加三继电器加双 DS18B20 的骨架替换传感器和显示部分。比如液位检测换成超声波测距温度检测换成 NTC 加分压电阻显示换成 OLED主循环的优先级判断结构不用动。移植时先改硬件抽象层把Read_Temp_Max()里面的 DS18B20 时序换成自己传感器的读取函数返回值统一成“摄氏度整数”故障时返回一个大于干烧阈值的数这样主循环的判断逻辑一行都不用改。继电器部分如果只用一路把Heat_On()里的三路赋值改成一路Cut_Heater()保持不变安全侧逻辑照样成立。阈值和滤波参数是第二个要调的地方。干烧阈值 110℃ 是按饮水机工况定的换成其他加热设备要重新算加热器功率、水箱容积、正常最高水温、传感器安装位置都会影响这个值。我的习惯是先设一个保守值比如比正常最高水温高 15℃跑一段时间记录实际温度曲线再往回调。采样周期 500ms 也不是固定的热惯性大的设备可以放到 1s响应要求高的可以缩到 200ms但不要低于继电器动作时间。验证的时候按这张清单走一遍上电继电器是否断开、缺水时三路是否全断、单路温度超阈值是否断电、两路温度偏差大于 5℃ 是否断电、LCD 显示是否和实际状态一致、蜂鸣器和 LED 节奏是否可区分、断电重启后是否回到安全态。这七项全过基本可以上实物。最后说个血泪教训我第一次调这套板子时觉得液位传感器输出是开关量随便找个 IO 接上就行结果那个 IO 上电默认是高电平传感器还没稳定输出程序已经读到一个“有水”的假信号继电器啪地吸合了。从那以后我每次接开关量传感器都强制在初始化里先把对应 IO 拉成安全侧电平再延时 100ms 等传感器稳定然后才进主循环。这个习惯后来救过我好几次希望帮到你。本文还有配套的精品资源点击获取