尧图精选

基于STM32的DCM Buck变换器设计与数字PID控制

🕒 发布时间:2026/9/16 13:50:11 📁 来源:尧图网络
简介面向电子信息类毕业设计或课程设计场景这份资料以STM32为主控完成DCM模式下BUCK变换器的软硬件系统设计适合正在做电源方向课题的高校学生也适合嵌入式或电源工程师作为工程参考。资料共227个文件核心包含60个C源码、55个头文件以及启动汇编文件覆盖STM32驱动与应用逻辑同时提供原理图、PCB和库文件便于理解硬件连接另有PDF、Word、PPT等设计文档及多张原理图和实物图片帮助梳理设计流程。整个压缩包约32.62MB结构按功能模块划分从电路设计到代码实现均有清晰呈现。目前已有110人学习下载属于真实毕业设计整理后的实战成果对课题开题、方案论证、电路搭建和代码调试都有直接的借鉴价值。1. 用 STM32 做 DCM 模式的 Buck 变换器这组毕设到底在解什么布克变换器用现成的电源芯片搭出来并不难输入输出电容、反馈电阻、电感一接稳压和过流保护全是芯片内部的事。但“基于 STM32”和“DCM 模式”加进来后难度就变了。功率级要自己搭开关管用定时器输出的 PWM 驱动输出电压和电感电流通过 ADC 回读闭环逻辑全部写在固件里。毕设真正考察的是三件事电感电流在什么条件下进入断续、按 DCM 边界选多大电感、数字 PID 在 100kHz 开关频率下怎么整定。这套组合在答辩时问得最细。DCM 的轻载效率、没有右半平面零点带来的环路优势以及同一输出电压下 DCM 占空比和 CCM 明显不同这几个点能直接看出你是不是真做过。本文以 12V 转 5V、0.8A 输出为目标走完整条链路DCM 边界计算、功率级与采样硬件、STM32 固件闭环最后用示波器验证断续波形和负载阶跃。2. DCM Buck 的临界条件与 STM32 侧的控制策略选择2.1 临界电流公式先判断你的 Buck 到底在哪种模式Buck 变换器处于 CCM 还是 DCM不看负载也不看输入电压只看一个等效条件一个开关周期结束前电感电流是否已经降到零。以 12V 输入、5V 输出为例。假定开关频率 fs100kHz占空比近似 D≈Vout/Vin0.417。电感电流在导通期间从波谷上升到波峰斜率为 (Vin-Vout)/L关断后以斜率 Vout/L 下降。临界状态恰好是波谷到达零的时刻对应负载电流Io_crit Vout * (1-D) / (2 * L * fs)这里的 D 是稳态工作点附近的占空比工程上直接用 CCM 占空比估算即可误差不会影响边界判断。代入 Vout5V、1-D0.583、fs100kHz得到 L2.917/(2 * Io_crit * 100000)。如果想让负载在 0.8A 以内都维持 DCM就取 Io_crit≈0.97A算出来 L≈15uH。反过来如果直接焊一个 100uH 的电感上去这个 Buck 在 0.15A 附近就转入 CCM和题目要求的 DCM 目标就偏了。所以选电感的先后顺序是先确定目标负载范围再用边界公式反推电感上限再考虑饱和电流和绕线电阻而不是先抓一个电感看波形。表 1 是不同电感在 12V/5V/100kHz 下的临界负载电流。表 1 不同电感下的 DCM/CCM 边界电流fs100kHz电感 L (uH)临界电流 Io_crit (A)0.5A 负载时的模式101.46DCM150.97DCM220.66接近边界470.31CCMDCM 的电压增益公式和 CCM 完全不同。CCM 下 Vo/VinDDCM 下Vo/Vin 2D / (D sqrt(D² 8L*fs/R))其中 R 是负载电阻。用 L15uH、R6.25Ω5V/0.8A代入要稳住 5V 输出占空比大约 0.38而 CCM 是 0.417。这里第一个工程含义是 DCM 不能直接用 CCM 的开环占空比否则输出电压偏高第二个含义是 DCM 占空比与负载和电感都相关闭环时 PID 的输出初始范围要留出余量。固件里判断当前工作模式可以在调试阶段加一个简单的边界函数#define L_IND 15e-6f // 实际电感值 #define FS_SW 100e3f // 开关频率 uint8_t is_dcm(float iout) { float d_on 0.38f; // DCM 稳态占空比 float i_crit (5.0f * (1.0f - d_on)) / (2.0f * L_IND * FS_SW); return (iout i_crit) ? 1 : 0; }D_ON 如果按 CCM 估算值 0.417i_crit 算出约 0.97A按 DCM 实际工作点 0.38算出约 1.03A。两个值差别不大固件里判断模式用哪个都行区别只在边界余量。实际控制并不需要实时切换算法DCM 和 CCM 用同一套 PID 在跑这个函数主要用于串口打印调试确认负载变化时模式是否正确切换。2.2 电压模式还是峰值电流模式DCM 下控制方案选择STM32 控制 Buck 的常见做法是电压模式固定频率 PWMADC 只采样输出电压PID 输出直接改占空比。优点是接线少、调起来直观F103 用一个 ADC 通道就够用缺点是它对输入电压突变的响应慢负载阶跃时电压过冲要靠输出电容撑住。另一种是峰值电流模式。做法是在开关管电流路径上串联小采样电阻用比较器把采样电压和 PID 输出的电流基准做比较电感电流达到基准时关断开关。这一方案在 DCM 下特别自然因为每次开关都是从零电流开始上升峰值基准和平均输出电流有确定的比例关系响应速度远快于电压模式。用 STM32 做峰值电流模式有两条路。G431 这类芯片内部自带模拟比较器和 DAC比较器输出可以直接硬件封锁 PWM不需要软件干预。F103 没有内部比较器得外接一颗 LM393 或者用运放搭迟滞比较器门限由 DAC 或 PWM 滤波给出。毕设里如果时间紧先把电压模式跑通、把波形测完整拿到底分再把峰值电流模式作为加分项加进去。2.3 DCM 小信号的特性和数字 PID 的调整侧重点DCM Buck 的功率级传递函数近似为单个极点加一个很远的零点不像 CCM 在占空比大时有右半平面零点环路补偿更简单。但 DCM 有一个副作用功率级增益会随负载变化。PWM 占空比到输出的等效增益近似正比于 sqrt(R)轻载时增益明显高于重载。固定一组 PID 参数在 0.3A 时调稳拿到 0.8A 时环路带宽可能翻倍容易在负载阶跃时振荡。数字实现上控制频率取开关频率的 1/10 到 1/2 都可用。100kHz 开关频率下让 PID 每 8 到 16 个周期执行一次也就是 6.25kHz 到 12.5kHz。采样点必须和 PWM 同步否则输出电压纹波混叠进 ADCPID 会不停抖。第 4 章给的例子就是让定时器触发 ADC 采样从源头消除这个问题。提示DCM 轻载时电感电流有一段时间是零输出电压完全靠输出电容维持。这段时间采样的电压接近真实稳态值适合做闭环反馈开关导通期间采样则会看到明显的纹波台阶。3. 功率级与采样电路STM32 周边的硬件参数计算3.1 电感、输出电容与开关器件的选型按第 2 章的结果设计目标是 12V 输入、5V/0.8A 输出、fs100kHz、L15uH让 Buck 在满载点附近仍维持 DCM。电感选型还要看饱和电流DCM 的电感电流峰值是平均电流的两倍以上按 0.8A 平均、峰值约 2A 算电感饱和电流至少取 3A。输出电容要同时满足电压纹波和负载阶跃两项要求。DCM 下一部分能量直接来自电感另一部分由电容补充。粗算纹波用 ΔVout≈ΔIL*ESR电解电容 ESR 若在 50mΩ 量级2A 的纹波电流会产生 100mV 纹波。常见做法是电解电容并联陶瓷电容470uF 电解负责容量22uF X7R 陶瓷负责压低高频 ESR 纹波整体纹波可以做到 30mV 以内。开关管选 N-MOSFET因为 Buck 的高端开关需要栅极电压高于输入电压。30V/30mΩ 的管子在这个功率下足够AO340030V、约 32mΩ、SOT-23便宜好买驱动电流要求不高。续流管用肖特基二极管SS545A/40V的正向压降只有 0.4V 左右反向恢复电荷几乎为零对 DCM 的高频续流比较友好。3.2 MOSFET 驱动电路自举电容怎么取值高端 N-MOS 的门极电压必须比源极SW 节点高 10V 左右。STM32 的 GPIO 无法直接驱动必须用驱动芯片。常见方案是 IR2104S 加自举电容驱动芯片内部有一个高压悬浮电源轨靠自举电容给高端栅极驱动供电。IR2104S 的接法是输入口接 STM32 的 PWM只用高侧输出VB 与 VS 之间接自举电容。电容取值与开关频率和栅极电荷有关习惯取 1uF 陶瓷电容配一个快恢复二极管到 12V。计算依据是 C_boot Qg_total / ΔV_bootΔV_boot 取实测 VB-VS 纹波的允许值一般是 0.5V 以内。#define QG_N 12e-9f // AO3400 栅极电荷单位 C #define DV_BOOT 0.5f // VB-VS 允许压降单位 V float cboot_min QG_N / DV_BOOT; // 理论值 24nF float cboot_pick cboot_min * 20.0f; // 实际取 0.47uF~1uFAO3400 的 Qg 只有 12nC 左右0.1uF 理论上都够但实际充电路径上还有驱动芯片内部损耗和 PCB 寄生建议至少 0.47uF 以上。驱动部分的典型参数如下器件参数说明U1IR2104S半桥驱动只用高侧C_boot1uF/25V X7R自举电容靠近 VB-VSD_bootUS1M / SS14自举二极管耐压大于 20VR_g4.7Ω栅极串联电阻限制 di/dtC_in100uF10uF输入母线电容靠近功率级R_g 的作用是限制 MOSFET 开关瞬态的栅极电流防止振铃。R_g 取太大开关损耗上升取太小栅极出现振铃4.7Ω 到 10Ω 是粗调起点。3.3 输出电压采样和电流采样链路输出电压采样用电阻分压降到 STM32 ADC 的 3.3V 以内。5V 输出分压到 2.0V 比较合理R127kΩ、R218kΩ分压比 0.4。分压电阻后加一个 RC 滤波1kΩ10nF 是比较常见的组合截止频率约 16kHz能滤掉开关纹波而不会影响 12.5kHz 以下的有效控制信号。电流采样看是否做峰值电流控制。F103 方案里用 50mΩ 采样电阻串联在高端 MOSFET 源极到输入地之间用 INA240 这类仪表放大器放大 20 倍后接到 ADC。这个电阻的功率按 RMS 值计算0.8A 负载 DCM 下 RMS 电流约 0.7A50mΩ 上损耗约 24mW0805 封装的 0.25W 电阻完全够用。注意采样电阻放在高端源极会导致 ADC 参考地与功率地之间有共模噪声。PCB 要单点接地功率地铺完整铜皮STM32 的模拟地单独走线回到输入电容负端避免 ADC 数值在开关瞬间被拉偏。3.4 STM32 最小系统和开发环境F103C8T6 用 8MHz 晶振通过 PLL 倍频到 72MHz。8MHz 晶振配套的负载电容不是随手拿 22pF需要按晶振手册的 CL 值和 PCB 寄生电容反推一般取 10pF 到 22pF。开发环境方面Keil5 要先装 STM32F1 器件支持包或者用 STM32CubeMX 生成工程再导入 Keil5。很多同学卡在芯片包安装这一步表现为 Keil 里找不到 STM32F103C8先装好 DFP 再打开工程就不会出这个问题。如果后面想换成 G431 做更高开关频率CubeMX 里改型号重新生成工程定时器和 ADC 配置基本能平移过去只有高级定时器的死区寄存器略有差异。国内常见的 APM32F103、GD32F103 在多数框架下可以直接用 STM32 源码CubeMX 生成的工程也通常能跑。但不要一上来就怀疑型号兼容性用 ST-LINK Utility 读一次芯片 ID 确认实际型号再开始排查。4. STM32 固件实现PWM、ADC 与 PID 闭环代码4.1 用高级定时器产生 100kHz PWM 并配置死区F103 的 TIM1 是高级定时器输出带互补通道和死区控制用来驱动 IR2104S 很合适。这里只用 CH1 输出互补通道关闭。PWM 频率由定时器时钟和 ARR 决定72MHz/(ARR1)100kHz所以 ARR719。脉冲宽度 CCR 初始值设 270对应占空比约 37.5%。// TIM1_CH1 初始化100kHz PWM TIM_HandleTypeDef htim1; htim1.Instance TIM1; htim1.Init.Prescaler 0; htim1.Init.CounterMode TIM_COUNTERMODE_UP; htim1.Init.Period 719; // 72MHz/(7191)100kHz htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter 0; HAL_TIM_PWM_Init(htim1); TIM_OC_InitTypeDef sConfigOC {0}; sConfigOC.OCMode TIM_OCMODE_PWM1; sConfigOC.Pulse 270; // 初始占空比 270/72037.5% sConfigOC.OCPolarity TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(htim1, sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1);PWM1 模式的意思是计数器计数到 CCR 之前输出有效电平到 ARR 重新开始。占空比(CCR1)/(ARR1)CCR719 时是 100% 占空比。控制里随时改 CCR1 就能实时调压。要注意 F103 高级定时器必须先 HAL_TIM_PWM_Start 一次否则 CH1 引脚一直是低电平。如果后面要用死区配置sConfigOC.OCIdleState和死区寄存器TIM1-BDTRIR2104S 直接用单端 PWM 不需要死区。表 2 TIM1 PWM 关键参数参数值说明ARR719PWM 周期计数Prescaler072MHz 不分频CCR 初值27037.5% 软启动起点PID 调用周期10 个 PWM 周期10kHz 控制频率4.2 ADC 同步采样用 TIM1 触发加 DMA 搬运电压采样如果在主循环里随意读与 PWM 不同步100kHz 的开关纹波会混进 ADC 结果PID 看到的是一路乱跳的数字。正确做法是用定时器触发 ADC 采样让 ADC 在每个 PWM 周期同一时刻启动转换。ADC_HandleTypeDef hadc1; hadc1.Instance ADC1; hadc1.Init.ScanConvMode DISABLE; hadc1.Init.ContinuousConvMode DISABLE; hadc1.Init.DiscontinuousConvMode DISABLE; hadc1.Init.ExternalTrigConv ADC_EXTERNALTRIGCONV_T1TRGO; hadc1.Init.ExternalTrigConvEdge ADC_EXTERNALTRIGCONVEDGE_RISING; hadc1.Init.DataAlign ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion 1; HAL_ADC_Init(hadc1); DMA_HandleTypeDef hdma_adc1; hdma_adc1.Instance DMA1_Channel1; hdma_adc1.Init.Direction DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc DMA_PINC_DISABLE; hdma_adc1.Init.MemInc DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode DMA_CIRCULAR; HAL_DMA_Init(hdma_adc1); __HAL_LINKDMA(hadc1, DMA_Handle, hdma_adc1); HAL_ADC_Start_DMA(hadc1, (uint32_t *)adc_buffer, 32);DMA 开循环模式32 个样本不断写入缓冲区。PID 每次取平均能进一步滤掉高频噪声并对 ADC 偶发的坏点有平滑作用。ExternalTrigConvEdge 必须设为上升沿采样时刻落在 TIM1 计数器溢出瞬间正好是开关周期的起点。此时电感电流刚从零开始上升输出电压接近纹波谷值数值稳定适合作为反馈。CubeMX 里还需要把 TIM1 的 Master-Slave Mode 配置为 Update 事件触发 TRGO否则 ADC 外部触发不会生效。4.3 PID 控制器代码与占空比限幅DCM 下最容易写对的是位置式 PID输出直接代表占空比目标范围限制在 2% 到 90%留出余量给输入电压跌落等瞬态工况。积分项必须加抗饱和否则从空载切入负载时积分会冲到很大输出电压恢复过程出现明显超调。typedef struct { float kp; float ki; float kd; float integral; float last_error; float out_min; float out_max; } pid_t; float pid_update(pid_t *pid, float ref, float fb) { float err ref - fb; float out; pid-integral err; // 抗积分饱和积分限幅跟随输出限幅 if (pid-integral pid-out_max) pid-integral pid-out_max; if (pid-integral -pid-out_max) pid-integral -pid-out_max; out pid-kp * err pid-ki * pid-integral pid-kd * (err - pid-last_error); pid-last_error err; if (out pid-out_max) out pid-out_max; if (out pid-out_min) out pid-out_min; return out; }PID 在另一个定时器中断里每 10 个 PWM 周期调用一次控制频率100kHz/1010kHz。返回值换算成 CCRccr (uint16_t)(duty * 720.0f)duty 范围 0.02 到 0.90。初值给 Kp0.5、Ki0.02、Kd0。Kp 的单位是“占空比比例/伏误差”0.5 意味着 200mV 误差会拉出 10% 占空比变化。DCM 轻载增益高Kp 超过 1.0 后容易出现电感电流嘶嘶声用示波器看到高频抖动就降 Kp。Ki 从零往上加每加一次做一次负载阶跃测试。Kd 在 ADC 有滤波之后才起作用否则只是放大噪声。4.4 过压保护和软启动逻辑固件里除了 PID还要写两个通用保护。输出电压高于 5.5V 或低于 3.8V 时立即关断 PWMADC 采到的电流超过 1.2A 时锁存关断手动复位才恢复。关断用 HAL_TIM_PWM_Stop但要加保护标志位防止主循环又把 PWM 启动回来。软启动的思路是让占空比从 10% 以固定斜率上升直到 PID 输出去接管。上升斜率按每 10 毫秒加 1%从 0 到目标约 300ms 到 500ms。这个阶段绕过 PID在主流程里直接小步长更新 CCR避免上电瞬间冲击电流同时给自举电容充电留出时间。提示不要在控制循环里调用 HAL_Delay。F103 的中断和 DMA 在持续工作一旦卡在阻塞延时里ADC 缓冲区停更PID 会以为电压不变积分项可能被慢慢推上去。这个现象和常见的“延时函数卡死”是一个原因根因在中断优先级配置或头文件里中断打开顺序不对。控制循环保持短、快、无阻塞。5. 用示波器验证 DCM 边界和闭环稳定性几个实操技巧5.1 用开关节点波形确认 DCM 边界没有电流探头看 SW 节点电压也能判断。CCM 下 MOSFET 关断期间SW 被续流二极管钳在约 -0.3V持续到下次开通DCM 下电感电流到零后SW 电位会浮起来被输出电容通过电感拉到 Vo 附近。波形上出现一段等于输出电压的平台就说明确实断续了。把负载往上调平台逐渐缩短直到消失那个点对应实际边界电流可以和公式算出的约 0.97A 对照。5.2 负载阶跃调 PID只看两个指标用电子负载在 0.2A 和 0.8A 之间按 100Hz 跳变记录电压过冲和恢复时间。过冲大加 Kp出现 20kHz 以上振铃先清零 Kd电压缓慢爬升后超过稳定值再回落是 Ki 过大几十赫兹低频抖动则是采样与 PID 执行不同步。每次只改一个参数记录结果毕业答辩直接拿这张表讲KpKiKd过冲 mV恢复 ms现象0.5002202.8无振荡0.8001501.9轻微高频噪声0.80.0201601.2稳定1.00.050.52804.5振铃不可用5.3 三个容易翻车的量测细节第一探头地线接太远会量出一堆假振铃用弹簧地线直接搭在功率地铜皮上再看 SW 波形。第二输出纹波要开 20MHz 带宽限制关掉时看到的高频毛刺不是 DC-DC 的真实纹波会误导你给输出电容加过大的容量。第三自举电容太小会导致上电后 PWM 停发表现为输出电压上不来或掉电重启把 VB-VS 电压接到示波器如果低于 8V加大自举电容到 1uF 以上再验证。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →