51单片机冰箱控制器:三态状态机与DS18B20测温实战
2026/9/11 11:58:32 网站建设 项目流程

简介:基于51单片机的冰箱控制系统设计资料,面向单片机课程设计、毕业设计及电子竞赛备赛者。资源围绕冷藏、速冻、化霜三种核心工作模式,提供完整原理图、PCB仿真工程、Proteus仿真文件及C语言源代码,并配套元件清单和系统总体/分模式流程图。内容同时包含操作讲解视频,可帮助理解复杂的模式切换逻辑与自动除霜控制策略;需注意电路规模已接近仿真上限,不宜随意添加外围元件。资源包共72个文件,以c/h源程序、hex烧录文件、schdoc/pdsprj电路与仿真文件为主,辅以bmp流程图、mp4视频及xlsx物料清单,总大小约97.33MB。目前已有213人学习,适合完整搭建一套基于51单片机的全自动冰箱控制系统,并可在此基础上进行功能扩展与调试。

1. 用51单片机做冰箱控制器:看懂三态切换后再画原理图

很多人拿到这个标题,第一反应是去画“冷藏控制”“速冻控制”“化霜电热丝”三张独立电路,结果状态一多,按键触发了速冻,化霜定时还在后台跑。常见做法是把三个模式收进同一个状态机,任意时刻只允许一个模式控制继电器,再用三路DS18B20分别测冷藏室、冷冻室和蒸发器温度,控制芯片用STC89C52RC这类51单片机就够。适用对象很明确:做51单片机课程设计、把老冰箱改成电子控温、或者想照着完整源码在Proteus里跑一遍的工程师。原理图、流程图、物料清单、仿真图和源代码五样东西,本质是同一套设计的不同视图,下面按状态机、原理图、仿真、实测的顺序讲清楚。

2. 冷藏/速冻/化霜状态机的判定条件与流程图简化

2.1 先立状态转换表,再画流程图

冰箱和普通恒温箱的区别在于:它有三个相互制约的状态。正常制冷时压机由温度滞回控制;进入速冻后,压机绕过滞回判断强制运行;进入化霜后,压机停机、加热丝接通,风扇也要断电,防止化霜水被吹到箱内。三个状态的转换条件稍有交叉,必须在流程图之前先把状态表定下来。这张表就是流程图的等价文字版,也是后面写源代码的依据。

当前状态进入条件继电器动作退出条件
制冷上电/从其他状态退出压机+风扇受温度滞回控制按键触发速冻;压机累计运行≥8h进入化霜
速冻短按速冻键压机+风扇强制运行再按速冻键;冷冻室温度≤-25℃;超时30min
化霜压机累计运行≥8h压机停、风扇停、化霜加热丝开蒸发器≥5℃;加热超时20min

流程图怎么画才不绕?我一般先把“进入条件”写在状态框左上角,“执行动作”写在中间,“退出条件”写在右下角,箭头只画三个方向:制冷进速冻、制冷进化霜、化霜回制冷。这样画出来既方便贴进课程设计报告,也方便对照代码做单元测试。特别要注意的一点是,化霜退出后不要立刻启动压机,常见做法是加一个2到3分钟的排水等待状态,让蒸发器上的化霜水充分流走,这一步流程图里不能省。

2.2 三路DS18B20测温:单总线时序和防坑点

冷藏室、冷冻室、蒸发器各放一支DS18B20,三支传感器可以挂在同一个IO口,也可以分别接P3.2、P3.3、P3.4。独立IO口的好处是代码简单,每路互不影响;挂在同一IO则需要处理64位ROM序列号,工程代码会复杂不少。课程设计里我一般选独立IO口,把精力留给状态机。下面的代码是读取单路温度的通用序列,三路复制三份,各用各的引脚即可。

