ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

车载充电器数字电源:PFC+LLC两级控制与F28035启动代码实战解析

车载充电器数字电源:PFC+LLC两级控制与F28035启动代码实战解析 简介一份面向车载电源与电力电子工程师的完整设计资源包围绕OBC车载充电机/车载电脑场景整合功率因数校正PFC与LLC谐振变换器的技术文件可用于高效能车载电源系统开发、充放电控制策略研究及充电设备性能优化。压缩包共373个文件、15.27MB以C源码44个.c、头文件82个.h和Makefile40个.mk为主体同时包含PCB库13个.pcblib、原理图12个.schdoc、PCB设计文件9个.pcbdoc、汇编启动代码10个.asm以及CCS工程配置等覆盖从嵌入式软件到硬件设计的完整链路。目前已有131人学习下载。资源内提供的DSP28035启动代码、外围电路库及工程管理文件可直接用于实际项目研发或学术验证帮助快速搭建基于LLC谐振拓扑的车载电源原型是一份难得的工程参考素材。1. 为什么车载充电器的数字电源要同时做PFC和LLCOBC车载充电器的功率链路在工程实现上几乎绕不开“PFCLLC”两级结构前级把电网输入的交流电整成稳定的直流母线常见 400V让输入电流时刻跟随电压波形解决功率因数和谐波问题后级 LLC 谐振变换器负责把母线电压转换成电池需要的几百伏直流用谐振腔的软开关特性把满载效率做上去。两级控制器大多落在 TI C2000 系列比如 TMS320F28035 这种 100MHz 定点 DSP片上自带 PWM 死区、ADC、比较器和模拟比较器专门为数字电源设计。OBC_PFC_LLC.zip 里的内容正是这类工程启动阶段的框架源码汇编格式的上电入口、延时函数、Flash 密钥占位和调试中断设置。这些文件看着零碎但没搭好后面 PID 写得再漂亮也跑不出稳定波形。这份资料适合正在做电源数字化的嵌入式工程师对号入座尤其是从仿真转工程落地的阶段。2. 从zip里的五个asm文件看F28035的启动与代码安全设计2.1 文件清单与它们在数字电源工程里的分工解压后第一眼会看到同名文件出现两次这是打包时保留了上层目录结构造成的去重后实际上是五段汇编源码。它们分别对应启动跳转、微秒延时、Flash 密钥和调试中断使能这几件事每一件都直接影响 PFC/LLC 工程在上电瞬间和调试阶段的行为。汇编文件在链接/启动链路中的角色对PFC和LLC工程的实际影响CodeStartBranch.asm复位后第一条指令所在的入口跳转决定上电后能否进入 C 环境进而进入主循环和中断DelayUs.asm基于 CPU 周期的微秒级延时用于 ADC 触发等待、软启动步进、传感器稳定延时Passwords.asmCSM 密钥值的占位定义量产固件能否被轻易读出由这一段决定Flash28035_CsmKeys.asm链接阶段把密钥段安排到固定地址与 cmd 文件配合把密钥放到芯片规定的 Flash 位置SetDBGIER.asm配置调试中断使能寄存器 DBGIER决定 CCS 调试器单步、断点时中断是否仍然按预期执行这几段代码平时不会出现在控制环路的分析里但它们定义了数字电源系统最底层的“运行环境”。拿到一个新的 OBC 工程先花半小时把这五个文件过一遍能少踩很多上电跑飞、无法连接、中断不响应的坑。2.2 CodeStartBranch.asm复位后进入C环境之前的那一跳F28035 上电后Boot ROM 根据引导引脚状态决定从 Flash 启动然后跳到 Flash 中一个固定地址。这个地址在 cmd 文件里被命名为codestart段CodeStartBranch.asm 里放的就是这个段的内容通常是下面这段;------------------------------------------------------------------------ ; codestart段, 链接脚本负责把它放在Boot ROM跳转的目标地址 ;------------------------------------------------------------------------ .sect codestart .ref _c_int00 ; C运行时环境的入口符号 LB _c_int00 ; 长跳转, 直接到C初始化代码 .endLB是 C2000 汇编的长跳转指令跳转目标_c_int00是编译器生成 C 初始化代码的入口。这一跳如果被别的代码覆盖或者codestart段被链接到错误地址程序上电后根本进不了 main。实际工程里常见的错误是把这段注释掉然后从别的文件里定义 main 入口结果 Boot ROM 跳进来抓到的是随机数据。另一个容易忽略的点是编译器版本。不同版本下 C 入口符号的前缀下划线处理方式不同项目从 CCS3.3 迁移到 CCS6 以上时_c_int00可能需要去掉前导下划线。排查方法很简单编译后在 map 文件里搜_c_int00确认它确实存在再确认codestart段地址落在 F28035 的 Flash 启动地址区间内。2.3 Passwords.asm与Flash28035_CsmKeys.asmCSM密钥不是加密TI C2000 系列有代码安全模块CSM它用一段 128 位密钥控制 Flash 的读取权限。F28035 的密钥是 8 个 16 位字分别对应密码位 PWL0 到 PWL7存放位置固定由链接器决定。Passwords.asm 和 Flash28035_CsmKeys.asm 就是和这套机制配套的文件。;------------------------------------------------------------------------ ; CSM密钥占位段, 8个16位字对应PWL0~PWL7 ; 调试期保持全0xFFFF 未锁定; 量产前改成随机数并烧录 ;------------------------------------------------------------------------ .sect csmpasswds .word 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF .word 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF需要说清楚的是CSM 不是加密它只是访问保护。芯片上电后外部调试器通过 JTAG 读 Flash必须先验证密钥与用户写入的 PWL 一致。密钥全为 0xFFFF 时视为未锁定任何调试器都能读一旦写入非 0xFFFF 的密钥CSM 立刻锁定再想通过 JTAG 读程序就必须要正确密钥。比较麻烦的是密钥写错后唯一解锁路径是整片擦除 Flash所以调试期保持全 F量产前最后一步再替换密钥这是工程上的常规顺序。Flash28035_CsmKeys.asm 在这里扮演的角色是把密钥段通过.sect和.word定义好再由 28035_RAM_lnk.cmd 或类似链接脚本把它映射到 0x3F7FF8 附近地址。两个文件同时出现是 TI 例程里常见的配对写法一个负责定义段内容一个负责定义段名和位置。实际项目里如果有保险丝或 DCSM 需求则要看新系列芯片的对应模块F28035 就认准 CSM。2.4 DelayUs.asm用CPU周期换微秒但不能在Flash里裸跑控制环路里很少用到大的延时但在预充、软启动、继电器吸合这些时序里微秒级延时很常见。DelayUs.asm 的基本思路是用指令周期凑时间;------------------------------------------------------------------------ ; 100MHz SYSCLKOUT下的延时实现, 输入为微秒数 ; 注意: 从Flash执行时, 每个取指都可能有等待状态, 这段应放到RAM运行 ;------------------------------------------------------------------------ .def _DELAY_US _DELAY_US: MOV AR0, AL ; 把微秒数放到循环计数器 SUB AR0, #1 ; 扣除一次迭代开销 $1: RPT #19 ; 内层重复20个周期 NOP BANZ $1, AR0-- ; AR0递减, 非零则跳回 LRETRRPT 指令让后续的 NOP 重复执行BANZ 是带递减的跳转指令两者配合构成双重循环。这里的计算基准是 100MHz SYSCLKOUT外层每微秒大约执行 20 个周期实际数值要在目标板上用示波器校准不能直接照抄。一个必须注意的坑是 Flash 等待状态。F28035 工作在 100MHz 时Flash 读取需要插入等待周期同样一段延时代码放在 Flash 里和搬进 RAM 里执行实际耗时差很多。严谨的做法是把这段汇编函数放到ramfuncs段由链接脚本把它装载并复制到 RAM 执行。PFC 和 LLC 的控制频率是 50kHz 到 200kHz 这个量级周期误差几百纳秒就能让波形失真所以延时精度直接影响测试结果的可信度。2.5 SetDBGIER.asm调试器停住时中断去哪儿了调试器在单步执行时CPU 会被挂起普通模式下一个 100kHz 的 PWM 中断可能因此不断堆积或丢失。TI 提供了 DBGIERDebug Interrupt Enable Register机制让 CPU 挂起时某些中断仍然能被执行前提是这些中断在 IER 里也使能了;------------------------------------------------------------------------ ; 设置DBGIER, 使它能响应的中断组与IER保持一致 ;------------------------------------------------------------------------ .def _SetDBGIER _SetDBGIER: PUSH ST1 SETC INTM ; 先关全局中断, 防止窗口期发生跳变 MOV AL, _IER ; 读取当前IER使能组 MOV _DBGIER, AL ; 同步到DBGIER POP ST1 LRETR这段代码的工作是把 IER 里已使能的中断组同步给 DBGIER。没有它程序正常运行不受影响但几个关键调试场景会出问题一是 CCS 实时仿真模式下PWM 中断对应的比较器输出停止更新电机或电源波形瞬间掉下去二是在断点处单步观察变量时ADC 中断不触发采样数据永远停留在旧值。工程里做环路调试时先把这段跑一遍再用实时仿真模式改 PI 参数看到的波形才是真实运行状态。3. 前级PFC的数字控制采样对齐、环路与母线电容纹波3.1 为什么OBC样机上常见交错图腾柱PFCOBC 前级要从电网吸收功率又要在车规尺寸内控制发热传统 boost PFC 的桥式整流二极管损耗在 3.3kW 以上就很不划算了。图腾柱无桥 PFC 省掉低频整流桥高频桥臂用氮化镓或碳化硅器件是当前 6.6kW OBC 的主流选择。所谓交错一般指两个图腾柱并联相位差 180°让电流纹波互相抵消电磁干扰滤波器体积也能缩小。控制目标可以概括成三个量输入电流跟踪输入电压波形、母线电压稳定在 400V、电网侧功率因数尽量接近 1。F28035 在控制上同时给出两路交错 PWM 并不吃力它有 ePWM 模块可以做相位同步。真正麻烦的是电流采样和占空比更新的对齐关系。PFC 电感电流在每个开关周期内先是上升再下降只有在 PWM 计数器归零附近采样才能避开开关管开闭造成的噪声窗口。常见做法是把 ADC 触发设成和 PWM 周期同步在计数值为零时触发采样然后在下一次占空比更新前完成电流环计算。3.2 电流采样窗口和PWM占空比更新数字电源里“采样时刻决定稳定性”这句话不是夸张。PFC 电流环如果采样点落在开关噪声上反馈进来的全是毛刺PI 输出抖得厉害。下面这段是典型的 ADC 中断处理结构// 每个PWM周期在计数器ZRO触发ADC, 中断里执行PFC电流环 interrupt void pfc_adc_isr(void) { // 1. 读取ADC结果寄存器 iL AdcMirror.ADCRESULT0; // 电感电流, 已标定到Q12格式 vBus AdcMirror.ADCRESULT1; // 直流母线电压 vGrid AdcMirror.ADCRESULT2;// 整流后电网电压, 用于前馈 // 2. 电压外环, 输出作为电流环的幅值给定 vErr VbusRef - vBus; iRef PI_Update(pfc_voltage_pi, vErr); // 3. 电流内环, 用瞬时电流误差计算占空比 iErr iRef - iL; duty PI_Update(pfc_current_pi, iErr); // 4. 电压前馈: 占空比约等于 vBus / vGridAbs EPwm1Regs.CMPA.half.CMPA duty * vBus / vGridAbs; // 5. 清中断标志 PieCtrlRegs.PIEACK.all PIEACK_GROUP1; }Q12 格式意味着量程被放大 4096 倍存成整型避免定点 DSP 做浮点运算的开销。PI_Update 的返回值在 Q12 下对应 0 到 1 之间的占空比归一化值。这段代码里最关键在于第 1 步的读取动作必须发生在 PWM 计数器归零后的几十纳秒内所以 ADC 触发源直接来自 ePWM 模块而不是软件启动。占空比更新用的是 shadow 寄存器机制CMPA 的 Shadow 值在周期匹配或归零时被加载避免中断中途修改造成半个周期的不对称。如果出现电流波形正负半周不对称优先检查是不是 CMPA 写入时机不对或者 shadow load 模式设成了立即加载。3.3 电压环带宽与PFC电容纹波电流计算电压外环带宽通常做在 10Hz 到 20Hz 之间原因是输入功率本身就带有 100Hz 的脉动电压环带宽太高会把这种脉动搬到电流给定上反而让输入电流畸变。所以整定顺序是先把电流环带宽做到开关频率的十分之一左右再去压电压环带宽。电流环相位裕量建议留 45° 以上否则 PWM 占空比在负载切换时会明显振荡。母线电容纹波电流是选型时最容易拍脑袋算错的地方。单相 PFC 的瞬时输入功率包含 100Hz 分量这部分能量必须由母线电容吞吐对应的纹波电流有效值可以用简化公式估算I_c,rms ≈ P_out / (√2 × V_bus)对 6.6kW、400V 母线来说6600 / (1.414 × 400) ≈ 11.7Arms。这个电流主要落在 100Hz不是高频开关纹波。电解电容规格书里给出的额定纹波电流通常是在 105°C、10kHz 条件下的值低频段要乘 0.8 左右的系数。实际工程里常见的配置如下OBC额定功率Vbus100Hz纹波电流rms常见母线电容3.3kW400V5.8A2 只 330μF/450V 电解6.6kW400V11.7A4 只 220μF/450V 电解11kW400V19.4A电解与薄膜电容混联电容并联时还要考虑各支路 ESR 差异带来的均流问题ESR 小的电容会承担更多纹波电流温升更容易偏高。用热成像仪扫一遍电容表面温度比单纯按公式计算更能说明选型是否合理。3.4 预充电路与上电保护OBC 上电瞬间母线电容接近短路状态直接合继电器会产生极大浪涌电流。常见做法是先在母线电容两端并联预充电阻回路让电容通过电阻缓慢充电母线电压抬升到额定值 90% 以上后再闭合主继电器同时把预充回路切掉。这就是“无桥双 boost PFC 为什么有预充电路”的原因桥臂上的半导体器件在母线电压建立起来之前没有正常控制条件硬开会使器件应力超限。软件保护方面PFC 至少要处理三个量母线过压、输入欠压、过流。母线过压通常发生在负载突然断开时电压环来不及把占空比压住母线瞬间冲高。此时除了关断 PWM还要考虑是否给预充电阻后级的放电电阻投入。过流保护应由比较器子系统和 PWM 的 TZTrip Zone引脚硬触发而不是等 ADC 中断判断后软件处理因为软件处理延迟在微秒级功率器件等不起。4. 后级LLC谐振变换器从增益曲线到控制参数落位4.1 半桥和全桥LLC在OBC里的分工LLC 谐振变换器的基本构成是开关桥、谐振电感 Lr、谐振电容 Cr 和励磁电感 Lm。半桥 LLC 适合 3.3kW 以内的场景全桥 LLC 则用在 6.6kW 和 11kW 的 OBC 中。相比反激和普通 DCDCLLC 的优势在于一次侧开关管能在较宽负载范围内实现 ZVS体二极管反向恢复问题大幅减轻效率曲线在全负载范围内更平坦。LLC 的控制量是开关频率而不是占空比。它的电压增益和频率、负载之间呈非线性关系频率靠近谐振频率时增益接近 1低于谐振频率可以升压高于谐振频率则降压。OBC 电池电压范围很宽比如 250V 到 450V所以控制必须在增益曲线的感性工作区选择合适频率段避免掉进容性区。4.2 ePWM死区配置与调频方式F28035 的 ePWM 模块产生 50% 固定占空比、带死区的互补驱动信号频率通过改变周期寄存器实现// 初始化半桥LLC的ePWM1, 输出两路互补PWM void LLC_Epwm1_Init(void) { // 1. 时基: 连续递增模式, 适合PFM调频 EPwm1Regs.TBCTL.bit.CTRMODE 0; // Up-count EPwm1Regs.TBPRD 1000; // 初始100kHz 100MHz SYSCLKOUT EPwm1Regs.TBCTR 0; // 2. ZRO置高, PRD清低 A路输出接近50%占空比 EPwm1Regs.AQCTLA.bit.ZRO 0x2; // Set EPwm1Regs.AQCTLA.bit.PRD 0x1; // Clear // 3. 死区: B路取反, 与A路互补 EPwm1Regs.DBCTL.bit.OUT_MODE 0x3; // 两路都有死区 EPwm1Regs.DBCTL.bit.POLSEL 0x2; // A不反相, B反相 EPwm1Regs.DBRED 20; // 20个CLK 200ns EPwm1Regs.DBFED 20; }这里 TBPRD 直接影响开关频率100MHz 主频、周期寄存器 1000对应的开关频率是 100kHz。要调高频率就减小 TBPRD要降低频率就增大 TBPRD。PFM 控制里改变频率的代码把新值写入 Shadow 寄存器在周期边界统一加载避免频率在周期中途跳变。死区时间设置要同时考虑上升沿和下降沿DSP 的死区模块用 DBRED 和 DBFED 分别控制。20 个时钟周期在 100MHz 下等于 200ns这个数值不能随意取它需要配合 MOSFET 的关断延迟和谐振电流大小来整定。4.3 死区时间选择与ZVS边界LLC 的软开关依赖死区时间内谐振电流给开关管结电容充放电死区太短结电容来不及换向硬开关损耗直接上来死区太长电流在死区里反向流动体二极管被迫导通同样降低效率。工程上用一个简化公式估算死区下限t_dead ≥ 4 × C_oss × V_bus / I_pk假设开关管输出电容 C_oss 为 500pF母线 400V谐振电流峰值 10A得到t_dead ≥ 4 × 500e-12 × 400 / 10 80ns这只是一个下限实际还要叠加上驱动电路传输延迟、比较器空白时间和温度变化所以 6.6kW 全桥 LLC 上常见死区设在 150ns 到 300ns 之间。调试方法是在样机上把死区从 100ns 开始逐级增加同时记录半桥中点和输出效率效率最高点对应的死区时间通常在软开关边界附近。4.4 PFC与LLC联动启动流程两级电源联动的核心原则是“先稳母线再带负载”。如果 PFC 还在软启动过程中就启动 LLC母线供给能力不足LLC 从母线抽走大电流会直接把母线电压拉垮。以下是常见状态机实现// OBC两级启动流程 switch (obc_state) { case STATE_PRECHARGE: // 预充继电吸合, 母线通过电阻充电 if (bus_voltage 0.9 * Vbus_NOM) { close_main_relay(); obc_state STATE_PFC_SOFTSTART; } break; case STATE_PFC_SOFTSTART: // PFC升压到400V, 电压外环先启用电流环限幅缓慢爬升 pfc_enable(); if (bus_voltage Vbus_NOM - 10) { obc_state STATE_LLC_SOFTSTART; } break; case STATE_LLC_SOFTSTART: // 从200kHz往100kHz逼近, 每隔2ms降低一档 for (i 0; i 15; i) { LLC_SetFreq(200000 - i * 7000); // 200k-100k 分段 DELAY_US(2000); } obc_state STATE_CC_CV; break; }PFC 软启动阶段电压环给定从零开始缓慢爬升避免母线电压过冲LLC 软启动阶段频率从高到低初始高频意味着低增益输出电流平稳增加。每个阶段的退出条件都要同时满足“电压到位”和“电流在限幅范围内”不能只判断单一量。5. 离线调试技巧示波器和CCS验证启动链路5.1 用GPIO翻转测中断响应时间PFC 和 LLC 的控制频率都在几十上百 kHz验证中断是否按预期执行很大程度上我需要手动查看波形。用 GPIO 翻转是成本最低的手段// PFC ADC中断入口处翻转GPIO10, 出口处再翻回来 GpioDataRegs.GPBTOGGLE.bit.GPIO10 1; // 在PFC中断函数末尾再执行一次 GpioDataRegs.GPBTOGGLE.bit.GPIO10 1;示波器接在 GPIO10 上看到的方波占空比就是中断服务函数占用的 CPU 时间比例。100kHz 中断周期是 10μs如果方波高电平时间占了 3μs说明中断占用率是 30%还有余量如果超过 80%基本可以判断控制算法拖了后腿别再往上加滤波运算了。这套方法在验证 LLC 调频中断和 PFC 电流环中断是否互相抢占优先级时特别有效。5.2 用CCS观察PWM寄存器实际生效值连接仿真器后在 CCS 的 Expressions 窗口添加EPwm1Regs.TBPRD、DBRED、CMPA这些寄存器地址运行时可以实时看到它们的值变化。实时仿真模式下可以直接修写 TBPRD 值然后立刻观察输出波形响应这比反复改代码重新烧写快得多。前提是 SetDBGIER 配置正确否则 CPU 被调试器接管后PWM 输出可能直接停掉。调试 LLC 死区生效情况时把示波器两个通道分别接到 ePWM1A 和 ePWM1B 的驱动输出端放大到纳秒级别确认死区时间与 DBRED/DBFED 的设定一致。如果实际死区比设定值大很多检查一下 GPIO 复用配置是否把引脚错配到了其他外设这种情况在板子上电早期经常发生。5.3 启动瞬间最容易翻车的三个点第一个点是大电解电容预充完成后主继电器闭合的抖动。继电器触点闭合瞬间如果控制信号恰好落在 PWM 输出高电平期间驱动脉冲可能被继电器抖动干扰一次误开通就可能炸管。工程上会禁用 PWM 输出直到继电器状态回读稳定再延迟 5ms 以上重新使能脉冲。第二个点是 LLC 软启动起始频率选得太低。如果初始频率落在谐振频率以下增益可能超过 1输出电压爬升过快电流环来不及干预。判据是软启动第一拍不要让变压器原边电流出现饱和迹象用电流探头看谐振电流波形逐步提高起始频率直到启动阶段峰值电流低于满载值。第三个点是 PFC 输入欠压保护的判断窗口。电网在继电器吸合瞬间会有明显跌落如果保护响应太快会误触发。常见做法是连续检测到欠压 3 个电网周期后再动作用计数器去抖而不是一检测到瞬时值就关断。把窗口时间设在 50ms 到 80ms 之间既能滤掉跌落干扰又不会让 OBC 在真正断电时反应过慢。本文还有配套的精品资源点击获取
返回列表