TI C2000 ePWM核心寄存器深度解析:从CMPA到死区控制的实战指南

TI C2000 ePWM核心寄存器深度解析:从CMPA到死区控制的实战指南

1. 项目概述与ePWM核心价值

在电机驱动、开关电源、数字功放这些需要精确功率控制的领域,脉冲宽度调制(PWM)技术是绝对的基石。它的核心思想很直观:通过快速开关一个信号,并调整“开”的时间(即脉宽)占整个周期的比例(占空比),来控制输出到负载上的平均电压或电流。占空比越大,平均功率就越高。然而,在微控制器(MCU)层面,如何稳定、精确、安全地生成这些PWM波形,尤其是在驱动半桥或全桥电路时,防止上下管直通(短路)这种致命问题,就成了嵌入式工程师必须啃下的硬骨头。

德州仪器(TI)在其C2000系列等高性能微控制器中集成的增强型PWM(ePWM)模块,就是为了解决这些复杂需求而生的硬件利器。它远不止是一个简单的定时器加比较器。你可以把它想象成一个高度专业化、可编程的“波形生成与保护引擎”。这个引擎的核心驱动力,就是一系列精心设计的硬件寄存器。直接对着数据手册的寄存器描述进行配置,对于新手来说往往如同阅读天书,知其然不知其所以然。今天,我就结合自己多年在电机控制项目中的实际调试经验,深入拆解ePWM模块中最关键、也最容易让人困惑的几个寄存器组:CMPA/CMPBAQCTLA/AQCTLB以及DBCTL/DBFED/DBRED。我会抛开枯燥的位域描述,重点讲清楚它们在实际电路中是如何协同工作,一步步将你的配置代码变成稳定可靠的功率开关信号的。无论你是正在学习C2000的新手,还是希望优化现有PWM逻辑的老手,理解这些寄存器的“行为”而非仅仅是“定义”,都能让你在调试时更加得心应手。

2. ePWM模块架构与寄存器角色总览

在深入单个寄存器之前,我们必须先建立起对ePWM模块整体数据流和工作原理的宏观认识。如果把一个ePWM通道(例如ePWM1)看作一个生产流水线,那么各个寄存器就是这条流水线上不同工位的控制面板。

2.1 核心子模块与信号流

一个标准的ePWM通道包含多个子模块,它们按顺序处理信号:

  1. 时间基准(TB)模块:这是整个系统的“心跳”。TBCTR寄存器是这个模块的核心,它是一个计数器,可以配置为递增、递减或增减计数模式。TBPRD寄存器定义了它的计数周期。TBCTR的数值变化,是后续所有动作的时序基准。
  2. 计数比较(CC)模块:这是“事件发生器”。CMPACMPB寄存器是这里的核心。它们内部的值会与不断变化的TBCTR值进行实时比较。当两者相等时,就会产生一个“匹配事件”(如CTR=CMPA)。这个事件本身并不直接改变输出引脚的电平,它只是一个触发信号。
  3. 动作限定(AQ)模块:这是“指令执行器”。AQCTLAAQCTLB寄存器在这里扮演决策者的角色。它们定义了当接收到来自CC模块的特定事件(如CTR=CMPA且计数器在递增)时,应对EPWMxAEPWMxB输出引脚采取什么“动作”:置高(Set)、拉低(Clear)、翻转(Toggle)或忽略(Do nothing)。
  4. 死区生成(DB)模块:这是“安全调度员”。在驱动桥式电路时,AQ模块输出的原始信号(假设是互补的)如果直接驱动上下管,可能在开关切换的瞬间产生同时导通的危险。DBCTLDBRED(上升沿延迟)和DBFED(下降沿延迟)寄存器组成的死区模块,负责对AQ输出的信号进行可编程的边沿延迟,确保在任何时刻,两个互补的输出信号之间都有一个“两者都为低”的安全死区时间,从而从根本上避免直通。
  5. 错误联防(TZ)模块:这是“紧急制动系统”。TZSELTZCTL等寄存器用于配置当外部故障信号(如过流、过温)触发时,ePWM输出应采取何种紧急措施(如强制高阻态、强制拉低),以实现毫秒级甚至微秒级的硬件保护。

2.2 寄存器访问的“影子”与“活动”模式

这是理解ePWM配置同步性的关键,也是新手最容易栽跟头的地方。以CMPA寄存器为例,数据手册会提到“Shadow Register”(影子寄存器)和“Active Register”(活动寄存器)。

  • 活动寄存器:直接控制硬件比较器的那个寄存器。它的值直接决定了何时产生比较事件。在运行时直接修改它,会导致PWM波形立即突变,可能产生不可预测的毛刺。
  • 影子寄存器:一个缓冲寄存器,供CPU(你写的代码)安全地写入新值。它不直接影响当前波形。

CMPCTL[SHDWAMODE]等控制位决定了CMPA的工作模式。默认是影子模式启用。在此模式下:

  • 你的EPwm1Regs.CMPA.half.CMPA = 500;这条语句,实际上是把500写入了CMPA的影子寄存器。
  • 硬件会在一个安全的时刻(例如TBCTR等于0时,由CMPCTL[LOADAMODE]配置),自动将影子寄存器的值加载到活动寄存器。这个时刻称为“加载点”。
  • 这种机制保证了PWM占空比的改变与计数器周期同步,避免了波形在一个周期中间发生畸变。

实操心得:在初始化或需要动态调整PWM时,务必检查CMPCTLTBCTL寄存器中关于影子加载的配置。如果你在运行时修改了CMPA的值但波形没变化,第一反应就应该是去确认影子加载事件是否已正确配置并发生。你可以通过查询CMPCTL[SHDWAFULL]位来判断影子寄存器是否已满(即是否有新值等待加载)。

3. 核心寄存器深度解析与配置逻辑

理解了架构,我们就可以深入到每个核心寄存器的具体配置逻辑和它们之间的联动了。

3.1 CMPA与CMPB:脉宽设定的“标尺”

CMPACMPB是两个16位的比较寄存器。它们的核心功能非常简单:提供一个数值,让硬件不断地与时间基准计数器TBCTR做比较。

  • 工作原理:假设TBPRD设为1000(即计数器从0计数到1000),TBCTR工作在递增计数模式。如果你将CMPA设为300,那么在每个PWM周期内,当TBCTR从0开始计数,经过300个时钟节拍时,硬件就会检测到TBCTR == CMPA,随即产生一个CTR=CMPA事件。这个事件会被发送到AQ模块。
  • 与占空比的关系:PWM的占空比 = (有效电平时间)/ 周期。而CMPA的值直接决定了有效电平的边沿位置。但请注意CMPA本身不决定电平高低,只决定“事件”发生的时刻。电平高低由AQ模块根据这个事件来决策。例如,在递增计数且AQCTLA配置为“当CTR=CMPA时清除EPWMxA”,那么CMPA=300就意味着EPWMxA信号会在计数器到达300时被拉低。如果另一个边沿(比如由TBCTR=0事件设置为高),那么高电平时间就对应计数器从0到300的区间,占空比就是300/1000=30%。
  • CMPA与CMPB的协同:你可以使用CMPACMPB来生成更复杂的波形。例如,生成一个带中间凹陷的PWM(常用于某些特定的电机控制算法)。CMPA定义第一个边沿,CMPB定义第二个边沿,AQ模块可以分别响应这两个事件,通过“置高”、“拉低”、“翻转”的组合,在单个周期内塑造出复杂的输出波形。

