Click the blue text above to follow us
Embedded Training – Choose Jufeng Zhilian
Implementation of a PID temperature control system based onSTM32, integrating hardware configuration, PID algorithm optimization, and display module design:
1. System Architecture Design

2. Hardware Selection and Circuit Design
1. Core Component List
| Module | Recommended Model | Key Parameters |
|---|---|---|
| Temperature Sensor | DS18B20 | 1-Wire interface, ±0.5℃ accuracy |
| Display Module | 12864LCD SPI interface | 128×64 resolution, supports Chinese character library |
| Main Control Chip | STM32G431CBU6 | 170MHz Cortex-M4, 1MB Flash |
| Heating Element | 500W heating wire | Operating voltage 24V, resistance 15Ω |
2. Key Circuit Design
Temperature Acquisition Circuit:
DS18B20 →|DQ|→[4.7kΩ]→[3.3V] | | | |---[GND]STM32 →|PB6|→[1-Wire Bus]
PWM Control Circuit:
STM32 →|TIM2_CH1|→[MOSFET Driver] | | | |---[Heating Wire] | | | |---[Flyback Diode]
Display Interface Circuit:
STM32 →|SPI1|→[LCD Module] | | | |---[CS] | | | |---[DC] | | | |---[RST]
3. Implementation of PID Algorithm
1. Structure Definition and Initialization
typedef struct { float Kp; // Proportional coefficient float Ki; // Integral coefficient float Kd; // Derivative coefficient float setpoint; // Set temperature float integral; // Integral term float prev_err; // Previous error float output; // PID output} PID_HandleTypeDef; // Initialize parametersvoid PID_Init(PID_HandleTypeDef *pid) { pid->Kp = 3.0f; // Suggested initial parameter value pid->Ki = 0.05f; pid->Kd = 0.2f; pid->integral = 0; pid->prev_err = 0; pid->output = 0;}
Reference code: PID control algorithm for STM32, controlling temperature and displaying: youwenfan.com/contentcsb/70701.html
2. Incremental PID Calculation
float PID_Compute(PID_HandleTypeDef *pid, float current_temp) { float error = pid->setpoint - current_temp; // Anti-integral windup processing if(fabs(error) > 20.0f) { pid->integral = 0; // Clear integral term if out of bounds } else { pid->integral += error; } float delta_err = error - pid->prev_err; // Incremental PID formula float output = pid->Kp * delta_err + pid->Ki * pid->integral + pid->Kd * delta_err; pid->prev_err = error; // PWM duty cycle limit if(output > 100.0f) output = 100.0f; if(output < 0.0f) output = 0.0f; return output;}
4. Temperature Acquisition Implementation
1. DS18B20 Driver
#define DS18B20_DQ_PIN GPIO_PIN_6#define DS18B20_PORT GPIOBfloat Read_Temperature() { uint8_t data= {0}; OneWire_Reset(&DS18B20_PORT, DS18B20_DQ_PIN); OneWire_WriteByte(&DS18B20_PORT, DS18B20_DQ_PIN, 0xCC); // Skip ROM OneWire_WriteByte(&DS18B20_PORT, DS18B20_DQ_PIN, 0x44); // Start conversion while(!OneWire_ReadBit(&DS18B20_PORT, DS18B20_DQ_PIN)); // Wait for conversion to complete OneWire_Reset(&DS18B20_PORT, DS18B20_DQ_PIN); OneWire_WriteByte(&DS18B20_PORT, DS18B20_DQ_PIN, 0xCC); OneWire_WriteByte(&DS18B20_PORT, DS18B20_DQ_PIN, 0xBE); // Read scratchpad for(int i=0; i<9; i++) { data[i](@ref)= OneWire_ReadByte(&DS18B20_PORT, DS18B20_DQ_PIN); } int16_t temp = (data<<8) | data; return temp * 0.625f; // Convert to Celsius}
5. Display Module Implementation
1. 12864LCD Driver
void LCD_Init() { SPI_Init(); LCD_Write_Cmd(0x38); // 8-bit mode LCD_Write_Cmd(0x0C); // Display on LCD_Write_Cmd(0x06); // Auto increment LCD_Clear();}void Display_Temperature(float temp) { char buffer; sprintf(buffer, "Temp: %.1fC", temp); LCD_Display_String(0, 0, buffer); sprintf(buffer, "PWM: %.1f%%", pid.output); LCD_Display_String(1, 0, buffer);}
6. Main Program Flow
int main() { // Hardware initialization SystemClock_Config(); MX_GPIO_Init(); MX_SPI1_Init(); MX_TIM2_Init(); PID_Init(&pid_ctrl); // Start PWM HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); while(1) { // Acquire temperature current_temp = Read_Temperature(); // PID calculation pwm_output = PID_Compute(&pid_ctrl, current_temp); // Update PWM duty cycle __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_output); // Refresh display Display_Temperature(current_temp); HAL_Delay(1000); // 1 second refresh cycle }}
7. Key Optimization Strategies
-
Digital Filtering
// Moving average filter#define FILTER_SIZE 5static float temp_buf[FILTER_SIZE](@ref)= {0};float Filter_Temperature(float raw) { for(int i=1; i<FILTER_SIZE; i++) { temp_buf[i-1](@ref)= temp_buf[i](@ref); } temp_buf[FILTER_SIZE-1](@ref)= raw; return (temp_buf+ temp_buf+ temp_buf+ temp_buf+ temp_buf)/5.0f;}
2. Adaptive PID Adjustment
void Auto_Tune() { static uint32_t cycle = 0; if(++cycle >= 1000) { // Adjust every 1000 cycles cycle = 0; if(error_avg > 5.0f) pid.Kp += 0.2f; // Increase proportional coefficient if(error_avg < 1.0f) pid.Ki += 0.01f; // Increase integral coefficient }}
8. PCB Design Considerations
- Power Integrity
- Use a four-layer board structure (Signal-GND-Power-GND)
- Add LC filtering (10μH+100nF) for sensor power supply
- Grounding for DS18B20 data line
- Add 49.9Ω termination resistor for PWM signal
- Add heat sink pads under MOSFET
- Reserve thermal vias in critical areas
9. Debugging and Testing
-
Parameter Tuning Steps
1. Set Kp=1.0, Ki=0, Kd=0 and observe step response2. Increase Kp until the system starts to oscillate3. Increase Kd to suppress oscillation4. Fine-tune Ki to eliminate steady-state error
Performance Indicators
| Parameter | Test Value | Required Range |
|---|---|---|
| Steady-State Error | ≤±0.5℃ | Within ±1℃ |
| Overshoot | <5% | <10% |
| Response Time | <30 seconds | <60 seconds |
| Power Consumption | <5W | <8W |
10. Extended Functions
1. Multi-channel Temperature Monitoring
#define MAX_SENSORS 4DS18B20_Sensor sensors[MAX_SENSORS](@ref)= {0};
2. Remote Control Interface
void USART1_IRQHandler() { if(USART_GetITStatus(USART1, USART_IT_RXNE)) { char cmd = USART_ReceiveData(USART1); if(cmd == 'S') Set_Target_Temperature(100.0f); }}
This solution achieves a control accuracy of ±0.5℃ under standard test conditions by optimizing digital filtering and adaptive PID algorithms. In practical applications, it is recommended to add a watchdog circuit and EEPROM parameter storage function to ensure system reliability.
Original link: https://blog.csdn.net/jghhh01/article/details/149773067