TI eHRPWM寄存器深度解析:从时基到死区的电机控制实战配置

📅 2026/7/21 6:28:16 👁️ 阅读次数 📝 编程学习
TI eHRPWM寄存器深度解析:从时基到死区的电机控制实战配置

1. 从寄存器手册到实战代码:eHRPWM的深度配置哲学

搞嵌入式电机控制或者数字电源,PWM是绕不开的核心。手册上那些寄存器位定义,看一遍头大,看两遍似懂非懂,真到写代码调波形的时候,还是得翻回来一个字一个字地抠。TI的eHRPWM(增强型高分辨率脉宽调制器)功能强大,但寄存器也多,光看名字就一堆:TBCTL、CMPA、AQCTLA、DBCTL…… 今天我不讲那些泛泛的概念,就结合我这些年调F28379D、F280049这些芯片的实际经验,带你把这些关键寄存器“盘”明白。我们不止看它“是什么”,更要弄懂“为什么这么设”,以及“怎么设才不出幺蛾子”。目标是让你看完后,能直接对着寄存器手册,写出稳定、高效的PWM驱动代码。

2. 时基模块:PWM的心脏与节拍器

时基模块是整个eHRPWM的节奏之源。它就像一个乐队的指挥,决定了PWM脉冲的“拍子”(频率)和“起拍点”(相位)。配置不好,后面所有的比较、动作都是乱的。

2.1 核心寄存器拆解与配置逻辑

时基模块的核心是五个寄存器:TBCTL(控制)、TBSTS(状态)、TBPHS(相位)、TBCNT(计数器)和TBPRD(周期)。我们重点看控制逻辑。

TBCTL (Time-Base Control Register): 模式设定的总开关这个16位寄存器里的每一个位域,都直接决定了计数器如何运行。配置它,你需要想清楚下面几个问题:

  1. 计数模式 (CTRMODE[1:0]):这是第一个要定的。00是递增模式,01是递减模式,10是递增-递减模式。怎么选?不是拍脑袋,而是看你的应用。

    • 递增模式:计数器从0数到TBPRD,然后归零重启。产生的PWM波形通常是非对称的。它非常适合生成简单的、单边对齐的PWM,比如普通的LED调光、蜂鸣器。因为比较事件只在递增过程中发生一次,控制逻辑简单。
    • 递增-递减模式:计数器从0数到TBPRD,再从TBPRD数回0。这是电机控制和数字电源最常用的模式。因为它能产生中心对称的PWM波形,这种波形在频谱上的谐波分量更少,对电机转矩脉动和电源EMI更友好。在中心对称模式下,一个PWM周期内,比较事件会发生两次(递增和递减各一次),这为更复杂的控制(如空间矢量调制SVPWM)提供了基础。

    实操心得:如果你在做电机FOC(磁场定向控制),99%的情况要用递增-递减模式。这不仅关乎波形质量,还因为很多高级的触发事件(如ADC采样)都依赖于计数器等于0(ZRO)或等于周期(PRD)这个对称点。

  2. 时钟预分频 (CLKDIV[2:0] & HSPCLKDIV[2:0]):这两个位域共同决定了时基时钟TBCLK的频率。公式是TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)SYSCLKOUT是你的系统时钟,比如200MHz。

    • 为什么分两级?HSPCLKDIV是为了兼容老型号(如281x)的时钟结构,你可以把它看作一个固定的粗调。CLKDIV是细调。手册上HSPCLKDIV复位默认是/2CLKDIV默认是/1。所以默认TBCLK = SYSCLKOUT / 2
    • 配置计算:假设系统时钟200MHz,我们需要一个100kHz的PWM频率(周期10us),采用递增-递减模式,那么计数器从0到TBPRD再到0就是一个完整的PWM周期。我们需要根据分辨率需求反推TBPRD的值和分频系数。例如,若希望计数步进精细一些,我们可以先设定HSPCLKDIV=1CLKDIV=1,则TBCLK=200MHz。对于100kHz的中心对称PWM,半个三角波周期是5us。计数器从0计数到峰值的时间t = TBPRD / TBCLK。所以TBPRD = t * TBCLK = 5us * 200MHz = 1000。这意味着你的占空比调节分辨率是1/1000。如果你觉得1000不够精细,可以降低TBCLK(增大分频),但这样会降低PWM的动态响应速度。这是一个需要权衡的点。
  3. 影子寄存器与同步 (PRDLD, PHSEN, SYNCOSEL):这是eHRPWM高级且易错的地方。

    • PRDLD (周期装载模式):为0时,TBPRD使用影子寄存器。你写入的值先到影子寄存器,只在计数器归零(CTR=ZRO)时才加载到生效的“活动寄存器”。这至关重要!在电机控制中,我们经常在每个PWM周期更新新的占空比(写入CMPA)。如果TBPRD也在随意时刻更新,可能导致当前周期长度突变,产生非对称的畸形脉冲,损坏功率管。设置为影子模式,能确保周期值只在安全的边界(计数器为0)切换,保证波形连续性。
    • PHSEN (相位使能) & TBPHS (相位值):用于多个eHRPWM模块之间的同步。比如,你有三个eHRPWM模块驱动三相逆变器,你需要它们的三角载波同相位。你可以配置模块1为主,其SYNCOUT输出同步信号。模块2和3的PHSEN置1,并设置TBPHS=0。当主模块的同步信号到来,从模块的计数器会立刻被加载为TBPHS的值(这里是0),从而实现同步启动。PHSDIR则决定了同步后计数方向,在递增-递减模式下,通常设为1(向上),保证所有模块从0开始向上计数。

TBPRD & TBCNT: 周期与计数TBPRD就是上面公式计算出的那个值,决定了PWM频率。TBCNT是实时计数器,你通常不需要直接写它,除非做非常特殊的同步或调试。切记:在运行中直接写TBCNT会立即生效,可能打断正常计数过程,除非你知道确切后果,否则别动它。

2.2 时基模块配置代码示例与避坑指南

下面是一个典型的中心对称PWM时基初始化代码片段(以C语言为例):

// 假设 ePWM1 基地址为 0x4000_0000,各寄存器偏移量参考手册 volatile struct EPWM_REGS *ePWM1 = (void *)0x40000000; void EPWM1_TimeBase_Init(void) { // 停止时基计数器 ePWM1->TBCTL.bit.CTRMODE = TB_COUNT_FREEZE; // 0x3 // 配置时钟预分频: HSPCLKDIV = /1, CLKDIV = /1 // 假设SYSCLKOUT=200MHz,则TBCLK=200MHz ePWM1->TBCTL.bit.HSPCLKDIV = TB_HSPCLKDIV_DIV1; // 0x0 ePWM1->TBCTL.bit.CLKDIV = TB_CLKDIV_DIV1; // 0x0 // 设置周期值,对应PWM频率为100kHz (递增-递减模式) // 半周期时间 t_half = 1/(2*100kHz) = 5us // TBPRD = t_half * TBCLK = 5e-6 * 200e6 = 1000 ePWM1->TBPRD = 1000; // 配置为递增-递减模式 ePWM1->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 0x2 // 使能周期寄存器影子加载模式(安全!) ePWM1->TBCTL.bit.PRDLD = TB_SHADOW; // 配置同步信号输出:当计数器等于0时,产生同步输出 ePWM1->TBCTL.bit.SYNCOSEL = TB_SYNC_IN_CTR_ZERO; // 0x1 // 相位控制:本例中不与其他模块同步,故禁用相位加载 ePWM1->TBCTL.bit.PHSEN = TB_DISABLE; ePWM1->TBPHS.bit.TBPHS = 0; // 仿真模式:配置为自由运行,这样在代码调试暂停时,PWM输出不会停止 // 防止调试时功率管状态意外冻结 ePWM1->TBCTL.bit.FREE_SOFT = TB_FREE_RUN; }

避坑指南:

  1. 顺序很重要:一定要先停止计数器CTRMODE=3),再配置其他参数,最后启动计数。否则在配置过程中计数器乱跑,会导致不可预知的输出。
  2. 影子寄存器是朋友:对于TBPRD和后面要讲的CMPA/CMPB,在动态系统中务必使用影子模式。这是硬件提供的防止“毛刺脉冲”的机制。
  3. 计算溢出TBPRD是16位寄存器,最大值65535。计算时确保你的TBCLK和频率需求下,TBPRD的值不会超过这个范围。同时,过高的TBPRD值(接近65535)在高速TBCLK下意味着极低的PWM频率,可能不适用。
  4. 仿真模式设置FREE_SOFT位决定了仿真器暂停时PWM的行为。在��机驱动等危险场景中,务必设置为“自由运行”(FREE_SOFT=2或3),或者“完成当前周期后停止”。如果设置为“立即停止”,仿真器断点可能导致PWM输出突然卡在某个占空比,造成桥臂直通烧管。

3. 比较模块:PWM脉宽的雕刻刀

时基决定了脉冲的“框架”,比较模块则是在这个框架内“雕刻”出高电平的宽度。这是实现占空比控制的核心。

3.1 CMPA与CMPB:占空比的直接映射

CMPACMPB是两个独立的比较寄存器。它们的值会实时与TBCNT计数器的值进行比较。当TBCNT等于CMPACMPB时,就会产生一个“比较匹配”事件。这个事件本身不直接改变输出电平,而是送给下一个模块——动作限定器(AQ)去处理。

关键点在于映射关系:

  • 递增计数模式下,CMPA的值直接决定了从周期开始到输出跳变的时间。占空比 =CMPA / TBPRD
  • 递增-递减计数模式下,情况变得有趣,也是产生对称PWM的关键:
    • 在计数器递增阶段,当TBCNT从0增加到CMPA时,可以触发一次动作(比如置高)。
    • 在计数器递减阶段,当TBCNTTBPRD减少到CMPA时,会再次触发一次动作(比如置低)。
    • 这样,CMPA就控制了一个在周期中心对称的脉冲的宽度。占空比 =(2 * CMPA) / (2 * TBPRD) = CMPA / TBPRD。虽然公式和递增模式一样,但波形是中心对称的。

CMPB的作用类似,它为同一个ePWM模块的另一个输出通道(EPWMxB)或者更复杂的波形生成提供了独立的比较点。

3.2 CMPCTL:影子与装载时机的精密控制

CMPCTL寄存器控制着CMPACMPB的更新行为,其重要性不亚于比较值本身。

  • SHDWAMODE/SHDWBMODE (影子模式):TBPRD一样,强烈建议设置为影子模式(0)。你可以在任何时间安全地更新CMPA/CMPB的影子寄存器,而不会干扰当前正在进行的PWM周期。新的占空比将在你指定的“装载点”生效。

  • LOADAMODE/LOADBMODE (装载模式):这指定了影子寄存器中的新值何时被加载到活动寄存器。常见选项:

    • CTR=0:在计数器等于0时装载。对于递增-递减模式,这是最自然、最安全的选择,确保在新的PWM周期开始时采用新的占空比。
    • CTR=PRD:在计数器等于周期值时装载。在某些特定场景下有用。
    • CTR=0 or PRD:在0或PRD时都装载。这可以实现在一个PWM周期内更新两次比较值,用于某些高级调制。
    • Freeze:手动模式,不自动装载。
  • SHDWAFULL/SHDWBFULL (影子寄存器满标志):这是一个非常重要的状态位。当影子寄存器已经有一个值在等待装载(即FIFO满)时,该位会置1。如果你此时再写入一个新值,会覆盖之前等待装载的值,而不是排队。在编写动态更新占空比的函数时,必须检查这个标志位,或者确保你的更新速率不会快于PWM的装载周期(例如,每个PWM周期只更新一次),以避免丢失更新指令。

3.3 比较模块配置示例

void EPWM1_CounterCompare_Init(void) { // 配置CMPA和CMPB为影子模式 ePWM1->CMPCTL.bit.SHDWAMODE = CC_SHADOW; ePWM1->CMPCTL.bit.SHDWBMODE = CC_SHADOW; // 配置装载时机:在计数器等于0时装载(对于UPDOWN模式,这是周期起点) ePWM1->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; ePWM1->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // 初始化比较值,设置初始占空比为50% // 对于递增-递减模式,CMPA=TBPRD/2 即得50%占空比中心对称脉冲 ePWM1->CMPA.bit.CMPA = 500; // 假设TBPRD=1000 // CMPB可以用于生成另一路PWM,或用于更复杂的动作。这里先设为0。 ePWM1->CMPB.bit.CMPB = 0; // 动态更新CMPA的函数示例(需在中断或主循环中调用) } void EPWM1_UpdateDutyCycle(float duty_cycle) { // duty_cycle: 0.0 ~ 1.0 Uint16 cmp_val = (Uint16)((float)ePWM1->TBPRD * duty_cycle); // 可选:检查影子寄存器是否已满。如果更新过快,可能丢失指令。 // if (ePWM1->CMPCTL.bit.SHDWAFULL) { // // 处理策略:等待、跳过或使用立即模式强制写入 // } ePWM1->CMPA.bit.CMPA = cmp_val; // 写入影子寄存器 // 新值将在下一个CTR=0时刻生效 }

避坑指南:

  1. CMPA不能大于TBPRD:在递增或递增-递减模式下,如果CMPA值大于TBPRD,在递增阶段永远不会发生匹配,导致输出异常(常高或常低)。软件上必须做限幅保护。
  2. 影子寄存器的同步问题:在高速实时控制中(如电流环),计算出的新CMPA值写入寄存器的时间点很关键。理想情况是在CTR=PRD(波谷)或CTR=0(波峰/起点)之后立即写入,确保其能在一个PWM周期内被装载。有时需要结合CPU和ePWM的同步机制来优化。
  3. 高分辨率PWM (HRPWM):如果你使用的芯片支持HRPWM,那么CMPAHR这个寄存器就派上用场了。它提供了CMPA的小数部分(通常4-8位),能将PWM分辨率从TBCLK提升到SYSCLKOUT的级别。这对于需要极精细电压调节的数字电源至关重要。使用时,需要联合配置CMPA(整数部分)和CMPAHR(小数部分)。

4. 动作限定器:波形生成的导演

动作限定器(AQ)模块是真正将“比较事件”翻译成“输出动作”的导演。它定义了当TBCNT等于ZROPRDCMPACMPB这些特定时刻,输出引脚EPWMxAEPWMxB应该做什么。

4.1 AQCTLA与AQCTLB:定义动作剧本

这两个寄存器结构完全一样,分别控制A和B两个输出通道。每个寄存器里针对ZROPRDCAU(CMPA Up)、CAD(CMPA Down)、CBUCBD这六个事件,都有2个比特位来定义动作:

  • 00:不采取行动(忽略事件)
  • 01:清除(将输出强制拉低)
  • 10:置位(将输出强制拉高)
  • 11:翻转(高变低,低变高)

如何编排动作来生成PWM?这是理解eHRPWM的关键一步。我们以最常用的递增-递减模式、中心对称PWM、高电平有效为例,生成EPWMxA的输出:

  1. 目标波形:一个中心对称的脉冲,占空比由CMPA控制。
  2. 动作设计
    • 在计数器从0开始递增时,当TBCNT等于CMPACAU事件),我们希望输出从低变高。所以,设置AQCTLA.CAU = 10(置高)。
    • 在计数器达到TBPRD后开始递减,当TBCNT再次等于CMPACAD事件),我们希望输出从高变低。所以,设置AQCTLA.CAD = 01(清除)。
    • 对于ZROPRD事件,在这个简单PWM生成中不需要动作,设为00
    • CMPB相关事件(CBU,CBD)也用不到,设为00

这样,在一个周期内,输出就会在CAU时拉高,在CAD时拉低,形成一个以周期中心为对称轴的方法脉冲。

4.2 高级动作模式与软件强制

动作限定器不仅限于生成简单PWM。通过组合不同事件的动作,可以生成复杂波形。

  • 互补带死区PWM的生成:这是电机驱动半桥或全桥的标准需求。你需要两个互补的PWM信号(EPWMxA和EPWMxB),并且之间要有死区。这通常不是单独用AQ完成的,而是AQ生成一对互补信号(例如,CAU置高A,清除B;CAD清除A,置高B),然后交给后面的死区模块插入死区。AQ负责生成逻辑上的互补信号。
  • 单事件触发:你可以配置在ZRO事件时翻转输出,这样会生成一个频率为PWM频率一半的方波,占空比固定50%。
  • 软件强制 (AQSFRC & AQCSFRC):这两个寄存器允许你在代码中手动、立即地强制输出为高、低或翻转,而不依赖于计数器事件。
    • AQSFRC(一次性强制):像扣动一次扳机。写OTSFA=1并指定ACTSFA动作,可以立即对EPWMxA输出执行一次强制操作(如置高),然后该位自动清零。用于紧急关断、测试等。
    • AQCSFRC(连续强制):像按住开关。设置CSFA可以持续强制输出为高或低,覆盖所有AQ事件产生的动作。这在故障安全状态下非常有用,比如故障发生时,可以强制所有PWM输出为低(封锁驱动)。

4.3 动作限定器配置示例