配置示例与计算: 假设我们需要在EPWM1A上生成一个频率为10kHz,占空比为40%的PWM波。系统时钟SYSCLKOUT为100MHz,ePWM时钟预分频器设为/1(即TBCLK = 100MHz)。

  1. 计算周期值TBPRD:PWM周期 T = 1 / 10kHz = 100us。TBCLK周期 = 1 / 100MHz = 10ns。因此,一个PWM周期需要的TBCLK ticks数 = 100us / 10ns = 10000。所以TBPRD = 10000 - 1 = 9999(因为计数器从0开始)。
  2. 计算比较值CMPA��对于40%占空比,高电平时间应为 40% * 100us = 40us。对应的TBCLK ticks数 = 40us / 10ns = 4000。如果我们配置为计数器递增时,在CTR=0事件设置输出高,在CTR=CMPA事件清除输出低,那么CMPA = 4000
  3. 代码示意(基于TI的DriverLib或寄存器直接操作)
    // 假设使用寄存器直接操作(以TI C2000为例) EPwm1Regs.TBPRD = 9999; // 设置周期 EPwm1Regs.CMPA.half.CMPA = 4000; // 设置比较值,决定占空比 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 设置为递增计数模式 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位同步 EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟分频 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟分频

3.2 AQCTLA与AQCTLB:波形塑形的“导演”

动作限定寄存器AQCTLAAQCTLB是ePWM的灵魂所在,它们将单调的计时事件翻译成丰富的波形语言。每个寄存器控制一个输出引脚(A或B),并针对多种事件定义动作。

  • 核心事件:每个AQCTL寄存器主要响应五种事件:
    • CAU/CAD: 计数器等于CMPA且正在递增(Up)/递减(Down)。
    • CBU/CBD: 计数器等于CMPB且正在递增/递减。
    • PRD: 计数器等于周期值(TBCTR == TBPRD)。在增减计数模式下,此时计数器方向定义为向下。
    • ZRO: 计数器等于0。在增减计数模式下,此时计数器方向定义为向上。
  • 动作类型:对于每个事件,可以配置四种动作之一(2位编码):
    • 0b00: 无操作(忽略事件)。
    • 0b01: 清除(Clear)——强制输出为低电平。
    • 0b10: 置位(Set)——强制输出为高电平。
    • 0b11: 翻转(Toggle)——输出电平取反。

经典配置模式解析

  1. 非对称PWM(递增计数):这是最常用的模式。以EPWMxA为例,我们希望它在周期开始时为高,在CMPA时刻变低。

    • AQCTLA配置:ZRO事件 ->Set(计数器为0时置高);CAU事件 ->Clear(计数器等于CMPA且递增时拉低)。
    • 这样,每个周期开始时输出变高,到达CMPA值时变低,并保持低电平直到周期结束。占空比 =CMPA / TBPRD
  2. 对称PWM(增减计数):这种模式产生的PWM波形关于周期中心对称,能有效降低谐波,常用于电机控制和逆变器。

    • 目标:在周期中心点附近输出高电平脉冲。
    • 配置思路:我们需要在计数器递增到CMPA时置高,在计数器递减到CMPA时拉低(或者反过来)。这里CMPA定义的是脉冲的“半宽”。
    • AQCTLA配置:CAU事件 ->SetCAD事件 ->Clear
    • 此时,高电平时间对应于计数器从CMPA递增到TBPRD再递减回CMPA的区间。占空比 =2 * (TBPRD - CMPA) / (2 * TBPRD) = (TBPRD - CMPA) / TBPRD。注意这里CMPA越大,高电平时间反而越短。
  3. 互补带死区PWM:这是驱动半桥的核心。我们需要EPWMxA和EPWMxB输出互补的波形,但必须通过死区模块(下一节详述)来插入延迟,不能直接由AQ模块生成完全互补的信号。通常,我们先让AQ模块生成一对同相或反相的基础波形,然后交给DB模块处理。

    • 一种常见配置是:让AQCTLAAQCTLB对相同的事件做出相反的动作。例如,对于ZRO事件,AQCTLA设为SetAQCTLB设为Clear;对于PRD事件,AQCTLA设为ClearAQCTLB设为Set。这样,在AQ模块输出端,EPWMxA和EPWMxB已经是互补的方波。但是,这个信号不能直接用于驱动!必须送入DB模块插入死区。

配置示例(互补对称PWM的AQ部分)

// 生成一对互补的对称PWM(AQ模块输出,尚未加死区) // 假设使用CMPA定义脉冲宽度,CMPB未使用 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // CTR上升至CMPA时,EPWM1A置高 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // CTR下降至CMPA时,EPWM1A拉低 EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // CTR上升至CMPA时,EPWM1B拉低 EPwm1Regs.AQCTLB.bit.CAD = AQ_SET; // CTR下降至CMPA时,EPWM1B置高 // 注意:此时EPWM1A和EPWM1B是瞬间互补的,存在直通风险!

4. 死区控制:DBCTL、DBRED与DBFED的实战应用

死区控制是ePWM用于功率驱动场景的“安全锁”。它的原理是在一对互补的PWM信号的边沿处,人为地加入一段两者都为低电平(或都为高电平,取决于功率管类型)的时间,确保一个管子完全关断后,另一个管子才开启。

4.1 死区模块的工作流程

死区模块接收来自AQ模块的原始信号(EPWMxA_In, EPWMxB_In),并输出经过延迟处理后的信号(EPWMxA_Out, EPWMxB_Out)。它内部包含两个独立的延迟单元:一个处理上升沿(Rising Edge Delay),一个处理下降沿(Falling Edge Delay)。DBREDDBFED这两个10位寄存器,就分别定义了这两个延迟的时钟周期数。

关键点:延迟是针对边沿的,而不是针对整个电平。DBRED会在输入信号的上升沿到来时,启动一个计数器,延迟指定的时钟数后,才在输出端产生上升沿。DBFED同理。

4.2 DBCTL寄存器的三重配置哲学

DBCTL寄存器是死区模块的“总指挥”,它通过三个关键的位域(OUT_MODE,IN_MODE,POLSEL)来定义整个信号流图。

  1. OUT_MODE(输出模式控制):决定死区功能是否启用,以及如何应用到两个输出上。

    • 00:直通模式。死区模块被完全旁路,AQ的输出直接送到最终输出。在调试初期或不需要死区的场合使用。
    • 01:仅启用下降沿延迟。EPWMxA_In直通到EPWMxA_Out;EPWMxB_In经过下降沿延迟后输出到EPWMxB_Out。IN_MODE决定EPWMxB_In的延迟源是谁。
    • 10:仅启用上升沿延迟。EPWMxA_In经过上升沿延迟后输出到EPWMxA_Out;EPWMxB_In直通到EPWMxB_Out。IN_MODE决定EPWMxA_In的延迟源是谁。
    • 11:全功能模式(最常用)。EPWMxA_Out是EPWMxA_In经过上升沿延迟后的信号;EPWMxB_Out是EPWMxB_In经过下降沿延迟后的信号。IN_MODE为每个延迟单元选择输入源。
  2. IN_MODE(输入模式控制):为上升沿延迟和下降沿延迟单元选择输入信号源。这是实现灵活死区控制的关键。

    • 00:经典模式。EPWMxA_In同时作为上升沿和下降沿延迟单元的输入。这是数据手册的“默认”配置,但需要配合特定的POLSEL和AQ配置才能生成正确的互补带死区信号。
    • 01: EPWMxA_In作为下降沿延迟的输入,EPWMxB_In作为上升沿延迟的输入。
    • 10: EPWMxA_In作为上升沿延迟的输入,EPWMxB_In作为下降沿延迟的输入。
    • 11: EPWMxB_In同时作为上升沿和下降沿延迟单元的输入。
  3. POLSEL(极性选择):在信号送出死区模块前,可选择性地对其中一个或两个输出进行取反。

    • 00: 主动高模式(AH)。都不取反。
    • 01: 主动低互补模式(ALC)。对EPWMxA_Out取反。
    • 10: 主动高互补模式(AHC)。对EPWMxB_Out取反。
    • 11: 主动低模式(AL)。两者都取反。

这个配置需要配合你的功率级电路(是使用高电平导通还是低电平导通的开关管,如上管是P-MOS还是N-MOS等)来使用。

4.3 一个完��的互补带死区PWM配置案例

假设我们驱动一个典型的半桥,使用两个N-MOSFET。N-MOS是高电平导通。我们需要EPWMxA驱动上管,EPWMxB驱动下管。为了避免直通,必须确保任何时候两个信号不同时为高。我们采用“插入死区时间,使两��在切换时都为低”的策略。

目标波形:EPWMxA和EPWMxB互补,但EPWMxA的上升沿比EPWMxB的下降沿晚一点(死区),EPWMxA的下降沿比EPWMxB的上升沿早一点(死区)。

配置步骤

  1. AQ模块配置:我们让AQ生成一对同相的原始信号。这样逻辑最简单。

    // TB配置为递增计数模式,PRD=1000 EPwm1Regs.TBPRD = 1000; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // AQ配置:两个输出都对相同事件做相同反应,生成同相方波 // 假设我们希望高电平时间为400个TBCLK EPwm1Regs.CMPA.half.CMPA = 400; // 在ZRO时,两个输出都置高 EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // 在CAU时,两个输出都拉低 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; // 此时,EPWMxA_In和EPWMxB_In是完全相同的50%占空比方波(高电平时间0-400)。
  2. DB模块配置:利用死区模块将同相信号变成互补带死区的信号。

    • 思路:我们希望EPWMxA_Out(上管驱动)的上升沿被延迟,而EPWMxB_Out(下管驱动)的下降沿被延迟。这样就能错开它们的开通时刻。
    • IN_MODE选择:我们需要EPWMxA_In的信号去经历上升沿延迟(生成EPWMxA_Out),也需要EPWMxA_In的信号去经历下降沿延迟(但输出给EPWMxB_Out)。查看IN_MODE选项,00模式(EPWMxA_In作为两者输入)符合要求。
    • OUT_MODE选择:我们需要同时启用上升沿延迟(给A)和下降沿延迟(给B)。所以选择11(全功能使能)。
    • POLSEL选择:最终我们需要EPWMxA和EPWMxB互补。目前AQ输出是同相的,DB的IN_MODE=00意味着两个延迟单元的输入是同相信号。如果直接输出,EPWMxA_Out和EPWMxB_Out将是同相的(只是边沿有错开)。因此,我们需要对其中一个输出取反。根据电路(上管高电平导通,下管高电平导通),我们需要两者互补且不同时为高。一种常见配置是选择主动高互补模式(AHC),即POLSEL=2,对EPWMxB_Out取反。这样,EPWMxA_Out是原始信号延迟后的结果,EPWMxB_Out是原始信号延迟后再取反的结果,自然形成互补。
    • 设置延迟值:假设TBCLK=100MHz(10ns周期),需要2us的死区时间。则需要的延迟节拍数 = 2us / 10ns = 200。
      EPwm1Regs.DBRED = 200; // 上升沿延迟200个TBCLK (2us) EPwm1Regs.DBFED = 200; // 下降沿延迟200个TBCLK (2us) EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 0b11 EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HI_COMP; // 0b10, AHC模式,对B取反 EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL_DBA_IN; // 0b00, 都使用EPWMxA_In作为输入

波形生成过程

  1. AQ输出同相方波(假设高电平在0-400)。
  2. 对于EPWMxA_Out(上管):取AQ输出的上升沿(在0时刻),延迟200个时钟后(在200时刻)才变为高电平。取AQ输出的下降沿(在400时刻),不延迟(因为DBRED只延迟上升沿)?等等,这里有个关键点!在OUT_MODE=11IN_MODE=00时,EPWMxA_Out得到的是EPWMxA_In经过上升沿延迟后的信号。EPWMxA_In的下降沿会立即反映在EPWMxA_Out上,因为下降沿没有被延迟。所以EPWMxA_Out的高电平区间是[200, 400)。
  3. 对于EPWMxB_Out(下管):取AQ输出的信号(EPWMxA_In)经过下降沿延迟,然后取反。AQ输出在0时刻的上升沿,其下降沿延迟不生效,所以EPWMxB_Out在0时刻因取反而为低。AQ输出在400时刻的下降沿,被延迟200个时钟,在600时刻才发生。由于经过了取反,这个下降沿延迟会导致EPWMxB_Out在600时刻从低变高(因为原信号下降沿延迟后取反,相当于上升沿)。同时,AQ输出在下一个周期0时刻的上升沿,其对应的下降沿延迟?不,对于EPWMxB_Out,我们只关心输入信号的下降沿(因为只使能了下降沿延迟)。所以EPWMxB_Out的高电平区间是[600, 1000)(本周期)和[0, 200)(下一周期开始阶段,因为上一周期末尾的下降沿延迟到了600,高电平持续到周期结束1000,然后新周期开始,AQ在0时刻的上升沿其下降沿未发生,输出因取反而为低,直到200时刻?)。这个分析有点绕,但最终结果就是EPWMxA_Out和EPWMxB_Out的高电平区间永远不会重叠,中间有死区间隔。

