单环PID控制Buck电路实现方案

系统概述

单环PID控制是Buck电路中最基础也是最常用的控制策略,主要通过调节PWM占空比来稳定输出电压。

硬件系统设计

核心组件配置

组件型号/参数作用
主控制器STM32F103PID算法执行,PWM生成
功率开关MOSFET IRF540高频开关
输出电感100μH能量存储,滤波
输出电容470μF输出滤波
电压采样电阻分压+ADC输出电压检测
电流采样采样电阻+运放可选,用于过流保护

关键参数计算

// 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控制器结构

// 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实现

// 增量式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采样处理

// 电压采样参数
#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生成与控制

// 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. 主控制循环

// 全局变量
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();
    }
}

保护功能实现

过压/欠压保护

// 保护参数
#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();
    }
}

软启动功能

// 软启动实现
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参数整定方法

经验整定法

// 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. 抗积分饱和

// 改进的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. 设定值平滑

// 设定值斜坡变化
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电路的实现方案提供了完整的电压闭环控制,具有较好的动态响应和稳态精度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值