从 PWM 无输出到上下管直通:GTM 配 L9945 推挽的连环踩坑记

从 PWM 无输出到上下管直通:GTM 配 L9945 推挽的连环踩坑记

用 AURIX TC38x 的 GTM(TOM 产生 PWM + DTM 插死区)驱动 ST L9945 预驱做推挽输出,这次调试经历了前后两段完全不同的故障:第一段,引脚上什么波形都没有;第二段,波形出来了,L9945 却报上下管直通。 两段加起来一共四个配置错误,前三个让信号"出不来",最后一个让信号"错着出来"。本文按这个顺序讲,每一节附一条可迁移的经验。

L9945 外围电路原理图
L9945 预驱外围电路:NON1~NON8 为低有效输入
半桥功率级原理图
推挽功率级:Q5002A(上管)/Q5004A(下管),IMSL0610AGDQ-13

一、第一段故障:引脚上什么都没有

最初的任务是配置四路推挽(NON1/3、NON2/4、NON5/7、NON6/8 四组),代码写完烧进去,示波器往引脚上一搭——什么都没有。逐层扒代码,发现配置链路上叠着三个错误。

1.1 ToutSel 移位量少了 ×4:写了个寂寞

GTM 的 TOUTSEL 寄存器控制每个输出引脚接哪一路内部信号,每个引脚的 SEL 位段是 4 bit,而代码按 2 bit 移:

/* 错误:SEL 位段是 4bit,偏移应该是 idxToutselSelUB * 4 */
regVal |= selVal << idxToutselSelUB;

/* 修复后 */
regVal |= selVal << (idxToutselSelUB << 2U);

后果是路由配置根本没写进目标位段,引脚上接的信号和注释里标的完全不是一回事。

1.2 死区通道号算错:四路死区全写进 CH0

SetDtmDeadtime 里把 TOM 通道号 >>2 当 DTM 通道号用,不管配哪个通道,DTV(死区时间寄存器)全都写到 DTM0 的通道 0:

/* 错误 */
idxDtmChanUB = idxTomChanUB >> 2U;

/* 修复后:调用方传入的就是 DTM 通道号 0~3,不要再移位 */
idxDtmChanUB = idxTomChanUB;

1.3 打包寄存器整写:四通道只剩最后一个

DTM 的 CH_CTRL2 是四通道共享的 32 bit 寄存器(每通道 8 bit),原代码整寄存器赋值,后写的通道把先写的配置清掉:

/* 错误 */
infoRegDtmPS->CH_CTRL2.U = (0x88U << (idxDtmChanUB << 3U));

/* 修复后:读-改-写 */
uint32 regVal = infoRegDtmPS->CH_CTRL2.U;
regVal &= ~(0xFFU << (idxDtmChanUB << 3U));
regVal |=  (0x99U << (idxDtmChanUB << 3U));
infoRegDtmPS->CH_CTRL2.U = regVal;

这一段的经验:调 GTM 这类寄存器密集的外设,先把"配置是否真的写进去了"用调试器读回验证,再谈波形。位段宽度和打包寄存器的读-改-写,是这类驱动最高发的两类错误。

二、第二段故障:波形出来了,芯片报警了

三个 Bug 修完,PWM 终于从引脚上出来了。但量推挽输出脚(J2-57),波形呈 10 ms 周期的 burst——一小段 PWM 之后被整体拉掉,过 10 ms 又起来。空载、占空比调多低都一样。同时 L9945 报:

  • 高边输入 NON1 报 STG(对地短路)
  • 低边输入 NON3 报 STB(对电池短路)
故障时的异常波形
故障现象:J2-57 输出呈约 10 ms 周期的 burst,PWM 反复被保护掐断

2.1 先读故障码:反方向双过流 = 直通

空载、两个管子、方向相反的过流故障同时出现,电流路径只剩一种可能:母线 → 上管 → 下管 → 地。上管看到的等效为对地短路,下管看到的等效为对电源短路。看到高低边双管反方向过流,直接查直通(shoot-through),不要先怀疑采样和诊断链路。

2.2 根因:死区加在了错误的边沿上

DTM 每个通道 8 个控制位,关键是 POL0 / DT0 / POL1 / DT1(OUT0 极性、OUT0 死区使能、OUT1 极性、OUT1 死区使能)。原配置 0x88 = 0b10001000:两路输出开死区、极性不反。

问题在于 L9945 的 NON 输入是低有效(低开高关)。DTM 死区的行为是"把有效沿延时",而对这个芯片,需要守的是关断沿而不是导通沿:

