系统概述
单环PID控制是Buck电路中最基础也是最常用的控制策略,主要通过调节PWM占空比来稳定输出电压。
硬件系统设计
核心组件配置
| 组件 | 型号/参数 | 作用 |
|---|---|---|
| 主控制器 | STM32F103 | PID算法执行,PWM生成 |
| 功率开关 | MOSFET IRF540 | 高频开关 |
| 输出电感 | 100μH | 能量存储,滤波 |
| 输出电容 | 470μF | 输出滤波 |
| 电压采样 | 电阻分压+ADC | 输出电压检测 |
| 电流采样 | 采样电阻+运放 | 可选,用于过流保护 |
关键参数计算
c
// Buck电路参数
#define INPUT_VOLTAGE 12.0f // 输入电压12V
#define OUTPUT_VOLTAGE 5.0f // 目标输出电压5V
#define SWITCHING_FREQ 50000 // 开关频率50kHz
#define INDUCTOR_VALUE 100e-6 // 电感值100μH
#define CAPACITOR_VALUE 470e-6 // 电容值470μF
#define LOAD_RESISTANCE 10.0f // 负载电阻10Ω
// PWM配置
#define PWM_PERIOD 1599 // 72MHz/(50kHz-1)
#define MAX_DUTY 0.95f // 最大占空比限制
#define MIN_DUTY 0.05f // 最小占空比限制
软件实现
1. PID控制器结构
c
// PID控制器结构体
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float Ts; // 采样周期
float integral; // 积分项
float prev_error; // 上一次误差
float output; // 输出值
float output_max; // 输出上限
float output_min; // 输出下限
} PID_Controller;
// PID参数初始化
void PID_Init(PID_Controller *pid, float kp, float ki, float kd, float ts, float out_max, float out_min)
{
pid->Kp = kp;
pid->Ki = ki;
pid->Kd = kd;
pid->Ts = ts;
pid->integral = 0.0f;
pid->prev_error = 0.0f;
pid->output = 0.0f;
pid->output_max = out_max;
pid->output_min = out_min;
}
// PID计算函数(位置式)
float PID_Calculate(PID_Controller *pid, float setpoint, float feedback)
{
float error, derivative;
// 计算误差
error = setpoint - feedback;
// 积分项(带抗饱和)
pid->integral += error * pid->Ts;
// 积分限幅
if(pid->integral > pid->output_max)
pid->integral = pid->output_max;
else if(pid->integral < pid->output_min)
pid->integral = pid->output_min;
// 微分项
derivative = (error - pid->prev_error) / pid->Ts;
// PID输出计算
pid->output = pid->Kp * error +
pid->Ki * pid->integral +
pid->Kd * derivative;
// 输出限幅
if(pid->output > pid->output_max)
pid->output = pid->output_max;
else if(pid->output < pid->output_min)
pid->output = pid->output_min;
// 更新上一次误差
pid->prev_error = error;
return pid->output;
}
2. 增量式PID实现
c
// 增量式PID结构体
typedef struct {
float Kp, Ki, Kd;
float Ts;
float prev_error;
float prev2_error;
float output;
} Incremental_PID;
// 增量式PID计算
float Incremental_PID_Calculate(Incremental_PID *pid, float setpoint, float feedback)
{
float error, delta_output;
error = setpoint - feedback;
// 增量计算
delta_output = pid->Kp * (error - pid->prev_error) +
pid->Ki * error * pid->Ts +
pid->Kd * (error - 2*pid->prev_error + pid->prev2_error) / pid->Ts;
// 累加输出
pid->output += delta_output;
// 输出限幅
if(pid->output > MAX_DUTY) pid->output = MAX_DUTY;
if(pid->output < MIN_DUTY) pid->output = MIN_DUTY;
// 更新误差历史
pid->prev2_error = pid->prev_error;
pid->prev_error = error;
return pid->output;
}
3. ADC采样处理
c
// 电压采样参数
#define VOLTAGE_DIVIDER_RATIO 0.4f // 分压比
#define ADC_REF_VOLTAGE 3.3f // ADC参考电压
#define ADC_RESOLUTION 4095.0f // 12位ADC
// 读取输出电压
float Read_Output_Voltage(void)
{
uint16_t adc_value;
float voltage;
// 启动ADC转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
adc_value = ADC_GetConversionValue(ADC1);
// 转换为电压值
voltage = (adc_value / ADC_RESOLUTION) * ADC_REF_VOLTAGE;
voltage = voltage / VOLTAGE_DIVIDER_RATIO; // 考虑分压比
return voltage;
}
// 移动平均滤波
#define FILTER_WINDOW_SIZE 8
float Moving_Average_Filter(float new_sample)
{
static float buffer[FILTER_WINDOW_SIZE] = {0};
static uint8_t index = 0;
static float sum = 0;
// 减去最旧的值,加上最新的值
sum = sum - buffer[index] + new_sample;
buffer[index] = new_sample;
// 更新索引
index = (index + 1) % FILTER_WINDOW_SIZE;
return sum / FILTER_WINDOW_SIZE;
}
4. PWM生成与控制
c
// PWM初始化
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 配置GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // TIM2_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置定时器
TIM_TimeBaseStructure.TIM_Period = PWM_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 配置PWM通道
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比0
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
TIM_CtrlPWMOutputs(TIM2, ENABLE);
}
// 设置PWM占空比
void Set_PWM_Duty(float duty_cycle)
{
uint16_t pulse;
// 限制占空比范围
if(duty_cycle > MAX_DUTY) duty_cycle = MAX_DUTY;
if(duty_cycle < MIN_DUTY) duty_cycle = MIN_DUTY;
// 计算脉冲值
pulse = (uint16_t)(duty_cycle * PWM_PERIOD);
// 更新比较寄存器
TIM_SetCompare1(TIM2, pulse);
}
5. 主控制循环
c
// 全局变量
PID_Controller voltage_pid;
float output_voltage = 0.0f;
float setpoint_voltage = 5.0f; // 目标输出电压5V
// 系统初始化
void System_Init(void)
{
// 初始化PID控制器
// Kp=0.5, Ki=10.0, Kd=0.001, Ts=0.0001(100μs), 输出范围0-0.9
PID_Init(&voltage_pid, 0.5f, 10.0f, 0.001f, 0.0001f, 0.9f, 0.0f);
// 初始化外设
ADC_Init();
PWM_Init();
// 启用定时中断
Timer_Init(100); // 100us定时中断
}
// 定时中断服务函数(100us)
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
// 清除中断标志
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
// 执行控制算法
Buck_Control_Loop();
}
}
// Buck控制主循环
void Buck_Control_Loop(void)
{
static uint16_t sample_counter = 0;
float duty_cycle;
// 每10次中断采样一次(1ms采样率)
if(++sample_counter >= 10)
{
sample_counter = 0;
// 读取输出电压
output_voltage = Read_Output_Voltage();
// 数字滤波
output_voltage = Moving_Average_Filter(output_voltage);
// PID计算
duty_cycle = PID_Calculate(&voltage_pid, setpoint_voltage, output_voltage);
// 更新PWM输出
Set_PWM_Duty(duty_cycle);
}
}
// 主函数
int main(void)
{
System_Init();
while(1)
{
// 主循环可执行其他任务
// 如通信、状态监测、参数调整等
Monitor_System_Status();
}
}
保护功能实现
过压/欠压保护
c
// 保护参数
#define OVER_VOLTAGE_THRESHOLD 6.0f // 过压阈值6V
#define UNDER_VOLTAGE_THRESHOLD 4.0f // 欠压阈值4V
// 电压保护检查
void Voltage_Protection_Check(void)
{
if(output_voltage > OVER_VOLTAGE_THRESHOLD)
{
// 过压保护:关闭PWM输出
Set_PWM_Duty(0.0f);
// 触发故障处理
Handle_OverVoltage_Fault();
}
else if(output_voltage < UNDER_VOLTAGE_THRESHOLD)
{
// 欠压保护:可记录故障或采取其他措施
Handle_UnderVoltage_Fault();
}
}
软启动功能
c
// 软启动实现
void Soft_Start(float target_voltage, uint32_t start_time_ms)
{
static uint32_t start_tick = 0;
static uint8_t soft_start_active = 0;
if(!soft_start_active)
{
soft_start_active = 1;
start_tick = Get_Tick_Count();
setpoint_voltage = 0.0f; // 从0开始
}
// 线性增加设定值
uint32_t elapsed = Get_Tick_Count() - start_tick;
if(elapsed < start_time_ms)
{
setpoint_voltage = target_voltage * elapsed / start_time_ms;
}
else
{
setpoint_voltage = target_voltage;
soft_start_active = 0;
}
}
PID参数整定方法
经验整定法
c
// Ziegler-Nichols整定法
void Ziegler_Nichols_Tuning(float Ku, float Tu)
{
// Ku: 临界增益,Tu: 临界振荡周期
voltage_pid.Kp = 0.6 * Ku;
voltage_pid.Ki = 1.2 * Ku / Tu;
voltage_pid.Kd = 0.075 * Ku * Tu;
}
// 试凑法参数调整
void Empirical_Tuning(void)
{
// 先调整Kp,使系统快速响应但不过冲
// 再调整Ki,消除稳态误差
// 最后调整Kd,抑制超调
// 典型Buck电路起始参数:
voltage_pid.Kp = 0.1f; // 从小开始
voltage_pid.Ki = 1.0f; // 适当积分
voltage_pid.Kd = 0.001f; // 小微分
}
参考代码 单环PID控制buck电路 www.3dddown.com/csa/73179.html
性能优化技巧
1. 抗积分饱和
c
// 改进的PID计算(带抗积分饱和)
float PID_Calculate_AntiWindup(PID_Controller *pid, float setpoint, float feedback)
{
float error = setpoint - feedback;
// 临时计算输出(不更新积分)
float temp_output = pid->Kp * error +
pid->Ki * pid->integral +
pid->Kd * (error - pid->prev_error) / pid->Ts;
// 只有输出未饱和时才更新积分
if(temp_output < pid->output_max && temp_output > pid->output_min)
{
pid->integral += error * pid->Ts;
}
// 其余计算相同...
// ...
}
2. 设定值平滑
c
// 设定值斜坡变化
void Setpoint_Ramp(float new_setpoint, float ramp_time_ms)
{
static float current_sp = 0;
static float target_sp = 0;
static uint32_t ramp_start = 0;
if(new_setpoint != target_sp)
{
target_sp = new_setpoint;
ramp_start = Get_Tick_Count();
}
uint32_t elapsed = Get_Tick_Count() - ramp_start;
if(elapsed < ramp_time_ms)
{
setpoint_voltage = current_sp + (target_sp - current_sp) * elapsed / ramp_time_ms;
}
else
{
setpoint_voltage = target_sp;
current_sp = target_sp;
}
}
这个单环PID控制Buck电路的实现方案提供了完整的电压闭环控制,具有较好的动态响应和稳态精度。