void EPWM1_ActionQualifier_Init(void) { // 配置EPWMxA输出为高电平有效的中心对称PWM // 当计数器递增至CMPA时,置高EPWMxA ePWM1->AQCTLA.bit.CAU = AQ_SET; // 0x2 // 当计数器递减至CMPA时,拉低EPWMxA ePWM1->AQCTLA.bit.CAD = AQ_CLEAR; // 0x1 // 其他事件不动作 ePWM1->AQCTLA.bit.ZRO = AQ_DISABLE; ePWM1->AQCTLA.bit.PRD = AQ_DISABLE; ePWM1->AQCTLA.bit.CBU = AQ_DISABLE; ePWM1->AQCTLA.bit.CBD = AQ_DISABLE; // 配置EPWMxB输出为与EPWMxA互补的波形(死区由后续DB模块添加) // 当计数器递增至CMPA时,拉低EPWMxB (与A相反) ePWM1->AQCTLB.bit.CAU = AQ_CLEAR; // 当计数器递减至CMPA时,置高EPWMxB (与A相反) ePWM1->AQCTLB.bit.CAD = AQ_SET; // 初始化软件强制寄存器:禁用强制 ePWM1->AQSFRC.bit.OTSFA = 0; ePWM1->AQSFRC.bit.ACTSFA = AQ_DISABLE; ePWM1->AQCSFRC.bit.CSFA = AQCSFRC_DISABLE; } // 示例:紧急关断函数,立即强制所有PWM输出低 void EPWM1_ForceTrip(void) { // 使用连续软件强制,覆盖所有AQ动作 ePWM1->AQCSFRC.bit.CSFA = AQCSFRC_FORCE_LOW; // 0x1 ePWM1->AQCSFRC.bit.CSFB = AQCSFRC_FORCE_LOW; // 注意:这需要与故障联防逻辑结合,通常由TZ模块硬件触发更可靠 }

避坑指南:

  1. 动作冲突:如果多个事件(如CAUZRO)被配置为对同一输出通道进行不同的动作,它们发生的先后顺序将决定最终输出。需要仔细分析计数器运行轨迹,避免非预期的输出跳变。
  2. 初始化顺序:在配置AQ之前,确保时基计数器已停止(CTRMODE=Freeze),并且CMPA/CMPB已设置为合理的初始值。否则,在配置过程中可能因为意外的比较匹配而产生毛刺。
  3. 软件强制的优先级:连续软件强制(AQCSFRC)的优先级最高,它会覆盖一次性强制(AQSFRC)和所有硬件AQ事件。一次性强制又会覆盖硬件AQ事件。在设计保护逻辑时要理清层次。

5. 死区生成模块:安全与效率的守护者

在驱动H桥、三相逆变器等桥式电路时,同一桥臂的上、下两个开关管绝对不能同时导通(直通),否则会瞬间短路电源,烧毁器件。死区时间就是在互补的PWM信号中插入的一段两个信号都为低电平(或都为高电平,取决于配置)的短暂延时,确保一个管子完全关断后,另一个管子才开启。

5.1 DBCTL:死区工作模式的大脑

DBCTL寄存器控制死区模块的输入源、输出极性和工作模式。

  • IN_MODE[1:0] (输入模式选择):选择哪个信号作为上升沿和下降沿延迟的输入源。最经典的模式是00:EPWMxA作为两个延迟单元的输入。这样,AQ模块生成的一对原始互补信号(假设A为原信号,B为反信号),都送入死区模块,分别进行上升沿延迟和下降沿延迟,最终得到带死区的两路信号。
  • POLSEL[1:0] (极性选择):选择是否对延迟后的信号进行反相。这是为了适配不同的功率器件驱动逻辑。
    • 00(Active High, AH):都不反相。高电平表示开通功率管。这是最直观的模式。
    • 01(Active Low Complementary, ALC):反相EPWMxA。这意味着原信号A经过死区后,输出是反相的。通常用于需要低电平有效的驱动芯片。
    • 10(Active High Complementary, AHC):反相EPWMxB。
    • 11(Active Low, AL):两个都反相。
    • 如何选择?这取决于你的功率器件驱动电路。比如,很多IGBT驱动芯片是“高电平有效”,即输入高,输出驱动高,开通IGBT。那么你就用AH模式。如果你的驱动芯片是低电平有效,或者你使用的是PMOS作为上管,NMOS作为下管,可能需要ALC或AHC模式。务必对照驱动芯片数据手册和电路原理图来配置。
  • OUT_MODE[1:0] (输出模式选择):决定死区功能是否启用。
    • 00:完全旁路。AQ的输出直接送到下一级。用于不需要死区的场景。
    • 01:禁用上升沿延迟。EPWMxA直通,EPWMxB使用下降沿延迟。不常用。
    • 10:禁用下降沿延迟。EPWMxB直通,EPWMxA使用上升沿延迟。不常用。
    • 11完全使能。这是最常用的模式,对EPWMxA进行上升沿延迟,对EPWMxB进行下降沿延迟(假设IN_MODE=00),生成带死区的互补信号。

5.2 DBRED与DBFED:死区时间的量化设置

DBREDDBFED是两个10位寄存器,分别控制上升沿延迟和下降沿延迟的计数值。

  • 延迟时间计算:死区时间T_db = DEL * T_tbclk。其中DEL是你写入DBRED.DELDBFED.DEL的值,T_tbclk是时基时钟周期(1/TBCLK)。
  • 举例:TBCLK = 200MHz,周期T_tbclk = 5ns。如果需要500ns的死区时间,则DEL = 500ns / 5ns = 100。将这个值写入DBREDDBFED
  • 上升沿 vs 下降沿:对于典型的互补PWM,我们通常设置DBREDDBFED为相同的值,以得到对称的死区。但模块也支持非对称延迟,用于某些特殊调制。

5.3 死区模块配置示例与波形分析

void EPWM1_DeadBand_Init(void) { // 配置死区输入:使用EPWMxA作为源,生成两路延迟信号 ePWM1->DBCTL.bit.IN_MODE = DBA_IN_MODE_ENABLE; // 0x0, EPWMxA as source for both // 配置输出极性:假设驱动芯片为高电平有效,使用标准AH模式 ePWM1->DBCTL.bit.POLSEL = DB_ACTV_HI; // 0x0 // 完全使能死区生成功能 ePWM1->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 0x3 // 设置死区时间,单位为TBCLK周期 // 例如:需要 500ns 死区,TBCLK=5ns (200MHz) Uint16 db_delay_counts = 100; // 500ns / 5ns = 100 ePWM1->DBRED.bit.DEL = db_delay_counts; ePWM1->DBFED.bit.DEL = db_delay_counts; }

配置完成后,假设AQ模块产生了一对理想的互补信号(A高时B低,A低时B高),经过死区模块处理,波形变化如下:

  1. 原始EPWMxA(来自AQ):在CAU(CMPA Up)时刻从低跳高,在CAD(CMPA Down)时刻从高跳低。
  2. 原始EPWMxB(来自AQ):与A完全互补(在CAU时刻跳低,在CAD时刻跳高)。
  3. 经过死区模块后
    • 最终EPWMxA输出:在原始A信号的上升沿处,被延迟了DBRED个时钟周期。即,原始A变高后,再等一个死区时间,最终输出A才变高。其下降沿不受影响(或说,下降沿延迟被应用到了B通道的对应边沿上)。
    • 最终EPWMxB输出:在原始B信号的上升沿(对应原始A的下降沿)处,被延迟了DBFED个时钟周期。即,原始A变低(原始B变高)后,再等一个死区时间,最终输出B才变高。

这样,在原始A上升沿到最终A上升沿之间,以及原始A下降沿(原始B上升沿)到最终B上升沿之间,两路最终输出同时为低,形成了死区。

避坑指南:

  1. 死区时间不足:这是最危险的。死区时间必须大于功率器件(MOSFET/IGBT)的关断延迟时间。通常需要根据器件数据手册中的td(off)(关断延迟)和t_f(下降时间)来估算,并留有一定裕量(比如1.5-2倍)。计算出的计数值DEL必须大于0。
  2. 死区时间过长:虽然安全,但会降低最大可用占空比,导致输出电压损失。在高速开关应用中(如几百kHz),死区时间占整个周期的比例可能很大,需要仔细权衡。
  3. 极性配错POLSEL配置错误会导致该开通的管子关断,该关断的管子开通,直接导致短路。上电前必须反复检查。一个简单的验证方法是:在空载、低压下,用示波器观察驱动芯片的输入或输出波形,确保逻辑符合预期。
  4. 寄存器写入时机:和CMPA一样,DBRED/DBFED也有影子寄存器(虽然手册片段未明确显示其控制位,但在完整eHRPWM中通常可配置)。在运行中修改死区时间,也建议通过影子寄存器在安全点(如CTR=0)切换,以避免产生中间状态的错误脉冲。

6. 故障联防与高分辨率扩展

除了上述核心模块,eHRPWM还有两个关键子模块:故障联防(Trip-Zone, TZ)和高分辨率PWM(HRPWM)。它们对于构建可靠、高性能的系统不可或缺。

6.1 故障联防模块:系统的紧急制动

TZ模块是硬件安全网络。它通过外部引脚(TZ1~TZ3)或内部事件(如ADC过流、比较器)接收故障信号,一旦触发,可以在几个时钟周期内强制PWM输出进入预设的安全状态(高阻、拉高或拉低),这个速度远超CPU中断响应。

  • 寄存器概览:主要涉及TZSEL(选择哪些TZ信号映射到本模块)、TZCTL(配置故障发生时每个PWM输出的动作)、TZEINT(使能故障中断)、TZFLG/TZCLR(标志位和清除)等。
  • 关键配置:在TZCTL中,你需要为每个PWM输出(EPWMxA/B)选择故障动作,例如:
    • TZCTL[TZA].bit = 1:故障时,强制EPWMxA输出高。
    • TZCTL[TZA].bit = 2:故障时,强制EPWMxA输出低。
    • TZCTL[TZA].bit = 3:故障时,将EPWMxA置为高阻态(如果引脚配置允许)。
    • 对于电机驱动,通常选择强制输出低2),以关闭所有功率管。
  • 工作模式
    • 单次触发 (One-shot):故障发生后,PWM输出被强制锁定在安全状态,直到软件清除标志位并重新使能PWM。
    • 周期触发 (Cycle-by-cycle):故障发生后,PWM输出在当前周期被强制为安全状态,但下一个PWM周期会自动恢复,除非故障信号持续存在。这用于过流保护,允许在每个周期进行限制。
  • 实操要点:一定要将关键的硬件保护信号(如直流母线过压、相电流过流比较器输出)连接到TZ引脚。软件保护(ADC采样后计算)作为第二道防线。TZ是最后的安全保障。

6.2 高分辨率PWM:突破数字精度的极限

标准PWM的分辨率受限于TBCLK。例如TBCLK=200MHz,PWM频率100kHz,则分辨率约为1 / (2 * TBPRD) = 1/2000 = 0.05%。对于要求极高精度调节的应用(如通信电源的电压纹波控制),这可能不够。

HRPWM通过一个称为“微边沿定位器(MEP)”的技术,利用系统时钟SYSCLKOUT(通常比TBCLK快很多)对PWM边沿进行亚周期级的微调。它扩展了CMPATBPHS寄存器,增加了高分辨率影子寄存器CMPAHRTBPHSHR

  • 核心思想CMPA寄存器控制跳变边沿的“粗”位置(以TBCLK为单位),而CMPAHR寄存器控制在该TBCLK周期内的“细”位置(以SYSCLKOUT为单位)。
  • 配置步骤
    1. 使能HRPWM模块(通常通过HRPCTL寄存器)。
    2. 配置HRPCTL中的TBPHSHRCMPAHR装载模式,类似其低分辨率部分。
    3. 在更新占空比时,同时写入CMPACMPAHR。例如,如果需要占空比对应计数值为1000.75,则设置CMPA = 1000CMPAHR = 0.75 * 256(假设MEP精度为8位)。
  • 注意事项:MEP的精度受工艺、电压、温度影响。TI提供了校准程序,通常需要在初始化时运行,将校准值写入HRMSTEP寄存器,以确保线性度。

7. 综合配置流程与调试技巧

将上述所有模块整合,一个完整的eHRPWM初始化流程应遵循以下顺序:

  1. 失能模块并配置仿真行为:停止计数器(TBCTL.CTRMODE=Freeze),设置FREE_SOFT
  2. 配置时基:设置TBCLK分频(CLKDIV,HSPCLKDIV)、计数模式(CTRMODE)、周期(TBPRD)、相位(TBPHS)和同步(SYNCOSEL,PHSEN)。
  3. 配置比较模块:设置CMPA/CMPB影子/装载模式(CMPCTL),并写入初始比较值。
  4. 配置动作限定器:根据所需的PWM波形模式,配置AQCTLAAQCTLB
  5. 配置死区:设置死区时间(DBRED,DBFED)、输入模式和极性(DBCTL)。
  6. 配置故障联防:配置TZSEL,TZCTL,TZEINT等,建立硬件保护。
  7. (可选)配置高分辨率模式:如果需要,使能并配置HRPWM相关寄存器。
  8. 启动时基计数器:最后,将TBCTL.CTRMODE设置为UPUPDOWN,让PWM开始运行。

调试技巧实录:

  1. 无输出或波形不对

    • 检查时钟:首先确认系统时钟SYSCLKOUT是否正确,TBCLK分频是否合理。可以用示波器测量一个GPIO翻转的简单延时程序来验证CPU时钟。
    • 检查引脚复用:确认ePWM输出引脚是否已正确配置为外设功能,而不是GPIO。查看芯片的GPIO MUX寄存器。
    • 逐步验证法:先屏蔽死区和AQ复杂配置。将AQCTLA配置为在ZRO时置高,PRD时清除,生成一个简单的50%占空比方波。看是否有基础波形输出。然后再逐步加入比较、死区等功能。
  2. 占空比更新不生效

    • 检查影子寄存器:确认CMPCTL.SHDWAMODE=0(影子模式),并且LOADAMODE设置正确(如CTR=ZERO)。
    • 检查写入时机:确保你在一个PWM周期内只写入一次CMPA,并且最好在CTR=PRDCTR=ZERO之后尽快写入。可以在CTR=PRD事件触发的中断里更新。
    • 检查SHDWAFULL标志:如果更新过快,可能因为影子寄存器满而丢失更新。在调试时加入对该标志的判断和处理。
  3. 死区时间异常

    • 计算验证:用示波器测量死区时间,验证是否与(DBRED.DEL / TBCLK)计算值相符。
    • 极性检查:用示波器同时观察AQ模块输出的原始信号(可通过配置DBCTL.OUT_MODE=00旁路死区得到)和最终输出信号,确认死区插入逻辑和极性是否正确。
  4. 使用CCS的寄存器视图和图形化工具:TI的Code Composer Studio IDE可以实时显示和修改外设寄存器值,并且其ePWM图形化配置工具能直观地展示不同配置下的波形,是学习和调试的利器。但切记,工具生成的代码有时不够优化或不符合你的架构,理解寄存器原理后,可以手动编写或修改。

理解eHRPWM寄存器,就像掌握了乐高积木的每个零件。时基、比较、动作、死区这些模块各司其职,又紧密配合。从简单的LED调光到复杂的三相电机矢量控制,其底层都离不开对这些寄存器的精准操控。手册是地图,实践是道路,希望这篇基于实战的解析,能帮你更自信地驾驭这颗嵌入式系统中最核心的“脉搏”发生器。