1. 项目概述
最近在做一个基于STM32的同步Buck降压电源项目,这种数字控制的开关电源方案相比传统模拟控制方式有着明显的优势。同步Buck拓扑在3-30V输入电压范围内特别常见,比如给锂电池供电设备做电压转换就非常合适。
这个方案的核心在于用STM32的定时器产生PWM信号,通过驱动电路控制MOSFET的开关,配合电感、电容实现高效降压。数字控制最大的好处是能灵活调整输出电压和电流限制,还能实时监测各种参数。我实际测试下来效率能达到92%以上,比普通线性稳压器高出一大截。
2. 硬件设计要点
2.1 主控芯片选型
我选择了STM32F103C8T6作为主控,主要考虑几点:
- 72MHz主频足够处理控制算法
- 内置12位ADC用于电压电流采样
- 高级定时器TIM1支持互补PWM输出
- 价格便宜且货源稳定
注意:一定要选带高级定时器的型号,普通定时器无法输出带死区的互补PWM。
2.2 功率电路设计
同步Buck的核心功率器件包括:
- 上管MOSFET:IRF3205(55V/110A)
- 下管MOSFET:IRF3205(与上管同型号)
- 功率电感:47μH一体成型电感(饱和电流10A)
- 输出电容:2个100μF低ESR钽电容并联
关键参数计算:
- 开关频率选择200kHz,在效率和体积间取得平衡
- 电感值计算:
L = (Vin - Vout) × Vout / (Vin × ΔI × fsw)
假设输入12V,输出5V,纹波电流ΔI=1A
L = (12-5)×5/(12×1×200k) ≈ 14.6μH
实际选用47μH留足余量
2.3 驱动电路设计
MOSFET驱动采用专用驱动芯片IR2104,主要特点:
- 自带死区时间控制(约500ns)
- 驱动能力达2A
- 支持自举升压驱动上管
驱动电阻选择10Ω,既能保证开关速度,又不会产生过大振铃。
3. 软件实现
3.1 PWM生成配置
使用TIM1产生互补PWM:
c复制// PWM频率200kHz,72MHz/360=200kHz
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 180-1; // 50%占空比
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// 通道1配置为PWM模式
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 90; // 初始占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
// 互补通道配置
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC1NInit(TIM1, &TIM_OCInitStructure);
// 死区时间配置
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
TIM_BDTRInitStructure.TIM_DeadTime = 36; // 500ns死区
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
3.2 电压电流采样
使用ADC采集输出电压和电感电流:
c复制// ADC配置
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
// 校准ADC
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
// 配置规则通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5); // 输出电压
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles5); // 输出电流
// 启动ADC
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
3.3 控制算法实现
采用电压外环+电流内环的双环控制:
c复制// PID参数
float Kp_v = 0.5, Ki_v = 0.1, Kd_v = 0.02; // 电压环
float Kp_i = 0.8, Ki_i = 0.2, Kd_i = 0.01; // 电流环
// 控制周期1kHz
void TIM2_IRQHandler(void) {
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 读取ADC值
float Vout = ADC_GetConversionValue(ADC1) * 3.3 / 4096 * 11; // 11倍分压
float Iout = (ADC_GetConversionValue(ADC2) * 3.3 / 4096 - 1.65) / 0.1; // 电流传感器100mV/A
// 电压环PID
static float err_v_prev = 0, integral_v = 0;
float err_v = Vref - Vout;
integral_v += err_v;
float derivative_v = err_v - err_v_prev;
err_v_prev = err_v;
float Iref = Kp_v * err_v + Ki_v * integral_v + Kd_v * derivative_v;
// 电流环PID
static float err_i_prev = 0, integral_i = 0;
float err_i = Iref - Iout;
integral_i += err_i;
float derivative_i = err_i - err_i_prev;
err_i_prev = err_i;
float duty = Kp_i * err_i + Ki_i * integral_i + Kd_i * derivative_i;
// 限制占空比
duty = duty > 0.9 ? 0.9 : (duty < 0.05 ? 0.05 : duty);
TIM_SetCompare1(TIM1, (uint16_t)(duty * 180));
}
}
4. 关键问题与解决方案
4.1 开关噪声抑制
实测中发现开关节点有较大振铃,采取以下措施:
- 在MOSFET栅极串联10Ω电阻
- 在开关节点对地加100pF电容
- 使用开尔文连接方式布局功率回路
4.2 自举电容选择
上管驱动需要自举电容,选择0.1μF/50V陶瓷电容:
- 太小会导致驱动电压不足
- 太大会影响高频特性
4.3 电流采样方案
尝试了三种电流采样方式:
- 采样电阻+运放:成本低但损耗大
- 电流互感器:隔离但频响差
- 霍尔传感器:最终选用ACS712,精度高且隔离
5. 性能测试数据
测试条件:输入12V,输出5V/3A
| 测试项目 | 测量值 | 标准要求 |
|---|---|---|
| 输出电压精度 | 5.02V | ±1% |
| 效率 | 92.5% | >90% |
| 纹波电压 | 50mVpp | <100mV |
| 负载调整率 | 0.8% | <2% |
| 线性调整率 | 0.5% | <1% |
6. 实际应用建议
- 散热处理:持续3A输出时MOSFET温升约40℃,建议加装小型散热片
- 布局要点:功率回路尽可能短,信号地与功率地单点连接
- 保护功能:软件中实现了过流、过温保护,触发时关闭PWM输出
这个方案经过实际验证非常稳定,特别适合需要灵活调整输出电压的场合。通过修改PID参数可以优化动态响应,比如给电机供电时需要更快的电流环响应。