沿方向 对 MOSFET 的意义 死区该不该守
输出变低(NON 有效) 管子导通 不该
输出变高(NON 无效) 管子关断 该守的是这里

0x88 配置下死区落在导通沿,换向时上下管同时导通,窗口宽度为 2 倍死区时间——空载也直通。修复为 0x99 = 0b10011001(POL0 | DT0 | POL1 | DT1),OUT0 极性反相,死区回到关断沿上。

这一段的经验:用任何死区模块配推挽之前,先写一张真值表——MCU 输出有效电平 → DTM 极性 → 预驱输入有效电平 → MOSFET 状态,逐格推完再上电。死区方向错了比不加死区更危险。

三、极性反相的连锁反应

POL 反相不是改一个寄存器就完事,它牵连了整条软件链路。

3.1 占空比相位反了

反相后应用层给 30% 占空比,实际输出 70%。修复点选在 IoHwAb 层做补偿,而没用预驱配置里的 bInvert 字段——后者是编译期常量,而推挽使能是标定量,两条路径运行期必然失配。补偿挂在 SetDuty/SynOut 钳位之后,上层无感:

if ((IOHWAB_PWM_PUSHPULL_IDX_INVALID != idxPushPullUB)
    && (0U != IoHwAb_Pwm_bPushPullEnUB_CA[idxPushPullUB]))
{
    rDutyUW = (uint16)(IOHWAB_PWM_DUTYCYCLE_FULL - rSetUW); /* 反相补偿 */
}

原则一句话:运行期可变的配置,其所有关联逻辑必须走同一条运行期路径,不能一半编译期一半运行期。

3.2 上电窗口:idle 电平从"安全"变成"全开"

MCAL Pwm 通道配置的 Idle state = HIGH,原本无碍;POL 反相后,idle HIGH 经 DTM 反相变成预驱输入低电平 = 上管全开。代码走读确认这版 MCAL(Infineon Pwm_17_GtmCcu6 20.0.0)在 Pwm_Init 末尾就通过 host trigger 使能 TOM 输出,于是从 CDD 写入 POL 配置到 IoHwAb 初始化把占空比压到"恒关断"之间,存在一段毫秒级窗口,高边不受控导通。

临时缓解:IoHwAb 初始化末尾对推挽高边强制写 0%(经补偿后恰为恒关断)。根治:MCAL 配置里把这几个通道的 Idle state 从 HIGH 改成 LOW。给功率级做极性反相,idle 态安全分析必须跟着重做。

四、一个注释引发的 2.5 倍误差

死区寄存器写的是 tick 数,代码设 400,注释标着 /* 100MHz */,照算是 4 µs。实测死区 10 µs——反推 CMU 时钟实际约 40 MHz,注释是错的。死区时间属于安全参数,时钟树别信注释,以实测或配置推导为准。

五、表象拆解:10 ms burst 不是新 Bug

回头解释那段诡异波形,它是三个机制叠加的合成现象:

  1. 直通触发 L9945 过流保护锁存,输出被芯片掐掉;
  2. 软件里 10 ms 周期的异步输出任务不断重写输出控制寄存器,把输出"救"回来;
  3. 关断段里偶尔的小脉冲,是诊断任务的诊断脉冲,属正常行为。

修掉直通后波形立即恢复正常:高低边互补、死区清晰。经验:示波器上的周期性异常,先拆成"故障本体 + 保护动作 + 周期任务"三层再分析,别把保护动作当故障。

修复后的互补 PWM 波形
修复后:NON1/NON3 互补输出,换向处死区约 10 µs 清晰可见

六、推挽输出上电前检查清单

把这次踩过的坑浓缩成一张清单,下次同类工作照着过一遍:

  • [ ] 引脚路由/复用配置写完后,读回寄存器验证(位段宽度、移位量)
  • [ ] 多通道共享寄存器:全部读-改-写
  • [ ] 死区方向:真值表推一遍,确认死区落在关断沿
  • [ ] 死区时钟:实测或从时钟树推导,不信注释
  • [ ] 极性反相的连带项:占空比相位、idle 安全态、上电窗口
  • [ ] 上电窗口:从引脚使能到软件接管之间,功率管处于什么状态?
  • [ ] 故障复现后:断电测 MOSFET 的 D-S 电阻,直通过的管子可能已带伤

平台:AURIX TC38x(GTM TOM0 + CDTM0 DTM0)+ ST L9945,自研类 AUTOSAR BSW。记录于 2026-10。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