// 单总线复位:拉低480us以上,释放后检测应答脉冲 bit ds18b20_reset(void) { bit presence; DQ = 0; delay_us(480); DQ = 1; delay_us(70); presence = DQ; // 0=在线 1=无应答 delay_us(420); return presence; } // 拉高拉低组成写时隙,1位耗时约60us void ds18b20_write_byte(unsigned char dat) { unsigned char i; for (i = 0; i < 8; i++) { DQ = 0; delay_us(10); DQ = dat & 0x01; delay_us(55); DQ = 1; dat >>= 1; } } // 读时隙:15us内必须采样,所以要尽量短 unsigned char ds18b20_read_byte(void) { unsigned char i, dat = 0; for (i = 0; i < 8; i++) { dat >>= 1; DQ = 0; delay_us(2); DQ = 1; delay_us(2); if (DQ) { dat |= 0x80; } delay_us(50); } return dat; }
// 测量一次温度:跳过ROM匹配,单点读数的写法 void ds18b20_read_temp(unsigned int *raw) { ds18b20_reset(); ds18b20_write_byte(0xCC); // 跳过ROM ds18b20_write_byte(0x44); // 启动温度转换 delay_ms(750); // 12位转换约750ms ds18b20_reset(); ds18b20_write_byte(0xCC); ds18b20_write_byte(0xBE); // 读暂存器 raw[0] = ds18b20_read_byte(); raw[1] = ds18b20_read_byte(); }

说明一下时序的坑:复位后的应答脉冲要在60到240us之间采样,delay_us(70) 就是这个窗口;写时序要在拉低后15us内决定写1还是写0;读时序要在拉低后尽快读,超过15us读到的就是错数据。Proteus仿真里这些时序同样敏感,晶振频率和代码延时必须对应,晶振用11.0592MHz时,for空转1200次大约是1ms量级,具体要示波器量一下或者用定时器延时代替空循环。那个delay_ms(750)在仿真里会拖慢整体速度,稳妥做法是缩小延时或者改用读暂存器第7字节的低1位判断转换是否完成,但这个位在Proteus模型里不一定被实现,课程设计直接延时750ms最省事。

提示:单总线延时建议全部改用定时器计数的软件延时,代码移植到STC8或STM32时不用重新标定for循环次数。

2.3 用10ms时基累计压机运行时间

化霜进入条件是“压机累计运行≥8小时”,这里强调的是压机运行时间,不是整机上电时间。如果压机停机状态也在计时,8小时一到,蒸发器上可能根本没有霜,化霜加热丝却烧了20分钟,白白浪费电。常见做法是用定时器0产生10ms时基,在主循环里把计数换算成秒,只有压机继电器吸合时才累加。

