1. 项目概述与核心价值
在搞电机控制或者数字电源的兄弟,肯定都遇到过这样的场景:你想在PWM波形的某个精确时刻(比如计数器等于比较值的那一刻)去触发ADC采样,或者当某个外部故障信号(比如过流比较器输出)跳变时,立刻关断PWM输出并进入中断服务程序。如果你用CPU去轮询判断这些条件,不仅代码臃肿,实时性也根本没法保证,一个中断延迟就可能让MOS管炸掉。这时候,ePWM模块里的事件触发(ET)和数字比较(DC)子模块就是你的“硬件外挂”,它们能帮你把这些脏活累活全包了。
简单来说,事件触发子模块(ET)就是个高度可配置的“事件调度器”。它盯着时间基计数器(TBCTR)、比较匹配(CMPA/CMPB等)以及数字比较子模块送来的各种事件,然后按你的要求,比如“每发生3次CMPA匹配事件就触发一次中断”,去精准地产生中断(EPWMxINT)或ADC启动转换(SOC)脉冲。而数字比较子模块(DC)则是连接外部世界的“哨兵”和“信号处理器”。它把来自GPIO、模拟比较器(CMPSS)的外部数字信号(比如过流、过压信号)接进来,转换成内部的DCAEVT/DCBEVT事件。这些事件不仅能直接去“强制动作”(Force)关断PWM(即触发Trip-Zone),还能送给ET模块去触发中断或ADC,更厉害的是,它自带“事件过滤”和“谷底切换”这种高级功能,能滤除信号毛刺,还能在LLC、移相全桥这类谐振变换器里实现精准的谷底开通,大幅降低开关损耗。
我手头在调TI的AM263P,它的ePWM模块功能非常强悍,尤其是ET和DC部分,寄存器多,选项也多,刚开始看手册确实容易懵。但一旦啃下来,你会发现用它来构建高可靠、高精度的控制环路,效率提升不是一点半点。今天我就结合手册和实际调试中的一些坑,把这俩子模块的原理、配置套路和实战心得给你捋清楚。
2. 事件触发(ET)子模块深度解析
2.1 模块架构与核心功能
你可以把ET子模块想象成一个带有预分频器和多种触发源选择的高级定时器中断发生器。它的输入源非常丰富:
- 时间基事件:计数器等于零(TBCTR=0)、计数器等于周期值(TBCTR=PRD)。
- 计数器比较事件:这是最常用的。不仅包括CMPA和CMPB的匹配,在增强型ePWM(如AM263P的Type 5)中,还扩展到了CMPC和CMPD。更关键的是,它区分了递增匹配(CTR=CMPx when counting up)和递减匹配(CTR=CMPx when counting down)。这在不对称PWM生成或需要在一个周期内不同方向触发不同动作时极其有用。
- 数字比较事件:来自DC子模块的
DCAEVT1.soc和DCBEVT1.soc信号可以直接作为SOCA/SOCB的触发源,实现了外部事件到ADC采样的直连。
它的核心输出就两个,但至关重要:
- 中断(EPWMxINT):通知CPU,某个特定的事件序列已经发生。
- ADC启动转换(SOCA/SOCB):直接硬件触发ADC开始采样,实现了PWM事件与ADC采样的硬同步,采样时刻的抖动可以做到纳秒级,远非软件触发可比。
2.2 关键寄存器精讲与配置流程
配置ET模块,主要跟以下几组寄存器打交道,我把它翻译成“人话”:
ETSEL (Event-Trigger Selection):“选择触发源”。
INTSEL,SOCASEL,SOCBSEL:这三个位域决定了中断、SOCA、SOCB分别由哪个具体事件触发。比如,设置ETSEL.INTSEL = 010b,就表示中断由“TBCTR = PRD”这个事件产生。INTEN,SOCAEN,SOCBEN:总开关。选好了事件源,必须把这位置1,相应的输出(中断或SOC)才被使能。INTSELCMP,SOCASELCMP,SOCBSELCMP:当上述选择指向CMPx事件时,这个位用来进一步选择是CMPA/CMPB还是CMPC/CMPD。0选A/B,1选C/D。
ETPS (Event-Trigger Prescale):“设置事件分频”。这是ET模块的精髓,决定了“多少个输入事件才产生一个输出脉冲”。
INTCNT,SOCACNT,SOCBCNT:事件计数器。每当选择的触发事件发生时,这个计数器就加1(直到达到周期值)。INTPRD,SOCAPRD,SOCBPRD:事件周期值。你希望每N个事件产生一个输出,就把这里设为N。- 工作流程:使能后,
INTCNT从0开始,每来一个事件就+1。当INTCNT等于INTPRD时,如果中断使能(INTEN=1)且中断标志未置位(INTFLG=0),则产生一个中断脉冲,同时INTFLG置1,INTCNT自动清零,然后重新开始计数。如果中断被禁用或标志已置位,计数器会停在INTPRD值,等待你清除标志或重新使能。 INTPSSEL,SOCPSSEL:预分频器选择位。这是AM263P等新款芯片的增强功能。当它为0时,使用上述传统的INTCNT/INTPRD(最大分频比1/3)。当它为1时,则使用另一组增强寄存器ETINTPS/ETSOCPS里的INTCNT2/INTPRD2,支持的分频比可以达到每1到15个事件,灵活度大大增加。
ETFLG & ETCLR & ETFRC:“状态、清除与强制”。
ETFLG:标志寄存器。当中断或SOC事件真正发生时,对应的INT或SOCA位会被硬件置1。这是判断事件是否触发的直接依据。ETCLR:清除寄存器。向对应位写1,可以清除ETFLG中的标志位。通常在中断服务程序(ISR)里干这个。ETFRC:强制寄存器。向对应位写1,可以软件强制让事件计数器INTCNT加1。这主要用于测试和调试。比如你想手动触发一个中断来测试ISR,但又不想等实际事件发生,就可以用这个。
ETCNTINITCTL & ETCNTINIT:“计数器初始化控制”。这是一个高级功能,用于在特定时刻(如收到同步信号
EPWMxSYNCI时)将事件计数器(INTCNT2,SOCACNT2等)初始化为一个预设值,而不是从0开始。这在多个ePWM模块需要精确相位差触发事件时非常有用。
配置一个“每2次CMPA匹配(上升计数时)触发一次ADC SOCA”的典型流程:
- 选择事件源:
ETSEL.SOCASEL = 100b(CTR = CMPA when counting up)。如果使用CMPC,则还需设置ETSEL.SOCASELCMP = 1。 - 使能SOCA:
ETSEL.SOCAEN = 1。 - 设置事件分频:假设使用传统分频器。
ETPS.SOCAPRD = 2(每2个事件)。ETPS.SOCACNT硬件会自动管理,通常初始化为0。 - (可选)选择预分频器:如果需要1-15的分频,设置
ETPS.SOCPSSEL=1,然后在ETSOCPS.SOCAPRD2中设置周期值。 - 启动:配置完时间基和比较寄存器后,事件触发自动开始工作。
实操心得:在调试时,一定要先读
ETFLG寄存器确认事件是否真的触发了。有时候配置看起来都对,但ETFLG位没置1,可能是事件源本身没发生(比如CMPA值设得不合理),或者分频计数器还没数到周期值。用ETFRC寄存器做软件强制触发,是验证ET模块到CPU中断通路是否畅通的绝佳方法。
2.3 混合信号(MIX)功能
在Type 5 ePWM中,引入了ETINTMIX,ETSOCAMIX,ETSOCBMIX信号。这相当于一个“或”门集合。你可以通过ETINTMIXEN等寄存器,将多个事件源(比如同时是CMPA匹配和外部数字比较事件)进行逻辑“或”操作,其结果作为最终触发ET模块的源。这提供了更灵活的事件组合逻辑,允许你用更复杂的条件来触发中断或SOC。
3. 数字比较(DC)子模块深度解析
3.1 模块角色与信号流
如果说ET是内部事件的“调度中心”,那DC就是外部信号的“前处理站”。它的核心任务��把乱七八糟的外部数字信号(可能有毛刺、时机不对)变成干净、可靠、时机准确的内部事件。
信号流入:外部信号通过输入X-BAR映射进来,主要分两类:
- Trip-Zone输入:传统的TZ1, TZ2, TZ3引脚,通常用于紧急故障保护(如过流、过压),可配置为高有效或低有效。
- 数字比较输入:更通用的
DCAH/DCAL(数字比较A高/低)和DCBH/DCBL(数字比较B高/低)。这些信号可以来源于:- 模拟比较器模块(CMPSS)的输出。
- 其他GPIO引脚。
- 甚至其他外设(如ECC错误信号)。
信号处理与流出:外部信号经过DCTRIPSEL等寄存器选择后,形成DCAEVT1/2和DCBEVT1/2事件。这些事件有四大去处:
- 强制触发Trip(.force):最高优先级动作,可以直接控制PWM输出引脚(EPWMxA/B)强制变为高、低或高阻态,实现纳秒级硬件保护。通过
TZCTL、TZCTLDCA、TZCTLDCB寄存器配置具体动作。 - 触发中断(.interrupt):产生
EPWMxTZINT中断,通知CPU有故障或特定事件发生。通过TZEINT寄存器使能。 - 触发ADC SOC(.soc):将
DCAEVT1.soc或DCBEVT1.soc信号送到ET模块,作为ADC启动源。这是实现基于外部事件(如过零点检测)同步采样的关键。 - 产生同步脉冲(.sync):用于同步本模块或其他ePWM模块的时间基计数器。
3.2 高级功能一:事件过滤与消隐窗口
在电源和电机控制中,比较器信号极易在开关瞬间因噪声产生毛刺,导致误触发。DC模块的事件过滤(Event Filtering)功能,也叫消隐窗口(Blanking Window),就是用来解决这个问题的。
工作原理:在PWM周期的特定时间段内(消隐窗口),忽略所有DCxEVT事件。窗口的位置和大小完全可编程。
- 窗口起点:由
DCFOFFSET寄存器设定,单位是TBCLK周期数。起点是相对于一个“参考脉冲”的偏移。这个参考脉冲由DCFCTL[PULSESEL]选择,可以是CTR=PRD、CTR=0或两者。 - 窗口宽度:由
DCFWINDOW寄存器设定,同样是TBCLK周期数。
配置示例(防止开关噪声):在一个Buck变换器中,高边MOSFET开通瞬间(对应PWM上升沿)会产生严重的电流尖峰和噪声,可能误触发过流保护。
- 设置
DCFCTL.PULSESEL,让消隐窗口对齐到CTR=PRD(假设这是PWM周期开始,高边开通的时刻)。 - 设置
DCFOFFSET.OFFSET = 0,窗口从CTR=PRD立刻开始。 - 根据噪声持续时间,设置
DCFWINDOW.WINDOW = 10(假设10个TBCLK周期足以覆盖噪声)。 - 使能消隐:
DCFCTL.BLANKE = 1。
这样,在高边开通后的头10个TBCLK里,任何来自比较器的DCxEVT事件都会被无视,完美避开了开关噪声。
避坑指南:消隐窗口的
OFFSET+WINDOW之和不能超过PWM周期(TBPRD),否则行为可能不符合预期。手册中的图7-248展示了窗口跨越周期边界的情况,但实际设计时最好避免,以简化逻辑分析。务必用示波器同时抓取PWM波形、比较器原始输出和经过消隐后的DCEVTFILT信号,来验证窗口设置是否正确。
3.3 高级功能二:谷底切换(Valley Switching)
这是DC模块的王牌功能,主要用于LLC、移相全桥等谐振变换器,实现零电压开关(ZVS)。其核心思想是:检测谐振腔电压的谷底(最小值),并在谷底时刻开通开关管,从而使得开通损耗最小化。
传统上用模拟电路或复杂的软件算法来实现,现在DC模块用硬件帮你搞定。它的原理稍微复杂点,我拆解一下:
- 事件选择与边沿过滤:选择谐振腔电压过零检测比较器信号作为
DCxEVTy输入。通过DCFCTL[EDGEMODE, EDGECOUNT]配置边沿滤波器,例如,忽略前几个杂波,在检测到第N个有效边沿后才认为有效。 - 振荡周期捕获:这是关键。使能谷底捕获(
VCAPCTL.VCAPE=1)。硬件内部一个16位计数器,在STARTEDGE(如检测到上升沿)时开始计数,在STOPEDGE(如检测到下降沿)时停止计数。捕获到的计数值CNTVAL就代表了半个谐振周期的时长。 - 延迟生成与触发:将捕获到的
CNTVAL值(或它的几分之一,由VDELAYDIV控制)作为一个延迟量。当边沿滤波器再次检测到有效的STARTEDGE时,启动这个硬件延迟计数器。计数器到期后,才输出最终的DCEVTFILT信号。这个延迟后的信号,其边沿就对应了电压谷底。 - 应用:将这个
DCEVTFILT信号作为DCAEVT1.sync,去同步PWM时间基,从而将PWM的开通沿自动对齐到电压谷底。
配置要点:
STOPEDGE的设置值必须大于STARTEDGE。CNTVAL是硬件自动测量的,但谐振频率会随负载变化。因此通常需要软件读取CNTVAL,并结合一个软件偏移量SWVDELVAL进行微调,以补偿寄生参数等因素,实现最精确的谷底开通。- 触发逻辑
VCAPCTL[TRIGSEL]一般配置为由软件触发,每次PWM周期开始前,软件触发一次新的捕获。
3.4 事件检测与锁存机制
DC模块还提供了在指定时间窗口内检测事件是否发生的功能,通过XMINMAX寄存器设置窗口的上下限(MIN/MAX)。如果所选信号(如一个故障信号)的边沿出现在这个窗口内,则产生事件;如果窗口内没有边沿,反而可以配置产生一个“未发生”的Trip事件或中断。这用于监控某些必须在特定时间窗口内出现的信号(如反馈信号)。
此外,DCxEVT1LAT锁存功能在移相全桥(PSFB)等拓扑中非常有用。它允许你将一个事件(比如过流事件)锁存起来,并选择在不同的时间点(如CNT=0或CNT=PRD)清除。这样,你可以对周期循环(CBC)故障和单次触发(OST)故障采取不同的保护动作,例如CBC故障仅限流,而OST故障则完全关断。
4. 实战应用:构建一个过流保护与采样系统
假设我们要为一个三相电机驱动器实现硬件过流保护和同步电流采样。
目标:
- 当任意一相电流超过阈值(由CMPSS比较器判断),硬件立即关断所有6个PWM输出(高阻态)。
- 同时,产生一个中断通知CPU记录故障。
- 在正常的PWM周期中,当CMPA匹配(即PWM占空比点)时,触发ADC对三相电流进行同步采样。
系统设计:
- 过流保护(使用DC模块):
- 将三相下桥臂的电流采样信号接入三个CMPSS模块。
- 配置CMPSS输出连接到ePWM1的
DCAH输入(通过X-BAR)。 - 配置
DCTRIPSEL,选择DCAH信号源为这三个CMPSS输出的“或”逻辑(组合输入)。 - 配置
TZSEL,将DCAEVT1设置为Cycle-By-Cycle (CBC)和One-Shot (OST) Trip源。 - 配置
TZCTL和TZCTLDCA,使得当DCAEVT1.force事件发生时,将所有EPWMxA/B输出强制置为高阻态(Hi-Z)。 - 配置
TZEINT,使能DCAEVT1中断,以便在故障发生时进入ISR进行故障处理。 - 关键点:为
DCAEVT1配置消隐窗口,避开每个PWM周期开关时刻的噪声,防止误保护。
- 同步电流采样(使用ET模块):
- 假设我们使用ePWM1的计数器,并在
CTR=CMPA(递增计数时)进行采样。 - 配置
ETSEL.SOCASEL = 100b(CTR = CMPA when counting up)。 - ���置
ETSEL.SOCAEN = 1。 - 配置
ETPS.SOCAPRD = 1(每个CMPA匹配事件都触发SOCA)。 - 在ADC模块中,将
EPWM1SOCA配置为ADC的启动源。 - 这样,每次PWM的占空比更新点,ADC都会自动启动对三相电流的采样,实现了完美的硬件同步。
- 假设我们使用ePWM1的计数器,并在
调试技巧:
- 先分后合:先单独测试DC模块的Trip功能。可以暂时将
TZCTL配置为强制输出低电平,然后用一个GPIO模拟过流信号,观察PWM输出是否被正确拉低。用示波器看反应时间。 - 验证消隐:在PWM开关噪声期间,故意注入一个毛刺信号,观察是否被过滤掉;在消隐窗口外注入,观察是否正常触发Trip。
- ET模块测试:使用
ETFRC寄存器软件强制产生SOC事件,用示波器测量ADC的SOC引脚,看脉冲是否产生。然后结合PWM,看ADC采样是否精准对齐到CMPA匹配点。 - 优先级确认:明确Trip动作的优先级。在上述配置中,
DCAEVT1.force的优先级高于普通的TZ输入。确保在真实故障时,保护动作是绝对优先且不可被覆盖的。
5. 常见问题与排查实录
在实际调试中,我踩过不少坑,这里总结几个最常见的:
问题1:配置了ET,但ADC SOC始终不触发。
- 检查清单:
- 源头有没有:首先确认你选择的事件源是否真实发生。比如,你选择
CTR=CMPA,那就用仿真器或读取TBCTR和CMPA寄存器的值,确认在运行过程中它们是否真的相等。 - 使能开了没:
ETSEL.SOCAEN或ETSEL.SOCBEN必须设为1。 - 分频器状态:读取
ETPS.SOCACNT的值。如果它一直为0,说明事件没被计数;如果它卡在SOCAPRD-1,说明计数器满了但没触发,检查ETFLG.SOCA是否已置1但未被清除(ETCLR)。 - 输出映射:确认
EPWMxSOCA信号是否正确连接到ADC模块的触发源选择器。
- 源头有没有:首先确认你选择的事件源是否真实发生。比如,你选择
问题2:数字比较事件误触发,系统频繁进入保护。
- 首要怀疑对象是噪声:立即启用消隐窗口功能。根据你的开关频率和噪声持续时间,合理设置
DCFOFFSET和DCFWINDOW。一个经验值:对于几十到几百kHz的开关频率,消隐窗口设为5-20个TBCLK周期通常有效。 - 检查信号极性:确认
DCAH/DCAL等输入信号配置的极性(高有效/低有效)与实际硬件信号匹配。 - 检查X-BAR配置:这是最容易出错的地方。确保GPIO引脚已正确配置为ePWM Trip输入功能,并且通过INPUTxSELECT寄存器正确映射到了对应的
DCAH等信号。
问题3:使用谷底切换时,开通时刻总是不准,有偏差。
- 校准
SWVDELVAL:硬件捕获的CNTVAL是理想的半个谐振周期,但由于电路寄生参数(如MOSFET结电容、变压器漏感)、驱动延迟等,实际最优开通点会有偏移。这个偏移量需要软件补偿。方法是在一个稳态工作点,微调SWVDELVAL值,同时测量效率或开关节点波形,找到效率最高或电压振铃最小的点。 - 确认
STARTEDGE和STOPEDGE:确保你选择的边沿能稳定捕获到完整的半个谐振周期。有时需要配合边沿滤波器(EDGECOUNT)来避免误触发。 - 谐振频率变化:负载变化会导致谐振频率变化,
CNTVAL也会变。对于宽范围输出的应用,可能需要软件根据工作点动态调整SWVDELVAL,甚至建立一张查找表。
问题4:多个ePWM模块的事件需要同步触发。
- 使用同步链:利用ePWM的
EPWMxSYNCI和EPWMxSYNCO信号,将主模块的同步输出连接到从模块的同步输入。 - 使用
ETCNTINIT功能:在从模块中,使能ETCNTINITCTL[INTINITEN],并将触发源设置为同步输入事件。这样,当主模块发出同步脉冲时,从模块的INTCNT2等计数器会被初始化为ETCNTINIT[INTINIT]中设定的值。通过给不同从模块设置不同的初始值,可以实现多个ADC SOC脉冲之间精确的、可编程的相位差,这对于交错并联电源或多相电机控制非常有用。
最后,调试这些复杂的外设,善用寄存器的“影子”机制和“强制”功能。比如,在动态更新CMPA值改变PWM占空比时,要配置好影子寄存器加载时机(CTR=PRD或CTR=0),避免更新时刻的毛刺。而ETFRC、TZFRC这些强制寄存器,是你验证中断、SOC、Trip动作链路是否正常的“快捷键”,在系统初始化后的自检阶段非常有用。