基于51单片机与DS18B20的PID温度控制系统设计

发布时间:2026/9/13 14:50:06
基于51单片机与DS18B20的PID温度控制系统设计 简介一套面向电子设计竞赛、课程设计与毕业设计的51单片机温度控制与蓝牙控制系统完整方案适用于具备单片机基础、正在完成类似课题的在校生或工程师。资料包含Protues仿真图、C语言源代码、硬件原理图/PCB资料及设计论文并配套Android蓝牙调试APP覆盖从硬件搭建到手机端联调的完整链路。系统支持DS18B20测温、LCD1602显示、蓝牙透传、上下限报警值设定与断电记忆继电器可联动散热风扇或加热片功能模块清晰便于二次开发。资源包共166个文件以源码、仿真工程、Word/PDF文档、图片及APP安装包为主压缩包整体约81.82MB目录分类明确可快速定位所需材料。已有55人学习适合需要快速上手并产出完整设计报告的用户。1. 从课程设计到产品温度控制为什么要用51单片机单独做很多人拿到“基于51单片机设计的温度控制和蓝牙控制系统”这类题目时第一反应是把DS18B20、继电器、HC-05统统接在一个最小系统板上然后烧一段顺序执行的代码就收工。这么做的后果通常是温度要么冲过头、要么在目标值附近来回抖蓝牙连接时断时续仿真能跑而实物完全不是一回事。实际上这类项目的难点不在元器件接线而在于三个容易被新人忽略的约束51单片机的I/O时序、PID控制的周期匹配以及蓝牙串口与主循环之间的消息竞争。如果你正打算把这套资料做成课设、电赛作品或是年终要拿得出手的实物那么这篇文章会把温度采集、PID闭环、蓝牙协议、Proteus仿真以及论文里需要的验证数据串成一条完整链路。文中给出的代码和参数可以照抄也可以按你的硬件改动引脚后直接编译。适合已经会跑流水灯、但第一次接触独立传感器和无线通信的读者也适合那些因为实物不稳定、仿真图与电路图对不上而反复返工的工程师。2. 硬件设计51单片机、DS18B20与HC-05蓝牙模块的选型和接线2.1 为什么首选DS18B20做测温而不是热敏电阻或PT10051单片机的ADC不是标配STC89C52这类经典芯片内部根本没有ADC模块如果使用NTC热敏电阻还得外扩ADC0809或者PCF8591再加上分压电阻的温漂整个系统的误差来源一下子多了几个。DS18B20采用单总线协议一根数据线既传数据又传时钟省IO之外还自带12位分辨率实测精度可以到0.0625℃完全覆盖温控场景。另一个更关键的选型原因是DS18B20的温度转换过程是异步的启动转换后需要等待大约750ms才能读到结果。这个等待时间如果直接塞进主循环会让蓝牙串口响应变得不可用所以实现上通常把温度转换放到定时中断里主循环只消费结果。这个思路会在后面PID部分反复出现。2.2 继电器驱动电路和电源隔离温度控制的执行器多半是加热棒、半导体制冷片或小风扇工作电流从几百毫安到几安培不等。51单片机的P1口输出的高电平驱动能力有限直接用I/O口接继电器线圈是不现实的。常规做法是通过一颗NPN三极管如S8050或ULN2003达林顿管驱动继电器线圈两端并联续流二极管1N4148防止继电器断电瞬间的反向电动势击穿三极管。关于供电单片机、DS18B20、HC-05的VCC可以共用5V电源继电器的线圈电源也接5V但继电器触点单独接负载的供电回路。如果加热负载是220V交流设备建议使用带光耦隔离的继电器模块或者干脆把控制板与强电隔离只让继电器模块的输入端接受控制信号。仿真图上可以为了美观不画电源分配但实物做的时候电源地线尽量粗数字地与继电器地要特别注意否则单片机容易复位。2.3 引脚分配和HC-05蓝牙模块的电平转换HC-05蓝牙模块的串口逻辑电平是3.3V51单片机的RXD/TXD是TTL电平。很多课设资料里直接把HC-05的TXD接单片机的RXD因为HC-05的TXD输出在大多数情况下可以被51识别为高电平短期不会出问题但长期使用或加上外部干扰后通信可能不稳定。最稳妥的做法是加电平转换芯片或电阻分压。引脚分配建议如下表外设引脚51单片机对应IO说明DS18B20DQP2.0需接4.7kΩ上拉电阻继电器1加热INP2.1低电平触发控制加热继电器2制冷INP2.2低电平触发控制制冷HC-05TXDP3.0 (RXD)需3.3V/5V电平转化HC-05RXDP3.1 (TXD)分压到3.3VLCD1602RS/E/D4-D7P0或P2口推荐P0口上拉上面这个表格是多数51单片机课程设计的默认接法代码里也按这个引脚来写。常见做法是LCD1602用P0口接数据线D0-D7这样留给P2口的DS18B20和继电器刚好错开。如果你的板子引脚被占用只要在头文件里改宏定义就行不必跟着仿真图死搬。2.3.1 电平转换的一个低成本方案给HC-05的RXD接分压电阻是最省事的办法用两个电阻把5V的TXD电平分到3.3V比如串1kΩ再对地接2kΩ分压后大约为3.3V。HC-05的TXD输出3.3V高电平51的RXD对高电平的门限是约2V以上所以这一侧可以直接连不需要额外电路。硬件资料里除了原理图还至少要包含一份IO分配表和一个接线检查清单。很多人拿到别人的资料第一件事就是改引脚而不知道为什么要改往往是把DS18B20接到P3.7这类复用引脚上然后发现烧录后温度读数全是85℃这就是因为仿真和实物的引脚没有一一对应。3. 固件实现单总线驱动、PID控制算法与蓝牙通信协议3.1 单总线时序和CRC校验DS18B20的单总线协议对时序要求严格51单片机用12MHz晶振时一个机器周期为1μs写延时函数时最好用NOP指令配合循环调整到合适的时间。初始化时序是主机先拉低480μs以上再释放总线等待DS18B20拉低60~240μs作为存在脉冲主机在释放后延时60μs左右读取该电平。DS18B20读取温度的常规流程是复位、跳过ROM、发送转换命令0x44、等待转换完成、复位、跳过ROM、发送读取暂存器命令0xBE、连续读9个字节。核心代码片段如下sbit DQ P2^0; bit ds18b20_reset(void) { bit presence 1; DQ 0; delay_us(480); DQ 1; delay_us(60); presence DQ; delay_us(420); return presence; } void ds18b20_write_byte(unsigned char dat) { unsigned char i; for (i 0; i 8; i) { DQ 0; DQ dat 0x01; delay_us(60); DQ 1; dat 1; } } unsigned char ds18b20_read_byte(void) { unsigned char i, dat 0; for (i 0; i 8; i) { dat 1; DQ 0; DQ 1; delay_us(5); if (DQ) dat | 0x80; delay_us(60); } return dat; }这段代码的核心是DQ 0作为每个时隙的起始信号接着写入或读出数据位。注意写0和写1的区别只在于释放总线的时间点写0时让低电平持续60μs写1时先拉低1μs左右再释放靠总线上的上拉电阻把电平拉高。读时序则要求主机先把总线拉低1μs后释放然后在16μs内采样数据线超过这个窗口就可能读到错误数据。读出的9个字节中第0字节是温度低字节第1字节是温度高字节符号位在第1字节的最高位。0x07FF对应127.9375℃0xFC90对应-55℃这个范围足够覆盖常规温控。第8字节是CRC校验值也可以不校验直接读温度但作为论文资料或可靠性要求高的场景必须校验。你的程序里可以在读取暂存器后把前8个字节做CRC计算对比第9字节不匹配就丢弃本次数据并重新初始化总线。3.2 温度控制和PID参数的实现温度控制系统的执行逻辑是当前温度低于目标温度时打开加热继电器高于目标温度时如果制冷设备存在就打开制冷继电器。这种简单双位控制在100%占空比和0%占空比之间跳变系统会持续振荡。加入PID后控制量不再是0或100%而是占空比从而让温度稳定在目标值附近。以下是适合51单片机的增量式PID实现输出量为占空比百分比typedef struct { float target; // 目标温度 float kp, ki, kd; // 三个PID参数 float last_error; float integral; float out_max, out_min; } PID_Typedef; float pid_update(PID_Typedef *pid, float current) { float error pid-target - current; float p_out pid-kp * error; pid-integral error; float i_out pid-ki * pid-integral; float d_out pid-kd * (error - pid-last_error); pid-last_error error; float out p_out i_out d_out; if (out pid-out_max) out pid-out_max; if (out pid-out_min) out pid-out_min; return out; }增量式PID的优势是内存占用小、输出变化平滑而且不需要对输出做误差积分饱和处理。上面代码里的out直接作为加热器的PWM占空比在主循环里通过定时器中断产生PWM波形加热时P2.1引脚输出高电平的时间比例等于out / 100。参数整定遵循先比例后积分再微分的顺序。先把ki和kd设为0kp从1开始缓慢增大手动观察温度曲线见到微小振荡就回调到当前值的70%左右作为最终kp。之后把ki设为kp的1/10到1/20之间用于消除静差。最后加kd抑制超调但DS18B20的分辨率是0.0625℃采样周期又固定在750ms左右如果采样间隔内温度变化很小微分项会非常敏感kd初值建议从0.1起步。3.2.1 控制周期和PWM频率的匹配51单片机的PWM如果直接用定时器实现普通8位定时器的中断频率做20Hz左右的PWM比较合理。加热器是热惯性系统PWM周期太长温度波动大太短继电器触点寿命受影响。对于SSR固态继电器PWM频率可以做到1秒切换数次对于机械继电器PWM周期推荐不低于1秒最好使用SSR配合PID否则触点在频繁通断下几个月就会损坏。3.3 蓝牙串口和51单片机之间的通信协议硬件上蓝牙模块接单片机的是UART通信波特率常用9600bps。HC-05默认波特率常见的是9600或38400具体要看你手上的版本用AT指令查询确认后再定固件。固件里初始化串口时使用定时器1作为波特率发生器串口工作在方式1代码如下void uart_init(void) { TMOD 0x20; // 定时器1工作在8位自动重装 TH1 0xFD; // 9600bps 11.0592MHz TL1 0xFD; TR1 1; SM0 0; SM1 1; // 串口方式1 REN 1; // 允许接收 }注意晶振必须是11.0592MHz才能分频出精确的9600波特率。如果用12MHz晶振波特率误差在2%以上偶尔能和PC端通信和手机蓝牙模块互连时就很容易丢字节。这也是“HC-05蓝牙模块连接不上”“数据乱码”这类问题里最高频的原因之一。蓝牙收到手机端发来的字符串一般是‘R’表示查询当前温度‘S’后面跟目标温度值如S25.0表示设置25℃。为了在主循环中不阻塞解析最常用的方案是串口中断里逐字节接收拼到环形缓冲区主循环再解析。这里给出一个最简单的状态机解析。unsigned char uart_buffer[32]; unsigned char uart_len 0; bit cmd_ready 0; void uart_isr(void) interrupt 4 { unsigned char ch; if (RI) { RI 0; ch SBUF; switch (ch) { case R: cmd_ready 1; // 简单命令直接置位 break; case S: uart_len 0; // 开始接收目标温度 break; default: if (uart_len 31) { uart_buffer[uart_len] ch; if (ch \n) { uart_buffer[uart_len] \0; cmd_ready 1; } } break; } } }这个状态机的缺陷是如果主机发送‘R’之后没有结束符会在下一字节到来时被误判为普通数据所以协议设计要统一结束符。规范的做法是内部超声波模块数据或手机APP发送都统一结尾加\n单片机统一按行解析在中断维护一个简单的行状态机不区分‘R’和‘S’两个入口。4. 在Proteus中跑通51单片机温度与蓝牙控制仿真4.1 Keil工程配置与HEX文件生成在仿真之前先把固件编译通过。Keil5的安装和破解网上教程很多工程建立后要点是Target选项里的晶振频率改成11.0592MHzOutput选项卡勾选Create HEX File否则Proteus里的单片机没有可执行的机器码。编译时如果报错重点检查头文件路径和sfr定义特别是STC系列的寄存器定义需要选择对应芯片型号。编写代码时建议把DS18B20的驱动单独拆成一个.c和.hPID、蓝牙解析、LCD显示也分成独立模块。这样改一处不会影响另一处而且论文的“系统设计”章节可以直接引用模块划分图。4.2 Proteus元件放置和参数配置Proteus里找一个51单片机模板工程把AT89C51芯片拖入编辑区以后双击芯片设置Clock Frequency为11.0592MHz。程序加载方式是在芯片属性里选择Program File定位到刚才Keil生成的.hex文件。DS18B20在Proteus元件库里搜索“DS18B20”就可以找到属性里可以手动设置当前温度值。继电器在Proteus中不一定要用实际模型用一个LED或逻辑探针来观察控制电平即可。为了方便调试Proteus中加一个虚拟终端Virtual Terminal来模拟串口收发数据。虚拟终端的RXD和TXD与单片机的TXD、RXD交叉连接这样单片机发出的串口数据就能在终端上显示出来也可以直接向终端发送字符串来模拟手机蓝牙下发的指令这是在仿真阶段验证通信协议最快的手段。4.2.1 仿真时模拟蓝牙模块的方案仿真里没有真正的蓝牙设备常规替代办法是使用Proteus的COMPIM组件连接PC的串口再用电脑上的“虚拟串口软件”把物理串口转发成蓝牙虚拟串口手机端连接HC-05后也能参与实物联调。不过更简单的方案是仿真阶段只验证串口收发逻辑和PID输出把蓝牙协议验证留在实物上做因为仿真里加COMPIM的串口配置和波特率误差问题反而容易消耗大量调试时间。4.3 仿真和实物不符的三个典型问题第一个问题是Proteus的DS18B20温度模型变化太快实物中DS18B20从室温到加热目标可能需要几十秒仿真里你稍微改一下温度属性就会立刻变化。因此PID参数在仿真里调好的数值搬到实物上还要再做一次整定不能直接照抄。第二个问题是仿真里继电器没有触点寿命概念可以1Hz切换但实物机械继电器绝不能这么做。仿真调通以后应该在PID输出和继电器控制引脚之间加入一个死区或最小占空比限制。比如输出占空比小于5%时直接关闭加热避免继电器在目标温度附近高频颤抖。第三个问题是Proteus里51单片机的RC复位电路默认可用但实物如果采用最小系统必须加上10μF电容到VCC和10kΩ下拉电阻到GND的复位电路否则上电后程序可能不执行或随机跑飞。5. 硬件调试HC-05蓝牙连接不上、乱码和PID振荡排查5.1 把HC-05切换到AT模式配置主机或从机HC-05有数据模式和AT指令模式两种工作状态。进入AT模式的方法是按住模块上的按键再上电此时模块指示灯慢闪波特率变为38400。用USB转TTL连接模块在串口助手里发送AT返回OK就说明AT模式已经生效。常用指令和含义如下。AT指令返回作用ATNAMETempCtrlOK修改蓝牙广播名称ATPSWD1234OK配对密码ATROLE0OK设置从机角色ATROLE1OK设置主机角色ATUART9600,0,0OK设置波特率9600停止位1无校验配置时注意ATUART指令会改变模块的通信波特率改完以后要重新设置串口助手的波特率。如果你的模块是HC-06而不是HC-05它不支持ATROLE指令只能是从机和手机连接没有问题和另一块蓝牙互连时就不行了。5.2 实物联调时蓝牙数据乱码的排查路径实物接通以后经常遇到的故障是手机能搜到设备、也能配对成功但收到的数据是乱码。排查路径第一步把HC-05从板子上拆下来用USB转TTL直接连电脑发AT指令查波特率是否为9600。第二步检查USB转TTL的TXD是否接模块RXD、RXD接模块TXD。第三步检查单片机程序里串口初始化的晶振是否真的为11.0592MHz。第四步检查供电电流HC-05在配对状态下峰值电流可以达到几十毫安如果用电脑USB口供电且电源线过长压降会导致模块欠压复位症状就是连接断开再重连。一个容易被忽略的细节是手机蓝牙串口助手下发指令时默认后面会带\r\n有的助手还会自动加回车。单片机如果只读取一个字符做判断回车符会被当成下一个指令的第一个字符导致状态机错乱。解决办法是在接收状态机开头将\r和\n都视为行结束符不要只判断\n。5.3 温度控制超调和振荡的处理PID闭环调好以后温度曲线依旧可能剧烈振荡原因很可能不在PID公式里而在执行器上。如果你的系统是加热丝且没有风扇散热极差那么即使PID输出降为0温度依然会因为余热而持续上升造成很大的超调。对这类系统要么加入制冷设备并行控制要么在PID输出为0时通过蓝牙或OLED界面提示温度仍在上升让使用者知道这是系统结构决定的。处理振荡还有一个工程技巧在PID输出之前对误差做限幅处理即error的绝对值超过5℃时积分项不再累加避免温度误差大时积分饱和。具体代码在pid_update函数中加入一行判断即可if (error 5.0f || error -5.0f) { // 误差过大时禁用积分 pid-integral - error; }关键是误差超限时把本次误差从积分项里减掉让输出只由比例项和微分项决定等温度进入小误差范围后再让积分起作用消除静差。这个操作简单但效果显著也是绝大多数课程设计模板没有写进论文里的部分。6. 论文和答辩里最加分的一个技巧用串口日志输出PID过程曲线最终做成实物之后大多数人只会拍一张温度到设定值就停下来的照片这在答辩时缺乏说服力。一个很实用又不用外接上位机的方法让单片机每隔1秒通过蓝牙或串口输出一条时间戳、温度、目标温度、PID输出值四个字段的日志然后通过串口助手保存为CSV文件并绘制曲线图。固件里在发送数据时使用sprintf格式化注意STC89C52的sprintf完整版会占用较多代码空间如果你的PRINTF函数重定向了putchar直接用printf会比sprintf省事。输出格式建议如下printf(%ld,%d.%d,%d.%d,%d\r\n, seconds, (int)temp, (int)(temp * 10) % 10, (int)target, (int)(target * 10) % 10, (int)pid_out);采集到CSV文件后用Excel或Python的matplotlib绘图横轴是时间纵轴是温度和占空比在论文里可以直观地展现出上升时间、超调量、稳态误差这三个指标。为了让数据更干净采样间隔固定为1秒连续采集5分钟以上从室温35℃直接升温到60℃然后在目标温度保持2分钟这一组数据就能说明PID参数是否整定合格。最后的检查事项是你手里的硬件资料、仿真图、源代码三个部分必须保持同一引脚定义和同一逻辑。最容易被老师挑出的问题就是仿真图里用P2.1接继电器代码里却写的P2.2或者原理图上DS18B20接P2.0而仿真图接P1.0这种低级不一致在答辩时被要求现场跑仿真就会露馅。把这几个对应关系单独写一张表放到论文附录里能省去很多解释成本。本文还有配套的精品资源点击获取