unsigned int run_sec = 0; // 压机累计运行秒数 unsigned char tick = 0; void timer0_isr(void) interrupt 1 { TH0 = 0xDC; // 11.0592MHz下10ms重装值 TL0 = 0x00; if (compressor_relay == ON) { if (++tick >= 100) { tick = 0; run_sec++; } } }
if (run_sec >= 8 * 3600) { // 满8小时进入化霜 current_mode = MODE_DEFROST; defrost_sec = 0; }

按下速冻键时不要清掉run_sec,速冻结束后继续累计,直到满8小时才整体清零。这样速冻和化霜两个状态不会互相干扰。时序上如果单片机还要驱动LCD1602,建议把显示刷新放在主循环,定时器中断里只做计数。

3. 原理图与物料清单:51最小系统、继电器驱动、传感器分布

3.1 端口分配决定原理图走向

原理图画得顺不顺,取决于端口表先不先定。P0口要接LCD1602数据线,必须外接10k上拉排阻;P2口给继电器控制信号;P3口给三路DS18B20。矩阵键盘可以放P1口,这套分配在Proteus仿真和实物PCB上都能直接用,端口表如下。

功能端口说明
LCD1602 D0~D7P0外接10k排阻
LCD1602 RS / ENP2.6 / P2.7
冷藏室 DS18B20P3.2独立IO
冷冻室 DS18B20P3.3
蒸发器 DS18B20P3.4
压缩机继电器P2.0S8050驱动
化霜加热丝继电器P2.1
风扇继电器P2.2化霜时断电
矩阵键盘行/列P1.0~P1.3 / P1.4~P1.7按键消抖状态机

为什么继电器不用P0口?因为P0接LCD数据线后已经带上拉排阻,感性负载开关时会产生电源毛刺,把液晶显示拉花;P2口内部上拉,输出高电平能力也更好。硬件设计的判断顺序应该是“显示外设优先,感性负载隔离,传感器单独留IO”。

3.2 继电器驱动和续流二极管不能省

51单片机IO口驱动能力有限,直接接5V继电器根本吸不住。常见做法是用S8050 NPN管做低端驱动:基极通过1k电阻接P2.x,集电极接继电器线圈负极,发射极接地,线圈两端反向并联1N4148二极管。二极管方向不能错,阴极接VCC,阳极接集电极,断电时给线圈提供续流回路,否则继电器释放瞬间的感应电动势很容易打坏IO口。仿真里如果不接这个二极管,继电器的动作波形也会出现明显抖动,用逻辑探头能看到触点反复通断几下才稳定。

原理图里还要注意:LCD1602的对比度脚V0接个10k电位器,Proteus仿真里直接给一个直流电压也行。晶振两端挂30pF瓷片电容到地,复位电路用10uF电解电容加10k电阻接到VCC。这些属于51最小系统标配,但最常见的问题反而是晶振频率没设对或者复位电容极性画反。

3.3 物料清单:一张能直接发给采购的表格

冰箱控制器和普通LED流水灯课程设计不同,需要真实控制220V交流负载,物料清单必须把继电器、传感器、三极管和电源部分分开列,数量也要算清楚。给出常用物料表如下。

编号名称型号/规格数量用途
U151单片机STC89C52RC DIP401主控
U2温度传感器DS18B20 TO-923冷藏/冷冻/蒸发器
U3液晶屏LCD1602 16脚1温度与状态显示
U4三极管S8050 TO-923继电器低端驱动
U5二极管1N41483继电器续流
K1~K3继电器5V/10A 单刀双掷3压机/加热丝/风扇
R1排阻10k 8脚1P0上拉
R2限流电阻1k 1/4W4基极电阻
C1 C2瓷片电容30pF2晶振负载
C3电解电容10uF1复位
C4电解电容100uF1电源滤波
Y1晶振11.0592MHz1时钟
SW1~SW5按键轻触6x65设置/速冻/化霜测试
BUZ1蜂鸣器有源5V1报警

这份清单里最容易被忽略的是C4和蜂鸣器。继电器吸合瞬间电流冲击很大,100uF滤波电容能显著减少LCD乱码现象;蜂鸣器不是必须,但做化霜超时报警和按键反馈很好用,价格也很低。

3.4 用AD检查原理图有没有连上

画完原理图先做电气规则检查。在Altium Designer里执行设计规则检查DRC,重点看Unconnected Pin和Unconnected Net这两类报告;在嘉立创EDA里对应的是“检查”菜单里的“电气规则”或直接看左下角网络表错误列表。教科书里一般会忽略这类提示,但实际打板错了就是短路或飞线。我习惯的做法是把所有网络表里的悬空引脚标成黄点,逐一确认是故意悬空还是漏拉线,同时检查P0口的排阻是不是真的挂在了总线节点上,这个位置特别容易因为总线段没命名导致实体引脚根本没连上。

4. Proteus仿真图与源代码:从状态机代码到可观察的动作

4.1 最小仿真模型搭建顺序

仿真图按三个层次搭:先放最小系统,再放显示与按键,最后放继电器与传感器。先搭最小系统是电源、晶振、复位三件套,用虚拟示波器确认RST脚和ALE脚电平异常;然后放LCD1602并P0口接上拉排阻,跑一个滚动字符验证显示通路;最后放三路DS18B20和LED指示灯。仿真里用LED代替继电器,还有一个隐藏的好处:LED自带限流电阻,不会像真实继电器那样出现反向电动势,但LED亮灭切换能直接体现状态机的动作顺序,配合文字标签仿真效果比真实继电器更直观。

4.2 状态机源代码骨架

先定义三种模式和切换条件,再写主循环。这段代码是整套控制逻辑的骨架,也是验证化霜流程的核心。

typedef enum { MODE_REFRIG = 0, // 正常制冷:滞回控制 MODE_QUICKFREEZE, // 速冻:压机强制运行 MODE_DEFROST // 化霜:压机停、加热丝开 } sys_mode_t; sys_mode_t current_mode = MODE_REFRIG; unsigned int defrost_sec = 0; // 化霜已运行秒数 unsigned int quickfreeze_sec = 0; // 速冻已运行秒数
// 10ms时基节拍,主循环中每秒调用一次 void mode_update(void) { switch (current_mode) { case MODE_REFRIG: fridge_relay = (t_fridge > set_fridge + 1.5); freezer_relay = (t_freezer > set_freezer + 1.5); // 按键触发速冻 if (key_quickfreeze_click()) { current_mode = MODE_QUICKFREEZE; quickfreeze_sec = 0; } // 压机累计8小时进入化霜 if (run_sec >= 8 * 3600) { current_mode = MODE_DEFROST; defrost_sec = 0; } break; case MODE_QUICKFREEZE: fridge_relay = ON; freezer_relay = ON; quickfreeze_sec++; if (key_quickfreeze_click() || (t_freezer <= -25.0) || (quickfreeze_sec >= 30 * 60)) { current_mode = MODE_REFRIG; } break; case MODE_DEFROST: fridge_relay = OFF; // 压机强制停机 defrost_heater = ON; defrost_sec++; if ((t_evap >= 5.0) || (defrost_sec >= 20 * 60)) { defrost_heater = OFF; run_sec = 0; // 化霜周期清零 current_mode = MODE_REFRIG; } break; } }

这段代码把关键点都放在明处:制冷态按滞回控制压机,速冻态完全忽略温度上限,化霜态压机与加热丝互斥。参数里有一个隐含的工程习惯——化霜结束后不要立刻启动压机,需要加一个MODE_DRAIN排水等待,表中加一个2分钟倒计时,防止直接制冷把残水重新冻在蒸发器上。按键扫描可以复用51单片机矩阵键盘最常用的行扫+列读法,P1口低四位输出扫描码,高四位读回电平,消抖状态机用20ms延时切换。

4.3 用仿真观察三个状态的切换

仿真图最直观的验证方式是:正常制冷时LED跟随温度阈值翻转;按下速冻键立即强制亮起;把RUN_TO_DEFROST_SEC宏从8小时缩短到仿真秒,再启动运行,化霜LED在几十秒内点亮。为了做这种验证,代码里要加一个时间尺度宏:

// 仿真时1秒代替现实600秒,8小时=48秒触发化霜 #define TIME_SCALE 600 #define RUN_TO_DEFROST_SEC (8 * 3600 / TIME_SCALE)

run_sec的判定从8*3600改成RUN_TO_DEFROST_SEC,实物烧录时再把TIME_SCALE改回1。这项做法非常实用,因为8小时的真实时间在Proteus仿真里几乎等不起,不缩短时间尺度就没有办法观察化霜退出条件是否正确。仿真通过后改回真实值,再烧录到实物板,这套验证流程比直接改代码里的凝霜时间要可靠得多。

验证项预期行为仿真操作方法
正常制冷LED随滞回阈值翻转修改DS18B20温度,减小温度设定值
速冻进入退出LED长亮,30min后熄灭按速冻键,观察速冻指示灯
化霜进入退出压机LED灭、加热LED亮把TIME_SCALE调成600

5. 冰箱控板的三个实测指标与三个易翻车的调试细节

5.1 三项必测指标

装完板先别急着接220V,用5V直流继电器代替交流回路,测三项指标:温度波动是否在设定值正负1.5℃内;速冻触发后是否恒定运行并按时退出;化霜退出温度是否用了蒸发器传感器而不是冷冻室温度。第二项尤其关键,因为速冻没有独立的物理开关,靠的是按键扫描和计时器,软件上一处逻辑错误就会表现为速冻后一直压机不停。

5.2 三个容易翻车的细节

第一个细节是继电器释放毛刺。压机继电器断开瞬间,感性负载会在VCC上产生几十伏的尖峰,即使加了续流二极管,如果100uF电容离继电器太远照样会导致单片机复位。PCB布局时续流二极管、继电器线圈、三极管要构成尽可能小的电流回路,这个回路面积越小,毛刺越小。

第二个细节是化霜温度和压机启动的顺序。蒸发器温度探头通常在化霜时被加热丝烘烤,温度上升很快,5℃退出条件要加“加热时间≥2分钟”的最小运行热保护,否则冬天时探头还没被烘热,化霜就误退出。我一般同时设两个条件,任一满足都退出化霜。

第三个细节是硬件仿真和实物测试的时间基准差异。代码里的延时循环在Proteus中常因未开启“真实模拟速度”而表现为动作极快或极慢,所以按键消抖和单总线延时最好用定时器计时,不要用for空转。最后一个实用技巧:把温度回差、速冻超时、化霜累计时间都做成EEPROM参数区里的标定值,装完板直接用按键调整,不用改源代码重新烧录,以后换传感器或改箱体尺寸也能快速适配。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询