F28379D 下载后 VOFA+ 无数据、Reset 后恢复:一次 TZ 中断误触发排查记录

F28379D 下载后 VOFA+ 无数据、Reset 后恢复:一次 TZ 中断误触发排查记录 结论先行在 LAUNCHXL-F28379D 上调试 SCIA 和 VOFA 时出现了一个很有迷惑性的现象程序下载后 VOFA 没有数据gMainLoopCount也不增加在 CCS 中执行一次 Reset 后程序却能进入while(1)VOFA 随即正常显示数据。最终确认SCIA 初始化和 VOFA 发送代码并不是根本原因真正的问题是 CMPSS 输入引脚悬空导致 ePWM Trip Zone 保护被误触发。本工程的保护链路为ADCINA2/ADCINA3 悬空 → CMPSS1 输出不确定 → EPWM XBAR TRIP4 → DCAEVT1 → One-Shot TZ → TZ 中断持续触发 → CPU 无法稳定执行主循环 → VOFA 没有数据Reset 之后暂时恢复只是因为复位改变了外设状态以及悬空模拟引脚上的残余电荷输入短时间内恰好没有触发保护。这种恢复具有偶然性不能作为正常启动方案。开发环境与工程配置本次问题对应的主要环境如下MCUTMS320F28379D开发板LAUNCHXL-F28379DIDECode Composer Studio 20.5.1配置工具SysConfig 1.28 及以上版本上位机VOFA串口SCIAGPIO42 为 TXGPIO43 为 RX串口参数115200、8 数据位、无校验、1 停止位VOFA 协议FireWaterSysConfig 中还配置了 ADC、CMPSS、EPWM、EPWM XBAR、Digital Compare 和 Trip Zone用于实现硬件过流保护。故障现象程序下载后主要表现为VOFA 串口指示有时闪烁但没有形成有效波形gVofaSci.txFrameCount和调试帧计数不增加gMainLoopCount保持为 0说明程序没有正常执行主循环初始化步骤变量能够运行到EINT附近在 CCS 中执行一次 Reset 并继续运行后gMainLoopCount开始增加VOFA 也能接收数据。由于 Reset 后串口能够正常发送说明串口引脚、波特率和数据格式基本正确。问题重点应从“串口为什么发不出去”转向“CPU 为什么没有持续执行发送函数”。为什么悬空的 ADC 引脚会触发 TZF28379D 的部分模拟引脚同时连接到 ADC 和 CMPSS。与本工程相关的两个引脚为ADCINA2同时是CMPIN1PADCINA3同时是CMPIN1N。因此即使程序主要把它们当作差分 ADC 输入使用只要启用了 CMPSS1这两个引脚上的电压也会直接影响比较器输出。模拟引脚悬空并不等于 0 V。悬空输入会受到以下因素影响ADC 采样保持电容的残余电荷芯片输入漏电流电源和 PWM 开关噪声人体、导线和周围电路的电磁耦合上一次采样和复位过程留下的瞬态电压。因此悬空引脚可能随机越过 CMPSS 阈值使保护信号处于有效状态。本工程的 CMPSS DAC 配置值为CMPSS_setDACValueHigh(CMPSS1_BASE,3225U);CMPSS_setDACValueLow(CMPSS1_BASE,869U);当 CMPSS DAC 参考电压为 3.3 V 时阈值可近似计算为V T H 3225 4096 × 3.3 ≈ 2.60 V V_{TH} \frac{3225}{4096}\times 3.3 \approx 2.60\text{ V}VTH​40963225​×3.3≈2.60VV T L 869 4096 × 3.3 ≈ 0.70 V V_{TL} \frac{869}{4096}\times 3.3 \approx 0.70\text{ V}VTL​4096869​×3.3≈0.70V只要比较器输入落到保护区间CTRIPH或CTRIPL就可能使 EPWM XBAR 的 TRIP4 变为有效状态。TZ 保护链路如何阻止主循环运行本工程的硬件保护链路可以简化为CMPSS1 CTRIPH/CTRIPL → EPWM XBAR TRIP4 → DCAH → DCAEVT1 → One-Shot Trip ZoneSysConfig 生成的关键配置逻辑如下XBAR_setEPWMMuxConfig(XBAR_TRIP4,XBAR_EPWM_MUX00_CMPSS1_CTRIPH_OR_L);XBAR_enableEPWMMux(XBAR_TRIP4,XBAR_MUX00);EPWM_selectDigitalCompareTripInput(EPWM1_BASE,EPWM_DC_TRIP_TRIPIN4,EPWM_DC_TYPE_DCAH);EPWM_setTripZoneDigitalCompareEventCondition(EPWM1_BASE,EPWM_TZ_DC_OUTPUT_A1,EPWM_TZ_EVENT_DCXH_HIGH);EPWM_enableTripZoneSignals(EPWM1_BASE,EPWM_TZ_SIGNAL_DCAEVT1);Trip Zone 属于硬件快速保护。即使 CPU 还没有进入中断DCAEVT1 也可以直接把 ePWM 输出强制到安全电平。问题发生在全局中断开启之后EINT;ERTM;while(1){gMainLoopCount;VofaSci_SendCsv3U16(1U,2U,3U);DEVICE_DELAY_US(10000U);}如果 CMPSS 保护信号已经有效CPU 执行EINT后会立即进入 EPWM1 TZ 中断。若 ISR 又立即清除所有 One-Shot 标志而外部故障条件仍然存在就会形成以下循环TZ 触发 → 进入 ISR → 清除 OST/DCAEVT1 → 悬空输入再次触发 → 再次进入 ISRCPU 大部分时间都消耗在 TZ ISR 中主循环中的 VOFA 发送函数得不到执行机会于是表现为“串口没有数据”。排查过程检查 SCIA 与 VOFA 参数首先检查了以下内容SCIA 是否使用开发板板载 USB-UART 对应的 GPIO42/GPIO43波特率是否为 115200VOFA 是否选择正确的 COM 口串口格式是否为 8N1FireWater 数据是否以逗号分隔并以\r\n结束SCIA 发送计数是否增加。由于 Reset 后相同程序能够发送数据说明串口链路并没有根本性错误。使用主循环计数判断程序位置在主循环中增加计数变量volatileuint32_tgMainLoopCount0UL;while(1){gMainLoopCount;VofaSci_SendCsv3U16(1U,2U,3U);DEVICE_DELAY_US(10000U);}第一次下载运行时gMainLoopCount不增加说明问题发生在 VOFA 发送函数之前。继续观察初始化步骤程序正好停留在全局中断开启附近排查重点随即转向 ADC 和 TZ 中断。临时关闭 TZ 的 CPU 中断在Board_init()后临时加入Board_init();// 仅关闭CPU的EPWM1 TZ中断用于定位问题。// ePWM硬件Trip Zone动作仍然可以保持有效。Interrupt_disable(INT_Phase_A_TZ);关闭 TZ 的 CPU 中断后程序能够直接进入while(1)VOFA 也能正常显示数据。这一步证明问题来自 TZ 中断而不是 SCIA。检查模拟输入状态进一步检查发现ADCINA2 和 ADCINA3 均未连接任何稳定电压处于悬空状态。由于这两个引脚同时是 CMPSS1 的输入CMPSS 输出自然无法保持确定状态最终导致 TZ 误触发。正确处理方法模拟保护输入不能悬空测试差分 ADC 零输入时可以先给 ADCINA2 和 ADCINA3 提供相同的稳定共模电压。例如使用两个电阻对 3.3 V 分压获得约 1.65 V再把两个输入都接到该电压。此时差分输入接近 0 V16 位差分 ADC 结果通常接近中间码 327681.65 V 位于当前约 0.702.60 V 的阈值范围内CMPSS 高、低保护信号都应处于非故障状态。实际设计仍需满足数据手册规定的 ADC 差分输入范围、共模电压和信号源阻抗要求。低限保护需要正确设置极性如果CTRIPH OR CTRIPL用于表示“超过上限或低于下限”低比较器输出通常需要配置为反相。生成代码应包含CMPSS_configLowComparator(CMPSS1_BASE,CMPSS_INSRC_DAC|CMPSS_INV_INVERTED);否则低比较器可能在输入高于低阈值时输出有效使CTRIPH OR CTRIPL的逻辑与预期保护区间不一致。One-Shot 中断不要在 ISR 中自动恢复 PWMOne-Shot 的作用是故障发生后锁存 PWM 关断状态直到软件确认故障已经消失并主动恢复。因此 ISR 中只记录故障并确认 PIE 中断不立即清除 OSTvolatileuint16_tgPhaseATzFault0U;volatileuint32_tgPhaseATzCount0UL;__interruptvoidINT_Phase_A_TZ_ISR(void){gPhaseATzFault1U;gPhaseATzCount;// One-Shot故障保持锁存不在ISR中清除OST。Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2);}只有在确认 CMPSS 输入已经恢复到安全范围后才执行恢复操作voidPhaseA_ClearTripAfterFaultRemoved(void){// 清除DCAEVT1对应的One-Shot来源标志。EPWM_clearOneShotTripZoneFlag(EPWM1_BASE,EPWM_TZ_OST_FLAG_DCAEVT1);// 清除TZ状态并恢复PWM输出。EPWM_clearTripZoneFlag(EPWM1_BASE,EPWM_TZ_FLAG_OST|EPWM_TZ_FLAG_DCAEVT1|EPWM_TZ_INTERRUPT);gPhaseATzFault0U;}恢复前必须确保故障源已经无效。若 CMPSS 输出仍然处于保护状态清除标志后会立即再次触发 TZ。One-Shot 保护优先使用 OST 中断源如果 DCAEVT1 已经作为 One-Shot SourceTZ 中断源更适合选择 OST而不是直接选择持续有效的 DCAEVT1 电平中断。对应逻辑为EPWM_enableTripZoneInterrupt(EPWM1_BASE,EPWM_TZ_INTERRUPT_OST);这样一次故障只需要进入一次保护 ISRPWM 保持锁存关断后续由主循环完成故障记录、状态显示和人工恢复。推荐的调试顺序为了避免多个模块互相干扰可以按照以下顺序调试暂时关闭 TZ 的 CPU 中断只测试 SCIA 和 VOFA确认主循环计数持续增加。给 ADCINA2/ADCINA3 接入稳定电压确认 ADC 差分结果合理。单独观察 CMPSS 状态确认正常输入不会触发高限或低限。启用 EPWM XBAR 和 DCAEVT1先验证硬件能够把 PWM 拉到安全电平。将 TZ 中断源配置为 OST并在 ISR 中只记录故障。故障解除后通过独立恢复函数清除 One-Shot 标志。这种顺序可以快速判断问题发生在串口、ADC、CMPSS、XBAR、Digital Compare 还是 TZ 中断避免把“主循环没有运行”误判成“串口发送代码错误”。总结本次 VOFA 无数据并不是 SCIA 驱动失效而是 ADCINA2/ADCINA3 悬空后引起 CMPSS 输出不确定进而触发 EPWM Trip Zone。全局中断开启后CPU 持续处理 TZ 事件主循环无法稳定运行最终表现为 VOFA 没有数据。这次排查得到几个重要结论模拟比较器和 ADC 输入不能悬空判断串口问题前应先确认主循环是否真的在运行ePWM Trip Zone 的硬件关断不依赖 CPU 中断One-Shot 故障不应在 ISR 中立即自动恢复CTRIPH OR CTRIPL做窗口保护时需要检查低比较器极性Reset 后偶尔恢复不能说明问题已经解决稳定输入和正确的保护状态机才是可靠方案。当 VOFA 没有数据时除了检查串口参数还应重点观察gMainLoopCount、CMPSS 状态、TZFLG和 ISR 计数。只要先确认 CPU 实际运行到了哪里排查范围就会迅速缩小。参考资料TMS320F28379D 数据手册F2837xD Driverlib CMPSS API GuideF2837xD Driverlib EPWM API Guide