一、项目概述
本文基于 STM32F103C8T6 单片机,设计了一个高精度温度控制系统。通过 DS18B20 采集温度 ,采用位置型 PID 算法 控制 PWM 输出驱动 MOS 管加热Pi膜,配合 OLED 实时显示温度数据。系统可稳定将 PI 膜加热至 40℃,适用于实验室加热装置、小型温控设备等场景(可以换加热模块)。
二、硬件方案
模块 | 型号/参数 | 功能描述 |
---|---|---|
主控芯片 | STM32F103C8T6 | 核心控制单元 |
温度传感器 | DS18B20 | 温度采集(-55℃~+125℃) |
显示模块 | SSD1306 0.96寸OLED | 实时显示温度和系统状态 |
驱动电路 | IRF540N MOS管+续流二极管 | 加热膜功率控制 |
加热装置 | PI膜(12V/50W) | 电加热执行器 |
三、软件架构
c
/* 系统流程示意图 */
主循环:
初始化 → OLED显示 → DS18B20读取温度 → PID计算 → PWM输出 → 延时刷新
1. DS18B20 驱动优化
c
// 温度读取函数优化(去除冗余代码)
float DS18B20_Get_Temp(void)
{
u8 data[2];
short raw;
DS18B20_Start();
DS18B20_Read_Byte(); // 跳过温度值高位
data[0] = DS18B20_Read_Byte(); // 读取温度值低位
data[1] = DS18B20_Read_Byte(); // 读取温度值高位
raw = (data[1] << 8) | data[0];
return (float)raw * 0.0625; // 精度优化,直接计算0.0625℃/LSB
}
- 位置型 PID 算法实现
c
// PID结构体定义
typedef struct {
float Kp, Ki, Kd; // 控制参数
float err[3]; // 误差队列 [e(k), e(k-1), e(k-2)]
float integral; // 积分累加值
} PIDController;
// PID计算函数(增加限幅保护)
float PID_Compute(PIDController *pid, float setpoint, float feedback)
{
pid->err[0] = setpoint - feedback;
pid->integral += pid->err[0];
// 积分限幅(防止积分饱和)
if(pid->integral > 1000) pid->integral = 1000;
else if(pid->integral < -1000) pid->integral = -1000;
float output =
pid->Kp * pid->err[0] +
pid->Ki * pid->integral +
pid->Kd * (pid->err[0] - 2*pid->err[1] + pid->err[2]);
// 输出限幅(0~100%占空比)
if(output > 100) output = 100;
else if(output < 0) output = 0;
// 更新误差队列
pid->err[2] = pid->err[1];
pid->err[1] = pid->err[0];
return output;
}
- 显示优化方案
c
// OLED显示函数重构
void OLED_Update(float temp, float pwm)
{
static char buf[20];
// 温度显示
sprintf(buf, "Temp: %.1f C", temp);
OLED_ShowString(0, 0, (u8*)buf, 16, 1);
// PWM输出显示
sprintf(buf, "PWM: %.0f %%", pwm);
OLED_ShowString(0, 24, (u8*)buf, 16, 1);
// 状态指示
OLED_ShowChinese(0, 48, 0, 16, 1); // 温
OLED_ShowChinese(16, 48, 1, 16, 1); // 控
OLED_ShowChinese(32, 48, 2, 16, 1); // 系
OLED_ShowChinese(48, 48, 3, 16, 1); // 统
}
四、主函数核心逻辑
主函数是整个温控系统的调度中心,负责初始化配置、循环采集数据、执行控制算法并更新显示。其核心逻辑如下:
c
int main(void)
{
// 1. 系统初始化
PID_Init(&pid, 55, 0.1, 0.8); // 初始化PID参数
DS18B20_Init(); // 温度传感器初始化
OLED_Init(); // OLED显示初始化
PWM_Init(); // PWM输出初始化
// 2. 主控制循环
while (1)
{
// 2.1 温度采集与处理
float current_temp = DS18B20_Get_Temp();
current_temp = Filter_Temp(current_temp); // 滑动平均滤波
// 2.2 PID控制算法
float pwm_value = PID_Compute(&pid, 40.0, current_temp);
// 2.3 输出控制
PWM_SetCompare1(pwm_value);
// 2.4 数据显示
OLED_Update(current_temp, pwm_value);
// 2.5 系统延时(建议100ms周期)
Delay_ms(100);
}
}
四、调试优化
PID 参数整定:
初始参数:Kp=55, Ki=0, Kd=0.8
现象:温度上升较快但存在超调
优化:增加积分项(Ki=0.1)并降低微分作用
抗干扰措施:
c
// 温度滤波算法(滑动平均滤波)
float Filter_Temp(float new_temp)
{
static float temp_buf[5] = {0};
static u8 index = 0;
temp_buf[index++] = new_temp;
if(index >= 5) index = 0;
float sum = 0;
for(u8 i=0; i<5; i++) sum += temp_buf[i];
return sum / 5;
}
五、测试结果
时间 (s) | 实测温度 (℃) | PWM 输出 (%) | 状态描述 |
---|---|---|---|
0 | 25.0 | 100 | 快速加热 |
30 | 38.5 | 85 | 接近目标值 |
60 | 40.2 | 15 | 超调后稳定 |
120 | 40.0 | 20 | 稳定维持 |

有问题欢迎评论区留言,需要资料滴滴,或者观看b站视频:小陈学长的电子实验室