1. 项目概述:基于STM32F103的高效数控Buck电源设计
去年在调试一个嵌入式项目时,经常需要不同电压等级的直流电源,市面上的可调电源要么价格昂贵,要么调节不便。于是萌生了自己设计一款数控Buck电源的想法。经过三个版本的迭代,最终实现的这个基于STM32F103的同步整流Buck电源,实测效率达到96%,支持0-30V连续可调,最大输出电流5A,整套成本不到50元。
这个设计的核心优势在于:
- 采用同步整流技术,相比传统二极管方案效率提升显著
- 全数字化控制,电压调节通过程序直接修改目标值即可
- 增量式PI算法实现快速稳定的闭环控制
- 硬件设计简洁可靠,全部使用常见元器件
2. 硬件设计详解
2.1 功率级设计
功率级采用经典的Buck拓扑,但创新性地使用了同步整流技术。主开关管和同步整流管均采用NRF540N MOSFET,这款管子的优势在于:
- VDS=40V,ID=33A,完全满足设计需求
- Rds(on)仅44mΩ(VGS=10V时)
- 栅极电荷Qg=18nC,开关速度快
实测对比:
| 整流方案 | 效率@5A输出 | 温升 |
|---|---|---|
| 肖特基二极管 | 89% | 65℃ |
| 同步整流 | 96% | 42℃ |
关键提示:同步整流必须设置合理的死区时间,否则会导致上下管直通。根据IR2104的520ns传播延迟,我们设置0.875us死区时间。
2.2 驱动电路设计
驱动芯片选用IR2104,这款半桥驱动器的特点:
- 峰值输出电流0.6A
- 内置死区时间控制
- 工作电压10-20V
自举电路设计要点:
- 自举电容Cboot=0.1μF陶瓷电容
- 并联10Ω电阻用于抑制高频振荡
- 自举二极管选用快恢复二极管1N4148
实测驱动波形:
- 上升时间:18ns
- 下降时间:22ns
- 过冲:<5%
2.3 采样电路设计
电压电流采样是闭环控制的基础,本设计采用两路独立采样:
电流采样:
- 采样电阻:0.01Ω锰铜丝(5W规格)
- 放大电路:LM385构成100倍差分放大
- 带宽限制:RC低通滤波(fc≈1kHz)
电压采样:
- 分压电阻:10kΩ+2kΩ(1%精度)
- 滤波电容:0.1μF陶瓷电容
- 采样精度:±0.5%
ADC配置要点:
c复制void ADC_Config(void) {
ADC_InitTypeDef adc;
ADC_StructInit(&adc);
adc.ADC_ContinuousConvMode = DISABLE;
adc.ADC_DataAlign = ADC_DataAlign_Right;
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc.ADC_ScanConvMode = DISABLE;
ADC_Init(ADC1, &adc);
// 电流采样通道8,电压采样通道9
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);
}
3. 软件实现解析
3.1 PWM生成配置
TIM1配置为中央对齐PWM模式,关键参数:
- 开关频率:50kHz
- 时钟预分频:72MHz/(50kHz*1000) = 1.44 → 取1
- 自动重装载值:72000000/(50000*1) -1 = 1439
具体初始化代码:
c复制void PWM_Init(void) {
TIM_TimeBaseInitTypeDef tim;
TIM_TimeBaseStructInit(&tim);
tim.TIM_Prescaler = 0;
tim.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
tim.TIM_Period = 1439;
TIM_TimeBaseInit(TIM1, &tim);
TIM_OCInitTypeDef oc;
TIM_OCStructInit(&oc);
oc.TIM_OCMode = TIM_OCMode_PWM1;
oc.TIM_OutputState = ENABLE;
oc.TIM_Pulse = 720; // 初始50%占空比
TIM_OC1Init(TIM1, &oc); // CH1
TIM_OC2Init(TIM1, &oc); // CH1N
TIM_BDTRInitTypeDef bdtr;
bdtr.TIM_DeadTime = 63; // 0.875us
TIM_BDTRConfig(TIM1, &bdtr);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
}
3.2 增量式PI算法实现
相比位置式PI,增量式算法具有以下优势:
- 无积分饱和问题
- 输出变化平滑
- 更易实现抗积分饱和
算法结构体定义:
c复制typedef struct {
float Kp;
float Ki;
float Err[2]; // 当前和前一次误差
float OutMax; // 输出限幅
} PI_Controller;
算法实现:
c复制float PI_Calculate(PI_Controller *pi, float target, float actual) {
float err = target - actual;
float delta = pi->Kp*(err - pi->Err[0]) + pi->Ki*err;
// 限幅处理
static float out = 0;
out += delta;
if(out > pi->OutMax) out = pi->OutMax;
if(out < 0) out = 0;
// 更新误差记录
pi->Err[0] = pi->Err[1];
pi->Err[1] = err;
return out;
}
参数整定方法:
- 先将Ki设为0,逐渐增大Kp直到系统出现临界振荡
- 记录此时的Kp值为Kpc
- 取Kp=0.5Kpc,Ki=0.1Kp
- 微调直到响应速度和超调量达到平衡
3.3 控制环路实现
控制环路在1ms定时中断中执行,流程如下:
- 读取ADC采样值
- 转换为实际电压/电流值
- 执行PI计算
- 更新PWM占空比
电压转换公式:
c复制float Get_Voltage(void) {
uint16_t adc = ADC_GetConversionValue(ADC1, 2);
return adc * 3.3f / 4096 * (10+2)/2; // 分压比(10k+2k)/2k
}
电流转换公式:
c复制float Get_Current(void) {
uint16_t adc = ADC_GetConversionValue(ADC1, 1);
return adc * 3.3f / 4096 / 0.01 / 100; // 0.01Ω采样电阻,100倍放大
}
4. 关键问题与解决方案
4.1 开关噪声干扰ADC采样
现象:ADC采样值出现周期性波动
解决方法:
- 将ADC采样时刻设置在PWM周期中间
- 添加硬件RC滤波(10Ω+0.1μF)
- 软件采用滑动平均滤波
4.2 同步整流管体二极管导通
现象:轻载时效率下降明显
解决方法:
- 增加最小占空比限制(约5%)
- 轻载时切换为PWM-PFM混合模式
- 优化死区时间设置
4.3 启动冲击电流
现象:上电瞬间出现大电流脉冲
解决方法:
- 实现软启动功能
- 初始占空比从0开始线性增加
- 添加输出电流限制
软启动实现代码:
c复制void Soft_Start(float target_voltage) {
float voltage = 0;
while(voltage < target_voltage) {
voltage += 0.1; // 每ms增加0.1V
if(voltage > target_voltage)
voltage = target_voltage;
Voltage_Target = voltage;
Delay_ms(1);
}
}
5. 性能测试数据
测试条件:输入24V,环境温度25℃
| 输出电压 | 输出电流 | 效率 | 纹波(mVpp) | 调整时间(ms) |
|---|---|---|---|---|
| 5V | 1A | 94% | 25 | 30 |
| 12V | 3A | 96% | 28 | 45 |
| 24V | 5A | 95% | 35 | 60 |
温度测试(满载5A输出30分钟):
- MOSFET温度:58℃
- 电感温度:62℃
- PCB最高温度:45℃
6. 扩展功能实现
6.1 串口调压功能
通过USART实现命令控制:
c复制void USART_Process(char *cmd) {
if(strncmp(cmd, "SET ", 4) == 0) {
float voltage = atof(cmd+4);
if(voltage >= 0 && voltage <= 30) {
Voltage_Target = voltage;
printf("OK %.1fV\r\n", voltage);
}
}
}
6.2 恒流模式实现
在恒流模式下,PI控制器以电流为反馈量:
c复制if(Mode == CURRENT_MODE) {
float current = Get_Current();
duty = PI_Calculate(&pi_current, Current_Target, current);
} else {
float voltage = Get_Voltage();
duty = PI_Calculate(&pi_voltage, Voltage_Target, voltage);
}
6.3 过流保护功能
在ADC中断中添加保护判断:
c复制if(Get_Current() > 5.5) { // 5.5A过流保护
PWM_Disable();
Fault_Flag = 1;
}
7. 制作注意事项
-
PCB布局要点:
- 功率回路尽可能短而宽
- 驱动信号远离功率走线
- 采样走线采用差分对形式
-
元器件选型:
- 输出电容选用低ESR的固态电容
- 电感选择饱和电流足够的屏蔽式电感
- MOSFET的VGS(th)要匹配驱动电压
-
调试技巧:
- 先用可调电源供电调试控制电路
- 逐步增加输入电压观察波形
- 使用电子负载测试动态响应
这个项目最让我惊喜的是,通过合理的软硬件协同设计,用低成本元器件也能实现高性能的数控电源。特别是在优化PI参数后,系统的动态响应完全不输专业电源。整个开发过程中积累的调试经验,比如如何用示波器准确测量开关损耗、如何通过波形分析优化死区时间等,都是教科书上很难学到的实战技巧。
