资讯动态

单片机饮水机防干烧系统:水位检测、温度监控与仿真设计

发布时间:2026/10/15 22:22:50 来源:尧图企业网站定制
简介这份PDF文档以单片机饮水机防干烧控制系统为研究对象面向电子与自动化相关专业学生、嵌入式开发者及饮水机安全设计人员针对传统方案缺少可靠性分析的痛点提出基于故障树分析法FTA的完整设计流程。文档从加热系统工作原理出发建立故障树并找出导致干烧的最小割集据此对液位传感器、温度传感器和继电器模块分别优化液位侧选用非接触式电容传感器并前移至中水箱温度侧采用双传感器并联继电器侧以三单元触点串联提高断开概率同时补充声光报警与LCD提示。电路部分给出以STC89C52为主控的电源、检测、驱动、显示与报警等模块设计并通过Proteus完成仿真验证。资源为单一PDF文件大小1.27MB内含系统框图、故障树图、硬件电路及软件流程等核心内容便于对照学习整套设计思路与调试方法。目前已有184人学习适合作为课程设计、毕业设计或相关课题的参考资料。1. 先别急着买温控器这个防干烧系统到底在解决什么饮水机最怕的不是水不开而是桶里没水时加热管还在烧。干烧状态下加热管表面温度能在几十分钟内从室温冲到几百度轻则烧穿内胆重则引燃外壳。机械温控器只能在温度超标后断开属于事后补救而且反复干烧会让触点老化失灵。用单片机做防干烧控制本质是把「水温过高再断电」改成「水位不足直接不启动」加「加热过程持续监测」配合仿真环境先在电脑上把逻辑和参数调好再去做实物成本和风险都会低很多。这套系统适合做课程设计、毕设也适合想给小家电加保护逻辑的工程师参考。2. 防干烧的控制逻辑从水位检测到加热通断单片机这一套怎么想2.1 干烧判定的三个信号来源饮水机干烧的本质是加热管附近没有足够的水带走热量热量在金属管表面持续累积。所以防干烧不能只靠一个信号而是要把三个信号配合着看水位、温度、加热时间。水位信号负责“能不能烧”。最常用的是浮球开关和电极式探头。浮球开关是机械开关输出只有0和1成本低但浮球有可能卡在中间电极式探头利用水导电能覆盖整个液面范围但长期用会有极化问题需要交流激励。单片机看水位判断水有没有覆盖到加热管上方这个位置至少要高于加热管顶部留出安全余量。温度信号负责“烧得正不正常”。加热管正常在水里烧水温到沸点后会保持在一个范围内如果干烧几分钟内温度会飙升。用NTC热敏电阻贴在加热管外壳或者装在加热管附近通过分压电路把温度变成电压单片机用ADC采集。NTC便宜响应也够用但需要注意自热误差激励电流不能太大。时间信号负责“意外兜底”。如果水位和温度都正常但加热时间远超正常值比如已经烧了40分钟还没有到达设定温度那可能是传感器漂了也可能水位显示有误。逻辑上单片机会累计加热时间超过上限就强制停机避免传感器全部失效时系统干烧。这个上限我一般取正常加热时长的1.5到2倍。这三个信号各自都有盲区放在一起才可靠。启动时先看水位加热中定期看温度加热时长做冗余这就是防干烧控制的底层思路。2.2 控制状态机待机、预检、加热、保温、故障锁存程序上我习惯把系统拆成几个状态而不是在中断里到处设标志位。状态一多标志位之间互相打架排查起来非常痛苦。这套防干烧逻辑用五个状态就够待机状态系统上电后初始化不加热LED显示待机。只有当水位信号有效并且没有故障代码才允许进入预检。预检状态启动前强制读一次水位连续读3次每次间隔20毫秒三次都是“有水”才认为水位真实有效。这一步是为了滤掉浮球抖动也防止上电瞬间的毛刺让系统误启动。预检通过就闭合继电器开始加热不通过就回到待机并置一个“缺水”标志。加热状态每隔500毫秒采样一次温度同时读水位。温度超过设定的干烧阈值比如95℃或者水位变为无效立即断开继电器进入故障锁存。正常到达沸点附近后进入保温。保温状态低功率加热维护水温在设定区间防干烧监测依然运行。如果水位无效同样进入故障锁存。故障锁存故障原因记录在EEPROMLED或蜂鸣器报警加热回路强制断开。只有人工断电或按下复位键才能退出不允许自动恢复。这一步很关键干烧往往是瞬间的事自动恢复只会让加热管反复受折磨。状态转移的核心原则是从加热进入故障锁存的路径必须是唯一的不能出现“温度超标了但水位正常就继续加热”这种分支。宁可误停不可继续烧。状态进入条件主要动作退出条件待机上电初始化关闭继电器水位有效进入预检预检从待机转入3次读水位消抖确认有水通过后闭合继电器进入加热加热预检通过500ms采样温度和水位温度到阈值或水位无效进入故障锁存温度到保温区间进入保温保温加热结束低功率加热水温低于下限回到加热水位无效进故障锁存故障锁存任意加热相关状态断开继电器报警人工复位2.3 关键时序和参数设定时序参数直接影响系统是“灵敏”还是“乱跳”。采样周期、消抖时间、阈值滞后这三个要一起调不能单独拍脑袋。水位消抖时间20到50毫秒比较合适。太短滤不掉机械触点的抖动太长会让缺水响应变慢。尤其要注意缺水保护必须比加热管干烧升温快所以消抖时间上限要控制在100毫秒内。温度采样周期500毫秒足够NTC本身有热惰性采样再快也没有意义。ADC可以做连续几次求平均我一般取8次均值结果用于阈值判断避免单次尖刺触发误保护。温度阈值需要设置滞后。比如干烧保护阈值设为95℃恢复温度设为75℃。也就是说温度超过95℃立即断开温度要回落到75℃以下才允许重新加热。这个10℃到20℃的滞回差是防止系统在95℃附近反复通断的关键。如果不加滞后温度微小的波动会让继电器疯狂切换触点寿命急剧下降。加热时长上限按照热水壶正常加热8到12分钟估算取15到20分钟。超过这个时间还没达到温度阈值直接按异常处理。这个参数要留足余量但不能大到失去兜底意义。有人会问为什么不直接买一个双金属温控器串在加热回路里这样确实能在物理上断开但温控器动作温度高且需要手动复位无法知道缺水原因也无法显示故障状态。单片机系统可以做“预判控制”而不仅仅是“后果保护”。可以把温控器作为最后的物理保险单片机和温控器两级串联这在防干烧设计里是很常见的冗余做法。提示状态转移表看起来简单真正难的是每个状态里的标志位清理。进入新状态前把上一个状态的所有标志位清零否则故障锁存会莫名其妙被跳过。3. 硬件选型与电路设计单片机、传感器和继电器怎么搭3.1 主控选型与最小系统我们面向低成本小家电主控选择范围很宽。常见做法是用8位单片机比如51内核或者STM8原因是引脚少、ADC够用、成本在1到2元级别、开发工具成熟。用STM32当然也可以但在这个场景里性能过剩反而会增加外围电路复杂度和入门门槛。我一般会选带至少2路ADC和3个GPIO的单片机。ADC一路测温度一路可以用来做电源电压监测GPIO一路采集水位一路控制继电器一路驱动LED。如果有蜂鸣器再加一个GPIO。这些资源8位机完全够。最小系统包括晶振或内部振荡器、复位电路、电源滤波。如果用内部振荡器可以省掉晶振和两个电容但需要查手册确认内部RC精度是否满足时序要求。对于防干烧系统时间精度要求不高内部振荡器足够。选型时还要看ADC位数和参考电压。8位ADC按5V参考电压分辨率约20mVNTC分压后温度每变化1℃大约有几十毫伏8位够用。如果环境噪声大优先选10位或12位ADC软件平均后能更稳。3.2 水位检测与温度采集电路水位检测最省事的是用浮球开关接到单片机GPIO内部上拉。浮球闭合时引脚为低电平断开时高电平。电阻取值看GPIO上拉能力一般外接4.7k到10k上拉电阻避免浮球断开时引脚悬空。电极式水位探头需要更谨慎。水是导电的但直流电场会让探头电解时间长了探头表面生成氧化物信号会漂。常见做法是用两个IO口交替输出高电平或者用方波驱动再在单片机里同步采样避免极化。这个电路在仿真里很难模拟但实际做实物时要注意。温度采集我习惯用10k NTC加一个10k普通电阻做分压。NTC放在下桥臂标准电阻接5V中间抽头进ADC。温度T和ADC读数之间的关系可以由NTC的B值公式推出但工程中不用手算曲线直接用查表法把-20℃到120℃每1℃对应的ADC值算出来存成一个数组程序里二分查找。这样比在线算对数快也更容易写对。查表法需要先把NTC的B值代入分压公式生成表格。注意NTC标称10k是25℃时的值B值常见是3435或3950采购时一定要确认不同B值同一温度下电阻差异很大直接抄网上表格很容易翻车。3.3 继电器驱动电路与参数计算继电器是执行部件单片机GPIO驱动能力不够必须用三极管或ULN2003。我常用NPN三极管做低边驱动电路如下GPIO通过一个基极电阻接到三极管基极发射极接地继电器线圈一端接VCC一端接集电极线圈两端反向并联一个1N4148或1N4007二极管二极管负极接VCC正极接集电极。基极电阻的计算是核心。继电器线圈电压5V阻值例如70Ω线圈电流约70mA。三极管放大倍数hFE取100Ib至少要0.7mA。为了让三极管饱和导通一般取Ib Ic / 10 7mA。GPIO输出高电平约4.6V三极管Vbe约0.7V基极电阻R (4.6 - 0.7) / 7mA ≈ 557Ω取标准值470Ω或510Ω。电阻太小会让GPIO过流太大会让三极管进入线性区继电器吸合不稳。续流二极管不能省。继电器断开瞬间线圈会产生反向电动势如果不加二极管这个电压尖峰很容易打坏GPIO甚至让单片机复位。二极管选1N4007足够恢复时间没有要求因为继电器动作频率低。LED指示灯直接串一个330Ω到1kΩ电阻接到GPIO按5V供电3mm红LED压降1.8V电流控制在5到10mA亮度足够。3.4 仿真模型里要调整的电源细节仿真和实物有个很明显的差异仿真里电源是理想电压源没有压降也没有纹波。继电器模型在仿真里只等效成一个电阻和开关不会产生尖峰。这意味着仿真能通过不代表实物能通过。我在仿真里通常会故意加一个串联电阻模拟线阻继电器线圈两端加一个等效电感而不是直接用一个灯泡或者LED替代。很多教程把继电器画成LED只验证逻辑不验证驱动电流结果实物一接继电器就复位原因全出在这一步。4. 用仿真软件把系统跑起来搭建模型、写代码、调参数4.1 仿真环境搭建与器件清单这里以常见的单片机仿真环境为例我习惯用Proteus做原理图仿真用Keil写代码但思路对任何EDA套件都一样。仿真文件里要放单片机、晶振、复位按钮、一个水位开关用按键模拟、一个10k电位器模拟NTC分压输出、一个继电器模型、一个LED、一个蜂鸣器。水位开关用按键模拟的好处是可以随时按下和松开测试三个状态之间跳转。搭建步骤新建工程从器件库添加单片机双击设置时钟频率比如12MHz或16MHz添加5V电源和地接线顺序是先搭最小系统再搭水位输入、温度输入、继电器输出用按键一端接GND另一端接水位检测IOIO设置为输入上拉按键按下表示有水释放表示缺水温度输入直接用虚拟电位器中间抽头接ADC引脚先调到大约2.5V模拟常温继电器模型输出端串联一个灯泡或加热器模型方便观察通断。仿真不是一比一复刻实物水位和温度都做了抽象这是为了快速验证控制逻辑。抽象是好事但心里要清楚仿真里没有干烧物理过程温度只能靠电位器手动改变。4.2 主程序分模块初始化、采样、逻辑、执行程序按四个模块写不要全塞在一个main里。我给出的代码是一个可直接改用的骨架重点在状态机和防干烧判断。#define WATER_PIN P1_0 // 水位检测输入0为有水 #define RELAY_PIN P1_1 // 继电器控制输出1为加热 #define BUZZER_PIN P1_2 // 蜂鸣器输出 #define WATER_ON 0 // 水位有效电平 // 状态定义 typedef enum { STANDBY, CHECK, HEATING, KEEP_WARM, FAULT } SysState; volatile unsigned int adc_temp 0; SysState sys_state STANDBY; unsigned int water_count 0; void sys_init(void) { P1 0; RELAY_PIN 0; BUZZER_PIN 0; sys_state STANDBY; } unsigned char get_water_ok(void) { return (WATER_PIN WATER_ON); } void set_relay(unsigned char on) { RELAY_PIN on; // 继电器动作后留出吸合时间避免立刻采样干扰 } void sample_adc(void) { // 读取温度ADC连续8次平均结果保存在adc_temp unsigned int sum 0; unsigned char i; for (i 0; i 8; i) { sum read_adc_channel(0); } adc_temp sum 3; }这段代码里get_water_ok直接读引脚set_relay只做输出真正的逻辑放在状态机里。adc_temp保存的是ADC原始值不是温度值更方便调试时和电位器电压对应起来。状态机主体void state_machine(void) { switch (sys_state) { case STANDBY: if (get_water_ok()) { water_count; if (water_count 3) { water_count 0; sys_state CHECK; } } else { water_count 0; } break; case CHECK: if (get_water_ok()) { set_relay(1); sys_state HEATING; } else { enter_fault(FAULT_NO_WATER); } break; case HEATING: sample_adc(); if (!get_water_ok()) { enter_fault(FAULT_NO_WATER); break; } if (adc_temp DRY_TEMP_ADC) { enter_fault(FAULT_DRY_TEMP); break; } if (adc_temp BOIL_TEMP_ADC) { set_relay(0); sys_state KEEP_WARM; } break; case KEEP_WARM: sample_adc(); if (!get_water_ok()) { enter_fault(FAULT_NO_WATER); break; } if (adc_temp KEEP_MIN_ADC) { set_relay(1); } else { set_relay(0); } break; case FAULT: // 故障由外部复位打断 break; } }逻辑说明STANDBY里连续3次检测到水位有效才进入CHECK是为了消抖CHECK阶段没再等因为前面已经消抖过了。HEATING阶段每轮循环采样一次温度只要水位失效或温度超过DRY_TEMP_ADC立刻进FAULT。保温阶段用KEEP_MIN_ADC做滞回低于下限才重新加热。参数说明DRY_TEMP_ADC、BOIL_TEMP_ADC、KEEP_MIN_ADC都在头文件里定义典型值需要和仿真电位器电压匹配。比如ADC参考5V8位分辨率每约19.6mV对应1。95℃时NTC分压输出电压如果是2.1V那DRY_TEMP_ADC ≈ 2.1V / 5V * 255 ≈ 107。仿真时我是先把电位器调到2.1V再写入这个值实物则要按实际分压换算。4.3 仿真参数表与调参顺序下面是一套能跑通的典型参数供第一次搭建时使用。注意更换NTC型号或单片机后要重新算。参数含义典型值调整依据时钟频率单片机主频12MHz串口或定时器需要精确波特率时再改水位消抖次数连续有效次数3次主循环周期10ms总共约30ms温度采样周期主循环轮询10ms温度热惰性大不需要更快DRY_TEMP_ADC干烧保护阈值107对应NTC分压2.1V95℃BOIL_TEMP_ADC进入保温阈值98对应开水温度约90-92℃KEEP_MIN_ADC保温回差下限88对应80℃左右防频繁启停加热时长上限兜底计时20分钟按正常烧水时间1.5到2倍调参顺序很重要不要上来就调温度阈值。先把水位消抖逻辑跑通确认按键按下松开时状态能按预期跳转再把温度阈值从低往高调观察继电器通断点。每一个参数只改一个改完立刻跑一遍状态流程否则两个问题叠在一起很难定位。提示仿真里改阈值是在代码里改宏定义然后重新编译不要直接在仿真器里改电位器那样程序不知道阈值已经变化结果必然对不上。5. 防干烧系统调试避坑传感器失效、继电器抖动和仿真假象这一章写的是整个项目里最容易浪费时间的几个点位每一条我都按自己踩过的现象、原因、最后怎么解决来说明照着排查能少走不少弯路。5.1 水位信号在临界位置反复跳变现象实际水箱水位刚好在探头位置附近或者浮球半浮半沉按键在仿真里也能模拟出快速开关时系统在待机和加热间反复切换继电器哒哒响。原因传感器信号本身有物理抖动程序只在进入加热前做了3次消抖加热过程中只读1次临界状态下的毛刺直接让系统误判。解决加热过程中也要做消抖只不过超时要求更严。我一般在水位无效信号连续出现2次约20ms才认为缺水如果只出现1次当作干扰忽略。注意不能改成5次缺水响应速度要和干烧升温赛跑。调试时用示波器看水位引脚波形最直观。如果示波器显示几十毫秒的低电平脉冲那就是触点抖动如果是持续高电平那才是真正的缺水。不要靠眼睛看仿真里的LED判断。5.2 继电器吸合瞬间单片机复位现象一按下启动键单片机马上复位LED闪一下甚至无法启动。原因继电器线圈吸合瞬间电流很大如果电源变压器余量不足VCC会被拉低线圈断开瞬间的反向电动势也可能通过电源或GPIO窜入复位引脚。仿真里电源是理想的看不到这个现象。解决先在继电器线圈两端并上续流二极管二极管方向不能接反正极接集电极负极接VCC然后在单片机电源脚加一个100uF电解电容和104瓷片电容。还不行就把继电器换成固态继电器或改用可控硅驱动电流小很多但要注意可控硅的漏电流和散热。这个问题的排查顺序是先测VCC跌落幅度。如果跌落超过0.5V电源余量不足如果VCC没跌但依然复位多半是反向电动势串进了复位脚重点检查续流二极管和PCB走线。5.3 温度阈值在仿真里怎么调都“不触发”现象在仿真里把电位器调到干烧阈值对应的电压程序就是不进入故障状态调到很极端才动作。原因仿真普通的电位器模型不是精密可调输出电压漂移更常见的是代码里ADC读取通道号和实际接线不一致或者ADC参考电压没有按5V配置读回来的值和手动算的对不上。解决先不要靠电位器猜在程序里把ADC值通过串口或仿真调试窗口打印出来旋转电位器时观察数值是否平滑变化。若数值跳跃太大降低采样频率或者检查仿真器里电位器是不是带了多余的下拉电阻。然后以打印出的实际值重新标定DRY_TEMP_ADC。如果打印出来的ADC值在电位器旋到最大时仍不到255可能是仿真里的ADC参考电压被设成了内部2.5V或者电位器抽头没有真正接到ADC引脚。检查器和引脚连接比调阈值更优先。5.4 加热时间兜底被误触发现象正常烧水还没到温度系统先进入故障故障码是“加热超时”。原因加热时长上限设得太紧或者保温状态也累计了加热时间。比如设了10分钟上限冬天水温低正常烧水要12分钟就会误报。解决计时只从进入HEATING状态开始进入KEEP_WARM就清零上限按最恶劣室温下正常烧水时间的1.5到2倍计算。不能用一个固定死值至少要留50%余量。另外用定时器累计分钟数时要处理16位定时器溢出。比如定时器每50ms中断一次20分钟需要24000次中断16位计数器存不下需要用软件变量扩充高位。否则到一定时长后计数回绕兜底逻辑直接失效。5.5 从仿真搬到实物后上电时序不可控现象仿真里断电重启一切正常实物上电时有时候能启动有时候卡在故障报警再按一次复位又好了。原因单片机和继电器同时上电继电器触点闭合时产生的干扰影响到单片机复位或者是水位IO在上电瞬间内部上拉还没建立被读成了缺水。解决给继电器驱动电路加一个上电延时让单片机上电稳定后再允许控制。最简单的方式是在程序初始化里延时200ms再进入状态机避免继电器在电源爬坡时抢先动作。这个延时不能加在状态机内部会影响响应速度。这组问题做完后防干烧系统才算跑完一个完整的“正常路径加故障路径”闭环。6. 从仿真到实物之前验证功能安全的几个进阶做法6.1 故障注入测试在仿真通过之后不要急着正常流程先把最危险的路径测一遍。我习惯做三类故障注入断开水位传感器、温度传感器短路到地、继电器输出常通。每种故障注入后系统必须在1秒内进入故障锁存并且不能自动恢复。比如把水位引脚直接接高电平模拟缺水如果程序在500ms内没有断开继电器就说明消抖时间太长或者主循环被某个阻塞函数拖住了。这类测试结果可以直接做成一张验证记录表项目交接时比说明书更有说服力。6.2 硬件看门狗和物理保险丝单片机程序再健壮也存在跑飞的可能。防干烧系统务必打开看门狗喂狗语句放在主循环末尾而不是放在中断里。如果程序在某个分支死循环看门狗能强制复位复位后状态机回到待机不会直接继续加热。物理层面还要串联一个双金属温控器或者温度保险丝装在加热管外壳上。温度保险丝是一次性的超过动作温度就熔断成本几毛钱但能在单片机失效时保住设备。这个两级防护思路是这个系统的底线。6.3 参数自整定习惯每次换传感器批次都要重新标定阈值不要迷信网上别人给的参数。我通常先在实物上把温度从室温加热到100℃用串口记录ADC值和实际水温得到一条拟合曲线再用曲线反查阈值。这个过程每次只花半小时但能避免“仿真跑得好好的实物一到手就翻车”。参数记录习惯也很重要。我会做一个简单表格把设备编号、NTC型号、B值、分压电阻、干烧阈值ADC、消抖时间全部记录下来。同一个项目换一个人调试也不需要从头摸黑。调试防干烧系统最深的教训是不要只验证“有水能加热”这一条正常路径要把所有传感器失效的场景都当正常场景来对待。系统设计得再花哨最后守住安全底线的往往是那几行故障处理代码。希望帮到你。本文还有配套的精品资源点击获取

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

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

免费获取报价 →
↑