核心避坑指南:死区配置后,一定要用示波器同时测量EPWMxA和EPWMxB的输出,验证死区时间是否符合预期,以及是否存在任何瞬间的重叠(直通风险)。不要仅仅依赖逻辑分析仪或软件仿真,因为硬件延迟可能带来意外。DBREDDBFED的值是基于TBCLK的,务必确认你的TBCLK频率计算正确。对于高频率PWM,死区时间占空比会显著上升,需要权衡开关损耗和安全性。

5. 高级主题:影子寄存器、软件强制与故障联防

5.1 影子寄存器的同步加载机制

如前所述,影子寄存器是保证PWM参数(如CMPA,TBPRD)无毛刺更新的关键。CMPCTL[LOADAMODE]TBCTL[PRDLD]等位控制加载时机。

  • LOADAMODE=0:在CTR=0时(即每个PWM周期开始时)加载。
  • LOADAMODE=1:在CTR=PRD时(即每个PWM周期结束时)加载。
  • LOADAMODE=2:在CTR=0CTR=PRD时加载(增减计数模式常用)。
  • LOADAMODE=3:立即加载(禁用影子缓冲,慎用)。

在动态调整PWM(如闭环控制中更新占空比)时,务必在安全的时刻(通常是计数器为0或周期值)更新影子寄存器,并确保硬件加载事件会发生。一个常见的错误是连续快速写入CMPA,导致影子寄存器被覆盖,而加载事件还没发生。

5.2 软件强制输出:AQSFRC与AQCSFRC

AQSFRC(一次性强制)和AQCSFRC(连续强制)寄存器允许软件直接干预输出状态,优先级高于正常的AQ事件。这在特定调试、同步或故障恢复场景下非常有用。

  • 一次性强制(AQSFRC):向OTSFAOTSFB写1,会立即产生一个强制事件,并根据ACTSFAACTSFB的配置改变输出,然后该位自动清零。例如,你可以强制某个引脚在特定时刻拉高一个脉冲。
  • 连续强制(AQCSFRC):设置CSFACSFB为1(强制低)或2(强制高),输出将被锁定在该状态,直到你将其改为0或3(禁用强制)。这在故障发生后需要将输出强制置于安全状态(如全桥驱动中强制所有管为低)时非常关键。

注意:软件强制功能的优先级最高,使用时需格外小心,避免意外覆盖正常的PWM输出。在启用强制功能后,记得在适当的时候清除它。

5.3 故障联防(Trip-Zone)配置要点

TZ模块是硬件安全屏障。其配置流程通常如下:

  1. 选择故障源(TZSEL):配置哪些外部引脚(TZ1~TZ6)或内部数字比较事件(DCAEVT1/2,DCBEVT1/2)可以触发故障。可以分别配置为一次性(OSHT)或逐周期(CBC)故障。
  2. 配置故障动作(TZCTL):当故障发生时,你希望ePWM输出立即变成什么状态?常见的选择是强制为高阻态(Hi-Z)或强制拉低。这取决于你的功率驱动电路的外部下拉/上拉电阻和安全逻辑。例如,对于大多数MOSFET驱动,故障时强制输出低电平是安全的,可以关闭开关管。
  3. 使能中断(TZEINT):如果你需要在故障发生后由CPU进行一些清理或记录工作,可以使能CBC或OST中断。
  4. 处理故障标志(TZFLG, TZCLR):故障发生后,硬件会置位TZFLG中的相应标志位。对于一次性(OSHT)故障,必须由软件写TZCLR寄存器来清除标志,才能恢复PWM输出。对于逐周期(CBC)故障,当故障条件消��且TBCTR计数到0时,标志位会自动清除,PWM自动恢复。

