简介2015年全国大学生电子设计竞赛双向DC-DC变换器完整解决方案内含原理图、PCB源文件、基于STC12C5A60S2的C语言源代码及设计论文面向电赛参赛队伍、电源设计初学者及需要完整赛题复现的开发者。资源共25个文件覆盖Altium Designer电路工程.SchDoc/.PcbDoc、Keil程序源码.c/.h/.hex/.a51、设计说明文档.docx及工程备份文件压缩包仅5.14MB目录清晰便于按需提取。已有5858人学习使用。方案针对30V电池恒流充电场景实现充电电流1~2A步进0.05A可调、24~36V电压波动下电流变化率低至0.8%等高精度指标文档与源码配合可帮助理解双向DC-DC的环路控制与PWM实现直接用于竞赛参考或二次开发。 2015年电赛A题的双向DC-DC变换器我愿称之为当年“最容易看懂题目、最容易做砸系统”的一道题。题目本身不绕弯子24V直流母线和12V蓄电池之间做双向能量转换充电时降压、放电时升压全程要稳定、要效率、要保护。四天三夜下来不少人一大半时间都在跟炸管、振铃、电流失控作斗争。这篇就结合我当年整理的那份资料包——原理图、PCB源文件、源代码、论文——把这道题的完整设计链路过一遍重点是每个环节为什么要这么干以及最容易踩的坑在哪。1. 这道题的分值点放在哪先搞清楚方向再动手1.1 当年题目的核心指标我按这个参数链来设计以当年的赛题要求来说核心指标可以归纳成一条完整的参数链直流母线侧额定电压24V蓄电池侧额定电压12V充电方向母线向电池降压要求能恒流、恒压充电放电方向电池向母线升压要求能恒流输出效率尽量高通常赛题会对效率设定门槛90%是常见分界线具备过流保护防止电池短路或负载异常时烧毁主功率器件。我把这条参数链列出来的原因是它决定了后面所有选型和参数计算的起点。很多人上来就画板子结果电感多大、电容多大、MOS管耐压多少全是拍脑袋最后效率上不去、管子过热根本原因就是没从指标倒推设计。1.2 “双向”的正确理解方式“双向DC-DC”这个说法容易把人带偏觉得是不是要做两个独立的Buck和Boost然后拿继电器切换。其实题目要求的是同一个功率电路里能量可以反向流动不是物理上做成两套电源。以双向Buck-Boost拓扑为例电路本质上是一个半桥结构加一个电感两只MOS管Q1和Q2串联在母线正负之间电感一端接SW点两只管子中间另一端接电池正极。降压模式时Q1作为主开关管高频动作Q2作为续流管升压模式时Q2作为主开关管高频动作Q1作为输出整流管。两只管子都不需要真的做“角色互换之外的额外动作”关键是控制逻辑要跟着模式切换。更准确地说这就是同步Buck电路和同步Boost电路共享同一套功率级的形态。理解这一点之后你就能明白所谓“双向”本质上是PWM控制策略在不同模式下的切换而不是硬件结构的复制。1.3 资料包里这套方案的总体架构当时资料包里的方案以STM32F103C8T6为控制核心。功率级采用双向Buck-Boost拓扑驱动用IR2104半桥驱动器电流采样用低阻采样电阻加INA282放大电压采样用电阻分压配合OLED显示电压电流外加按键切换工作模式软件里跑状态机加数字PID。这套架构放到今天依然不过时属于电赛双向变换器题目的标准答案之一。STM32F103C8T6这颗芯片在当年的竞赛里几乎是标配72MHz主频、ADC、高级定时器TIM1带互补PWM输出资源完全够用。选它而不是用纯硬件模拟方案是因为题目要求的恒流恒压切换、模式管理、保护逻辑用软件实现更灵活调试周期也短。2. 主功率电路设计双向Buck-Boost不是两个电源背靠背2.1 拓扑对比为什么是Buck-Boost而不是Cuk或反激当年肯定有人想过用隔离方案比如反激或正激。但从题目出发电池和母线本来就共地没有隔离需求非隔离拓扑效率天然更高、控制更简单所以反激首先排除。Cuk和Sepic拓扑也能实现升降压但元器件多、电容应力大、效率也不占优。对24V/12V这个电压组合来说Buck-Boost的开关管电压应力只有母线电压加振铃电感电流是连续的功率密度和效率都更合适。如果你翻过一些参考设计会发现双向Buck-Boost几乎就是这类题目的主流答案。原因是它结构简单两个MOS管、一个电感、输入输出电容没了。而控制逻辑也清晰降压模式Q1动作Q2续流升压模式Q2动作Q1续流。调试时我们甚至可以先用开环逐级验证再上闭环。2.2 电感、电容、开关管的参数计算以100kHz为例这部分建议你拿计算器走一遍因为参数直接从技术指标推出来的不是为了凑数。先定开关频率。100kHz是变压器式变换器的常用值对MOS管开关损耗、电感体积、噪声都算均衡。接下来以降压模式为例母线24V、电池12V占空比D大约0.5。如果按电池侧额定功率120W来估算电池端平均电流10A。取纹波电流为平均电流的20%也就是ΔI2A。电感量计算公式L (Vin - Vout) × D / (ΔI × fs)代入L(24-12)×0.5/(2×100000)30μH。实际选型取标称值33μH考虑到电感电流偏大容易饱和绕制时用铁硅铝磁环不要用普通工字电感那个磁芯两下就饱和了。输出电容按纹波电压50mV来算最低需要C ΔI / (8 × fs × ΔV) 2/(8×100000×0.05)50μF但这只是理想电容值陶瓷电容的直流偏压特性会导致实际容量下降所以最终并了多个22μF/25V陶瓷电容和两个470μF/35V电解电容一个靠近输入、一个靠近电池侧目的是兼顾高频纹波和低频能量。开关管选型耐压至少留一倍裕量母线24V关断瞬间SW点振铃峰值经常冲到40V以上选55V档位是底线。电流按最大10A算留2倍裕量。当时用的IRF320555V、110A、8mΩ内阻虽然性能参数远超需求但散热压力小很多不容易炸。2.3 驱动电路IR2104自举与死区设置MOS管需要栅极驱动器STM32的GPIO直接驱动不了大电流栅极电容的快速开关。IR2104是半桥驱动芯片自带死区时间典型520ns左右这个死区对防止上下管直通很有价值。IR2104的硬件连接不难但有两个细节容易忽略。第一个是自举电容。VS端接SW点VB和VS之间需要一颗自举电容典型值0.1μF到1μF我用了0.22μF陶瓷电容。自举电容负责给上管栅极提供悬浮供电选小了会导致高边驱动能力不足、上管不完全导通、导通损耗剧增选大了充电恢复时间变长高占空比时会出问题。100kHz下0.22μF是常用值。第二个是自举二极管必须用快恢复二极管比如UF4007不能用普通1N4007。自举二极管的恢复时间太长会拖慢高压侧充电导致上管驱动波形畸变严重时管子直接发热炸掉。VCC供电我用24V母线先降到12V给IR2104因为IR2104的推荐工作电压在10V到20V之间12V驱动栅极电压足够让IRF3205完全开通。3. 采样和保护电路闭环里最容易翻车的一环3.1 电流采样方案对比电流采样是双向变换器闭环的关键。不能用电流互感器因为直流分量无法通过。霍尔传感器ACS712倒是能隔离但带宽低、零漂大、价格贵而且竞赛环境下精度不够理想。最实用的方案是采样电阻差分放大器。电流经过毫欧级采样电阻产生压降再用仪表放大器或专用电流检测放大器放大。当时用的INA282固定放大50倍带宽高、共模抑制比好非常适合这个场景。采样电阻选5mΩ合金电阻额定功率3W以上。10A电流下压降50mV功耗PI²R0.5W还在安全范围内。如果你用的是普通贴片电阻而不是合金电阻精度和温漂会让你崩溃校准完一批换一个温度又偏了。需要在采样电阻和放大器之间加一个RC低通滤波截止频率放在1MHz左右滤除开关噪声的同时保留控制带宽。滤波器时间常数不要太大否则采样信号延迟会导致PID相位裕度不足系统不稳定。3.2 恒压恒流模式切换的关键充电过程要求先恒流再恒压放电要求恒流。恒流恒压切换是典型的双闭环应用但竞赛里很多人在这里翻车两套PID同时跑输出互相打架轻则电流震荡重则炸管。我的做法是同一时刻只运行一个PID。软件先检测当前状态如果是恒流模式就用电流PID电压误差只做监控不参与调节当电压逼近目标值比如14.4V浮充电压切换到恒压模式此时电流PID退出积分项清零。切换条件加滞回防止临界点反复抖动。这个思路用状态机实现非常清晰。虽然理论上可以用电压外环加电流内环的串级结构做得更精致但在四天三夜的时间压力下单环切换方案更稳妥、更好调。3.3 硬件过流保护不能全指望软件软件保护有一个致命问题ADC采样、执行保护逻辑都需要时间从检测到响应快则几十微秒慢则几百微秒。对功率变换器来说这个时间足够让电流冲到破坏性水平。硬件保护电路必须独立于软件存在。当时用LM393比较器把INA282输出的电流信号和一个基准电压比较一旦超过阈值直接拉低IR2104的EN引脚或者拉低SD引脚实现封波。这个优先级高于所有软件指令响应时间在微秒级。比较器输出加了锁存触发一次保护后保持封锁状态必须手动复位才能恢复输出。这样做的原因是保护触发说明系统有不正常工况如果自动恢复器件会在故障状态下反复冲击很容易二次损坏。检修完确认问题排除后再复位是更稳妥的做法。4. 软件控制状态机、PID跟采样时序4.1 STM32F103C8T6的资源划分STM32F103C8T6虽然便宜但资源分配得当能省下很多调试时间。我当时是这样划分的TIM1作为高级定时器输出PWM1和PWM1N互补波形自动带死区ADC1两个通道电池电压、电感电流用定时器触发采样GPIO接两个按键和一个OLED屏I2C或SPI都行一个外部中断引脚接保护信号触发后进入异常处理。PWM频率100kHz对应TIM1的ARR值在72MHz下约720。死区时间寄存器按IR2104的520ns配合设置软件里也做了对应配置让硬件和软件双保险。4.2 三个状态的切换逻辑软件核心是状态机三个状态分别是恒流充电、恒压充电、恒流放电。typedef enum { CHARGE_CC, CHARGE_CV, DISCHARGE_CC } Mode_t;状态切换逻辑上电默认关机。按键切换到充电模式后先看电池电压如果低于浮充电压阈值就进入先恒流后恒压流程如果电池电压已经接近满电则直接进入恒压模式。切换到放电模式时目标是把母线电压稳到24V左右电流恒定。切换条件要小心临界抖动。比如电池电压在13.8V附近徘徊时CC和CV来回切换输出会出现明显的“呼吸效应”。解决办法是设置滞回进入恒压的阈值是13.9V退出恒压降到13.5V才算区间留0.4V。switch (mode) { case CHARGE_CC: pid_fb current_feedback; pid_target cc_target; if (voltage_feedback CC_TO_CV_THRESH) { mode CHARGE_CV; PID_Reset(pid); } break; case CHARGE_CV: pid_fb voltage_feedback; pid_target cv_target; if (current_feedback CV_TO_CC_THRESH) { mode CHARGE_CC; PID_Reset(pid); } break; }PID的初始化函数里关键是把积分项清零这样切换时不会把上一模式的积分带到新模式里导致输出跳变。4.3 数字PID的一点经验竞赛里调PID最常见的错误是先把Kp调得很小、Ki调得很大结果系统缓慢震荡然后一遍遍调参就是找不到问题。我的整定顺序是先P后I再DKp从零开始慢慢加加到输出出现轻微震荡再退回60%左右Ki负责消除稳态误差从0.01开始加加到电压或电流能稳定在目标值如果出现持续低频振荡说明Ki太大Kd基本不用或者很小因为电流环反馈噪声大D项会把噪声放大反而让PWM输出抖动。位置式PID实现很简单但一定要加积分限幅和输出限幅float PID_Update(PID_t *pid, float feedback) { float error pid-target - feedback; pid-integral error; if (pid-integral INTEGRAL_MAX) pid-integral INTEGRAL_MAX; if (pid-integral -INTEGRAL_MAX) pid-integral -INTEGRAL_MAX; float d_term pid-Kd * (error - pid-last_error); float output pid-Kp * error pid-Ki * pid-integral d_term; pid-last_error error; if (output OUT_MAX) output OUT_MAX; if (output OUT_MIN) output OUT_MIN; return output; }这里有第二个容易翻车的点PID输出和占空比的关系。降压模式下占空比DVo/ViPID输出直接映射到0~0.9的占空比没问题。但升压模式下VoVi/(1-D)同样的PID输出变化量在不同占空比下对输出电压的影响是非线性的。我当时的做法比较简单粗暴把PID输出按升压转换公式做了一次线性化处理也就是D1-Vi/Vo然后用这个D去设置PWM。虽然不算严格的小信号建模但实测效果够用。采样时序方面ADC触发要选在PWM周期的中点避开开关管开通和关断瞬间的尖峰噪声。用TIM1的更新事件触发ADC硬件时序比软件轮询稳定得多。5. PCB设计和布线效率上限在这里决定5.1 功率回路面积是头号问题PCB设计对整个系统的影响有多大我可以负责任地说原理图一样的两个板子一个效率91%一个效率83%差距全在布局布线。功率回路面积是首要问题。双向Buck-Boost的工作电流动辄10A如果功率回路面积大寄生电感就大。每次开关动作在寄生电感上产生的电压尖峰VL×di/dt非常可观轻则振铃严重重则直接击穿MOS管。画板之前先把两种状态的电流回路画出来降压模式Q1导通时电流从输入正极流经Q1、电感、电池、采样电阻回到输入负极降压模式Q1关断时电感维持电流通过Q2的体二极管或同步整流管续流。对这两种回路我在布局时反复调整目标是让输入电容、Q1、Q2、电感、输出电容围成的闭合路径尽可能紧凑。这个动作可以理解为把大电流换向的环路压缩到最小电流路径上每个来回都短而粗。5.2 驱动与功率地的处理驱动信号和功率走线要分开处理。IR2104的HO和LO输出到MOS管栅极的走线要短、要粗至少10mil以上不要绕弯不要跟功率走线平行很长一段距离。原因是栅极驱动是高频大电流脉冲布线太长会引入额外电感导致栅极波形过冲和振铃。地线处理上我采用了单点接地策略功率地和信号地在输入电容的负极端子处单点相连。ADC采样参考地、比较器基准地都走信号地不要像蜘蛛网一样到处乱铺。电流采样电阻的地端必须单独走线回到信号地节点避免采样信号里串入功率地的大电流噪声。我以前吃过这个亏采样波形上全是毛刺PID怎么调都稳不住根源就是采样地跟功率地共了一段。5.3 线宽、过孔与散热线宽按铜箔厚度和经验公式来1oz铜厚1mm线宽大约过1A电流这是温升可接受的工程经验值。10A电流至少需要10mm线宽如果板子面积不够就用铺铜加多层过孔替代。层间过孔要多打几个单孔过流能力约1A到2A10A至少要5个以上的过孔并联。MOS管散热是重点。IRF3205在这种功率下发热不小我建议在PCB上把MOS管的漏极焊盘做大底部打一整排过孔把热量导到背面铺铜上背面铺铜不要断开面积越大散热越好。电感也要注意不要为了追求回路面积小就把电感紧贴功率管电感自身会发热长期高温会影响周边电容寿命。另外电感下方的铺铜我记得当时也做了一点处理没有在电感正下方铺铜走大电流因为高频磁场会在铜箔上感应涡流既发热又降低电感效率。这个细节看起来小但对稳定性有直接影响。6. 实测调试记录炸过管才算真正懂这东西6.1 上电流程先降压、后升压、最后双向调试顺序比调试技巧还重要。我习惯按以下流程走不接电池先给母线接一个限流直流源比如24V限流0.5A确认板子没有短路母线电容充电正常手动固定一个很小的占空比比如10%开环验证SW点有没有正常开关波形无误后接上电池电池侧串联一个电阻限流慢慢加大占空比观察电池端电压是否线性上升电压正常后再接电流采样和闭环先把目标设低一点跑通再逐步加到额定值最后反向做升压测试同样从开环小占空比开始。千万别跳过开环直接闭环。开环炸了你能很快判断是驱动问题还是功率问题闭环炸了你连从哪里查起都不知道。6.2 开关节点振铃的排查正常工作的SW点应该是一个干净的方波。如果发现上升沿和下降沿有严重的振铃首先检查驱动波形栅极电压是否方波干净有没有过冲到危险电压。栅极串一个10Ω电阻有奇效能有效抑制驱动振铃代价是开关速度变慢一点开关损耗会略有增加。如果栅极正常但SW还是振铃多半是功率回路寄生电感太大这时候优化PCB布局比调参数管用。应急情况下可以在SW点加RC吸收电路比如1nF电容串10Ω电阻到地但这是治标不治本只能抑制辐射噪声不能解决本质问题。6.3 效率从83%到91%的调整过程当年调试时效率一开始只有83%这个数据在电赛评分里很吃亏。我逐项排查后发现损耗主要来自三块第一Q2续流用的是体二极管压降大、损耗高。开启同步整流后Q2在Q1关断期间完全导通续流压降从0.8V降到I×Rds(on)这部分效率提升最明显。第二死区时间设置过长。IR2104自带520ns死区但我在TIM1里又额外增加了一段死区导致续流时间变长、体二极管导通时间增加。后来我把TIM1死区改小到接近硬件极限用示波器确认没有上下管直通现象效率又有提升。第三电感磁芯损耗。最初用的电感在100kHz下发热严重后来换成铁硅铝磁环自己绕铜损和磁损都明显下降。这三步做完效率大概到了90.8%距离目标91%还差一点点。最后把栅极电阻从10Ω降到4.7Ω开关损耗进一步下降终于稳定在91%出头。注意栅极电阻不能降太狠否则驱动振铃会变大这个要自己在效率和可靠性之间找平衡。说回这份资料包的价值里面给的原理图、PCB源文件和代码本质上是一套可以完整复现的参考实现。我建议你复现的时候每一步都回到本篇我讲的设计逻辑里验证一遍——比如电感量是不是按题目功率算出来的、采样地是不是真的单点接地了、PID输出和占空比的映射关系有没有处理。直接照抄能跑但只有理解了参数从哪里来你才能应对赛题里的各种变故也才能真正把这个题目变成自己的东西。本文还有配套的精品资源点击获取
