简介:基于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~D7 | P0 | 外接10k排阻 |
| LCD1602 RS / EN | P2.6 / P2.7 | |
| 冷藏室 DS18B20 | P3.2 | 独立IO |
| 冷冻室 DS18B20 | P3.3 | |
| 蒸发器 DS18B20 | P3.4 | |
| 压缩机继电器 | P2.0 | S8050驱动 |
| 化霜加热丝继电器 | 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交流负载,物料清单必须把继电器、传感器、三极管和电源部分分开列,数量也要算清楚。给出常用物料表如下。
| 编号 | 名称 | 型号/规格 | 数量 | 用途 |
|---|---|---|---|---|
| U1 | 51单片机 | STC89C52RC DIP40 | 1 | 主控 |
| U2 | 温度传感器 | DS18B20 TO-92 | 3 | 冷藏/冷冻/蒸发器 |
| U3 | 液晶屏 | LCD1602 16脚 | 1 | 温度与状态显示 |
| U4 | 三极管 | S8050 TO-92 | 3 | 继电器低端驱动 |
| U5 | 二极管 | 1N4148 | 3 | 继电器续流 |
| K1~K3 | 继电器 | 5V/10A 单刀双掷 | 3 | 压机/加热丝/风扇 |
| R1 | 排阻 | 10k 8脚 | 1 | P0上拉 |
| R2 | 限流电阻 | 1k 1/4W | 4 | 基极电阻 |
| C1 C2 | 瓷片电容 | 30pF | 2 | 晶振负载 |
| C3 | 电解电容 | 10uF | 1 | 复位 |
| C4 | 电解电容 | 100uF | 1 | 电源滤波 |
| Y1 | 晶振 | 11.0592MHz | 1 | 时钟 |
| SW1~SW5 | 按键 | 轻触6x6 | 5 | 设置/速冻/化霜测试 |
| BUZ1 | 蜂鸣器 | 有源5V | 1 | 报警 |
这份清单里最容易被忽略的是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参数区里的标定值,装完板直接用按键调整,不用改源代码重新烧录,以后换传感器或改箱体尺寸也能快速适配。
本文还有配套的精品资源,点击获取