严重警告:故障联防的响应是硬件级别的,速度极快。务必在系统设计阶段就明确每个故障源对应的安全输出状态,并在PCB布局上确保故障信号路径的可靠性。错误配置TZCTL可能导致故障时输出危险状态,损坏设备。

6. 调试技巧与常见问题排查

6.1 无输出或输出不正确

  • 检查时钟:确认ePWM模块的时钟是否使能(PCLKCR0/PCLKCR1寄存器)。确认TBCTL中的CLKDIVHSPCLKDIV分频设置是否正确,TBCLK是否有预期频率。
  • 检查输出引脚复用:确认GPIO MUX寄存器是否已正确配置为ePWM功能,而非普通的GPIO。
  • 检查AQ配置:这是最常见的问题源。逐条检查AQCTLA/B的配置,确认你期望的事件(ZRO, PRD, CAU, CAD等)是否配置了正确的动作(Set, Clear, Toggle)。使用仿真器,在运行时观察TBCTR计数和CMPA的值,看事件是否如期发生。
  • 检查影子寄存器:如果你动态更新了CMPATBPRD但波形没变,检查CMPCTL[SHDWAMODE]和加载模式LOADAMODE。可以在影子加载事件(如CTR=0)后设置断点,观察活动寄存器的值是否已更新。

6.2 死区时间不生效或异常

  • 确认DB模块已使能DBCTL[OUT_MODE]不能是00(直通模式)。
  • 检查IN_MODEPOLSEL的逻辑:这是最复杂的部分。建议在纸上画出信号流:AQ输出 -> DB输入选择 -> 上升/下降沿延迟 -> 极性选择 -> 最终输出。用逻辑分析仪捕获EPWMxA_InEPWMxB_In(如果引脚可用)以及最终的EPWMxA_OutEPWMxB_Out,对照分析。
  • 测量死区时间:使用示波器的高级触发和测量功能,直接测量两个互补信号上升沿/下降沿之间的时间差。与计算值(DBRED/DBFED * TBCLK周期)进行对比。

6.3 故障联防不动作

  • 检查故障源信号:首先用示波器确认故障输入引脚(TZn)的电平是否确实达到了触发条件(通常是低电平有效)。
  • 检查TZSEL配置:确认你希望响应的故障源已被使能(OSHT或CBC)。
  • 检查TZCTL配置:确认故障动作不是0b11(无操作)。
  • 检查标志位:发生故障后,读取TZFLG寄存器,看对应的CBC或OST标志是否置位。如果没有,说明故障未被识别。
  • 清除故障:对于OST故障,必须在故障条件解除后,手动写TZCLR寄存器清除标志,PWM输出才会恢复。如果不清除,输出将一直保持故障状态。

6.4 代码配置的推荐顺序

  1. 禁用时钟预分频器(TBCLKSYNC),配置所有ePWM模块的TBCTL(时钟分频、计数模式)。
  2. 使能时钟预分频器同步(TBCLKSYNC),让所有ePWM模块的时基同步启动。
  3. 配置周期寄存器TBPRD和比较寄存器CMPA/CMPB
  4. 配置动作限定器AQCTLA/B
  5. 配置死区控制DBCTLDBREDDBFED
  6. 配置故障联防TZSELTZCTL等。
  7. 最后,通过设置TBCTL.bit.SWFSYNC位或使能计数器,启动PWM生成。

遵循这个顺序可以避免在配置过程中产生意外的毛刺输出。理解CMPAAQCTL和死区控制寄存器,是掌握TI ePWM模块精髓的关键。它们将硬件的精确性与软件的灵活性完美结合。实际项目中,最耗时的往往不是编写初始化代码,而是调试和验证这些寄存器相互作用产生的最终波形。务必结合示波器,耐心分析,理解每个配置位对实际引脚电平的直接影响,这样才能构建出稳定可靠的功率控制系统。