基于STM32的温度PID控制系统实现

2025-12-15

基于STM32的温度PID控制系统实现


一、系统架构设计

1.1 核心模块选型

模块 推荐型号 关键参数
温度传感器 DS18B20 12位分辨率,±0.5℃精度
执行机构 TEC1-12706 最大温差60℃,电流6A
电压基准 REF3030 3.0V±0.05%精度
电流检测 ACS712ELC-05 5A量程,±1.5%误差

二、硬件接口实现

2.1 传感器接口电路

DS18B20连接方案:
VDD → 3.3V
GND → GND
DQ → PB6 (AF_OD模式)
上拉电阻 → 4.7kΩ

TEC驱动电路:
TEC+ → BD237集电极
TEC- → GND
控制端 → PB8 (PWM输出)

2.2 执行机构驱动

// TEC驱动配置
void TEC_Init() {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

// PWM配置(TIM1通道1)
void PWM_Config(uint16_t period) {
    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = period/2; // 50%占空比
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
}

三、PID算法实现

3.1 结构体定义

typedef struct {
    float Kp;         // 比例系数
    float Ki;         // 积分系数
    float Kd;         // 微分系数
    float setpoint;   // 设定温度
    float error;      // 当前误差
    float prev_error; // 上次误差
    float integral;   // 积分项
    float derivative; // 微分项
    float output;     // 控制输出
} PID_Controller;

3.2 增量式PID算法

float PID_Compute(PID_Controller *pid, float current_temp) {
    pid->error = pid->setpoint - current_temp;
    
    // 比例项
    float Pout = pid->Kp * pid->error;
    
    // 积分项(带抗积分饱和)
    pid->integral += pid->error;
    if(pid->integral > pid->integral_max) pid->integral = pid->integral_max;
    if(pid->integral < pid->integral_min) pid->integral = pid->integral_min;
    float Iout = pid->Ki * pid->integral;
    
    // 微分项(带噪声滤波)
    float derivative = (pid->error - pid->prev_error) / PID_SAMPLE_TIME;
    derivative = (derivative + pid->prev_derivative) / 2; // 移动平均滤波
    float Dout = pid->Kd * derivative;
    
    // 输出合成
    pid->output = Pout + Iout + Dout;
    pid->output = constrain(pid->output, -100.0, 100.0); // 限幅
    
    // 更新历史值
    pid->prev_derivative = derivative;
    pid->prev_error = pid->error;
    
    return pid->output;
}

四、温度采集系统

4.1 DS18B20驱动

#define DS18B20_RESET()     { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); HAL_Delay(500); }
#define DS18B20_WRITE_BYTE(b) { for(uint8_t i=0; i<8; i++){...} }
#define DS18B20_READ_BYTE()   { for(uint8_t i=0; i<8; i++){...} }

float DS18B20_ReadTemp() {
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC); // 跳过ROM
    DS18B20_WriteByte(0x44); // 启动转换
    while(!DS18B20_ReadBit()); // 等待转换完成
    
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC);
    DS18B20_WriteByte(0xBE); // 读取暂存器
    uint8_t tempL = DS18B20_ReadByte();
    uint8_t tempH = DS18B20_ReadByte();
    
    int16_t temp = (tempH << 8) | tempL;
    return temp * 0.0625; // 转换为℃
}

4.2 Pt1000信号调理

Pt1000接口电路:
VCC → REF3030 (+3.3V)
GND → GND
Pt1000 → 运算放大器输入
输出 → STM32 ADC1_IN0

ADC配置:
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
uint32_t adc_val = HAL_ADC_GetValue(&hadc1);
float R = (adc_val / 4095.0) * 3300.0; // 12位ADC,3.3V参考
float temp = (-245.3 + 2.5*R + 0.0006*R*R) / 1000; // Callendar-Van Dusen方程

五、自整定PID参数

5.1 模糊自整定算法

void Fuzzy_Tune() {
    float error = setpoint - current_temp;
    float delta_error = error - prev_error;
    
    // 模糊规则库(示例)
    if(error > 2.0 && delta_error > 0.5) {
        Kp += 0.2; Ki *= 0.9; Kd += 0.1;
    } else if(error < 0.5 && delta_error < -0.3) {
        Kp *= 0.8; Ki += 0.15; Kd *= 0.9;
    }
    
    // 参数限制
    Kp = constrain(Kp, 0.5, 10.0);
    Ki = constrain(Ki, 0.0, 2.0);
    Kd = constrain(Kd, 0.0, 5.0);
}

5.2 Ziegler-Nichols整定

void ZN_Tune() {
    // 阶跃响应法获取临界增益
    float Ku = 0.0, Tu = 0.0;
    while(!oscillation_detected()) {
        Ku += 0.1;
        Set_PID(Ku, 0, 0);
        HAL_Delay(1000);
    }
    
    // 计算参数
    Kp = 0.6 * Ku;
    Ki = 1.2 * Ku / Tu;
    Kd = 0.075 * Ku * Tu;
}

参考代码 利用STM32进行温度PID控制 www.3dddown.com/csa/56674.html

六、系统集成与调试

6.1 主程序流程

int main() {
    SystemInit();
    ADC_Config();
    PWM_Config(1000); // 1kHz PWM
    PID_Init(&pid, 2.0, 0.5, 0.1);
    
    while(1) {
        current_temp = Read_Temperature(); // 多传感器融合
        pid_output = PID_Compute(&pid, current_temp);
        Set_PWM_Duty(pid_output);
        
        // 每10秒自整定一次
        if(timer_flag) {
            Fuzzy_Tune();
            Save_ParamsToEEPROM();
        }
    }
}

6.2 抗干扰措施

  1. 硬件滤波:在ADC输入端添加RC低通滤波器(1kΩ+100nF)

  2. 软件滤波:移动平均滤波(5点采样)

    float Moving_Average(float new_val) {
        static float buffer[5] = {0};
        buffer[0] = buffer[1];
        buffer[1] = buffer[2];
        buffer[2] = buffer[3];
        buffer[3] = buffer[4];
        buffer[4] = new_val;
        return (buffer[0]+buffer[1]+buffer[2]+buffer[3]+buffer[4])/5;
    }
    
  3. 看门狗定时器:防止程序跑飞

    void IWDG_Config() {
        IWDG_WriteAccessCmd(ENABLE);
        IWDG_SetPrescaler(IWDG_PRESCALER_4);
        IWDG_SetReload(4095); // 2秒超时
        IWDG_Enable();
    }
    

七、扩展功能实现

7.1 多传感器融合

float Sensor_Fusion() {
    float temp1 = DS18B20_ReadTemp();
    float temp2 = Pt1000_ReadTemp();
    float temp3 = DS18B20_ReadTemp(); // 冗余传感器
    
    // 加权平均算法
    return 0.6*temp1 + 0.3*temp2 + 0.1*temp3;
}

7.2 人机交互界面

void Display_Menu() {
    LCD_Clear();
    LCD_DisplayString("Set Temp:");
    LCD_DisplayNum(setpoint);
    LCD_DisplayString("℃  ");
    
    LCD_DisplayString("PID:");
    LCD_DisplayNum(pid.Kp);
    LCD_DisplayString(" ");
    LCD_DisplayNum(pid.Ki);
    LCD_DisplayString(" ");
    LCD_DisplayNum(pid.Kd);
}

八、典型应用场景

  1. PCR温控系统:实现±0.1℃精准控温
  2. 恒温培养箱:多区域独立温控
  3. 电池热管理:快速充放电温度控制
  4. 医疗设备:手术器械温度监测