深入解析TI C2000 ePWM动作限定器:从事件驱动到复杂波形生成

📅 2026/7/22 19:22:29 👁️ 阅读次数 📝 编程学习
深入解析TI C2000 ePWM动作限定器:从事件驱动到复杂波形生成

1. 项目概述:从事件到波形的精密转换器

在嵌入式电机控制和数字电源设计的核心,PWM波形的生成质量直接决定了系统的效率、响应速度和稳定性。我们常常需要的不只是一个简单的、固定占空比的方波,而是能够根据算法实时调整、具备特定相位关系、甚至带有死区保护的复杂波形对。传统的基础PWM模块往往力不从心,这时,像TI C2000系列微控制器中的增强型脉宽调制器(ePWM)就成为了工程师手中的利器。而ePWM模块中最具艺术性和灵活性的部分,莫过于动作限定器(Action-Qulifier, AQ)子模块。你可以把它想象成一个高度智能的“交通指挥中心”:时间基准计数器(TBCTR)的每一次“滴答”(计数值变化)和与预设值(如CMPA, CMPB, TBPRD)的每一次“相遇”(匹配事件),都是一辆辆驶入的“事件车辆”。动作限定器的任务,就是根据我们预先设定好的“交通规则”(AQCTLA/B寄存器配置),精准地指挥输出引脚EPWMxA和EPWMxB这“两条车道”上的信号电平,何时该亮起红灯(拉低),何时该亮起绿灯(置高),或者直接来个“信号翻转”(Toggle)。正是通过这种基于事件的、可编程的精细控制,我们才能从单调的计数器循环中,编织出驱动无刷电机旋转、让开关电源稳压、使逆变器输出完美正弦波的复杂PWM交响乐。

这篇文章,我将结合多年的电机驱动开发经验,为你深入拆解ePWM动作限定器的工作原理、配置心法以及那些手册上不会写的实战“坑点”。无论你是正在学习C2000的新手,还是希望优化现有PWM生成逻辑的老手,理解AQ模块都是你驾驭ePWM、实现精准控制的关键一步。我们将从它的核心设计思路开始,逐步深入到寄存器配置、波形构建逻辑,最后通过几个经典配置案例和代码,让你不仅能看懂,更能亲手“复现”出各种复杂的PWM波形。

2. 动作限定器的核心设计思路与架构解析

2.1 事件驱动的核心哲学

动作限定器模块的设计完全遵循事件驱动的哲学。它本身不主动产生信号,而是一个被动的“裁决者”和“执行者”。它的所有行为,都源于外部输入的事件。这些事件主要来自三个上游子模块:

  1. 时间基准(TB)子模块:提供CTR = PRD(计数器等于周期值)和CTR = ZERO(计数器等于零)这两个最基础、周期性的定时事件。
  2. 计数器比较(CC)子模块:提供CTR = CMPACTR = CMPB(以及CMPC/CMPD)事件。这是PWM占空比调节的核心,通过改变CMPx的值,我们就能移动这些事件在计数周期内发生的时间点。
  3. 软件强制(Software Force):这是一个异步事件,由软件直接写AQSFRC寄存器触发,优先级最高,用于在任意时刻立即干预输出状态,常用于故障注入测试或特殊控制序列。

AQ模块的输入就是这些离散的事件脉冲,输出则是施加在EPWMxA和EPWMxB引脚上的具体动作:置高(Set)、拉低(Clear)、翻转(Toggle)或保持原状(Do Nothing)。其内部逻辑可以看作一个可编程的查找表或交叉开关:针对每一个输入事件(并且进一步区分为计数器递增时发生还是递减时发生),我们都可以独立地为A、B两个输出通道分别指定一个动作。

2.2 模块框图与数据流

从系统框图看,AQ模块位于整个ePWM信号链的“心脏”位置。时间基准TB和计数器比较CC模块产生的原始事件,首先汇聚到AQ模块。AQ模块根据配置进行“裁定”和“转换”,生成最原始的PWM边沿动作。这些动作输出可以直接送到GPIO复用器驱动引脚,也可以先送入死区(DB)子模块插入互补延迟,再经PWM斩波器(PC)进行高频载波调制,最后输出。这种模块化设计赋予了极大的灵活性:你可以选择让AQ的输出直接驱动电机桥臂,也可以在其后级联DB模块来生成带死区的互补PWM对,以保护功率器件防止直通。

一个关键的理解:AQ模块处理的是“动作”,而非最终的“电平波形”。它只是在特定时间点发出一个“现在把引脚拉高”或“现在拉低”的指令。连续的指令序列,在引脚上才呈现为我们看到的PWM波形。因此,配置AQ的本质,就是在规划整个PWM周期内,所有关键时间点上应该执行哪些指令。

2.3 影子寄存器机制与实时更新

与CMPA/CMPB寄存器类似,AQ模块的核心控制寄存器AQCTLAAQCTLB也支持影子寄存器操作(在ePWM类型2及更高版本中)。这是实现PWM波形无毛刺、平滑切换的关键。

  • 立即加载模式(Immediate Load):当AQCTLR[SHDWAQxMODE] = 0时,对AQCTLA/B的写操作直接进入活动寄存器,立即生效。这可能会打断当前正在输出的PWM周期,导致波形出现毛刺或短时脉冲,通常仅在初始化或特殊调试时使用。
  • 影子加载模式(Shadow Load):当AQCTLR[SHDWAQxMODE] = 1时,对AQCTLA/B的写操作是写入其影子寄存器。影子寄存器的内容会在一个特定的加载事件发生时,一次性同步到活动寄存器。加载事件由AQCTLR[LDAQxMODE]AQCTLR[LDAQxSYNC]位域控制,常见选择有:
    • CTR = PRD:在计数器达到周期值时加载。适用于对称PWM(Up-Down模式)的周期中心点更新。
    • CTR = ZERO:在计数器归零时加载。这是最常用、最安全的更新点,能确保新配置在一个完整PWM周期开始时生效。
    • 外部同步事件(SYNC):由其他ePWM模块或外部信号触发同步时加载,用于实现多个ePWM模块间的相位协同更新。

重要避坑提示:在配置影子加载时,务必注意事件竞争问题。技术手册中特别警告:如果CMPACMPB的值被设置为0,并且AQ控制寄存器的影子到活动加载也配置在TBCTR=0这个边界,那么“比较匹配事件”和“寄存器加载事件”会在同一时刻发生冲突。硬件无法保证这两个事件的执行顺序,可能导致不可预期的波形。因此,最佳实践是避免将CMPx值设置为0,同时又在TBCTR=0时加载AQCTL寄存器。通常,在Up-Down模式下,如果选择在CTR=ZERO加载,应将CMPx值设置为≥1;如果选择在CTR=PRD加载,则应将CMPx值设置为≤TBPRD-1。这能确保每个PWM周期内至少有一个TBCLK周期宽度的脉冲,系统更容易稳定处理。

3. 寄存器详解与配置心法

3.1 核心控制寄存器:AQCTLA 与 AQCTLB

AQCTLAAQCTLB是直接控制EPWMxA和EPWMxB输出行为的寄存器。它们的位域结构是对称的,每个寄存器控制一个输出通道。每个寄存器的16位被划分为若干字段,分别对应不同事件在计数器不同方向时的动作。

AQCTLA为例(AQCTLB结构完全相同):

  • AQCTLA.bit.ZRO(2位): 定义当TBCTR = 0x0000事件发生时,对EPWMxA执行的动作。编码:00= 无操作,01= 置低,10= 置高,11= 翻转。
  • AQCTLA.bit.PRD(2位): 定义当TBCTR = TBPRD事件发生时的动作。
  • AQCTLA.bit.CAU(2位): 定义当TBCTR = CMPA事件发生且计数器正在递增(Up)时的动作。
  • AQCTLA.bit.CAD(2位): 定义当TBCTR = CMPA事件发生且计数器正在递减(Down)时的动作。
  • AQCTLA.bit.CBU(2位): 定义当TBCTR = CMPB事件发生且计数器正在递增时的动作。
  • AQCTLA.bit.CBD(2位): 定义当TBCTR = CMPB事件发生且计数器正在递减时的动作。

配置心法:理解“事件-方向-动作”的三元组是配置的关键。例如,要生成一个在Up-Down模式下中心对称的PWM,通常需要配置CAU = AQ_SET(上升沿匹配时置高)和CAD = AQ_CLEAR(下降沿匹配时置低)。而对于EPWMxB生成其互补信号,则可能配置CBU = AQ_CLEARCBD = AQ_SET

3.2 软件强制寄存器:AQSFRC 与 AQCSFRC

这两个寄存器提供了“绕过”事件系统、直接控制输出的能力。

  • AQSFRC:软件强制寄存器。写入此寄存器可以立即(或在下一次TBCLK边沿)产生一个一次性的强制事件,并根据AQCSFRC的配置对输出执行动作。例如,AQSFRC.bit.ACTSFA = 2(强制置高)会立即将EPWMxA输出拉高,无论当前处于计数周期的哪个阶段。
  • AQCSFRC:连续软件强制控制寄存器。它允许配置一个持续的强制状态,直到被软件清除。这在某些容错控制或测试模式下非常有用。

使用注意:软件强制事件的优先级是最高的(见下文事件优先级),它会覆盖任何由计数器事件触发的动作。使用后需及时清除强制状态,否则会“锁死”输出。

3.3 事件优先级机制:当多个事件同时发生时

在复杂的PWM模式中,特别是CMPA和CMPB值非常接近,或者它们与PRD、ZERO值重合时,多个事件可能在同一个TBCLK周期内发生。硬件必须有一套规则来决定哪个事件“胜出”。AQ模块的事件优先级规则是:软件强制事件拥有绝对最高优先级。对于其他由计数器产生的事件,其优先级取决于计数模式计数方向

以最常用的上下计数模式(Up-Down-Count)为例,其优先级顺序(1为最高)如下表所示:

优先级TBCTR递增时 (0 -> PRD)TBCTR递减时 (PRD -> 0)
1 (最高)软件强制事件软件强制事件
2CBU (CMPB Up-match)CBD (CMPB Down-match)
3CAU (CMPA Up-match)CAD (CMPA Down-match)
4CTR = ZEROCTR = PRD
5CBD (CMPB Down-match)CBU (CMPB Up-match)
6 (最低)CAD (CMPA Down-match)CAU (CMPA Up-match)

这个优先级规则对波形生成有重大影响。例如,在Up-Down模式下,如果你配置了CAU = SETZRO = CLEAR,并且CMPA = 0。当计数器从0开始递增时,CTR=0事件(ZRO)和CTR=CMPA事件(CAU)会在第一个计数周期就同时发生。根据上表,在递增阶段,CAU(优先级3)的优先级高于ZRO(优先级4),因此会先执行SET动作,然后ZROCLEAR动作可能被忽略或产生冲突,导致波形与预期不符。这就是为什么在配置时要避免比较值与周期边界值(0或PRD)过于接近或重合的原因之一,必要时需要利用优先级规则进行设计。

4. 实战:构建六种经典PWM波形

理论说得再多,不如一行代码。下面我将结合TI技术手册中的经典示例,详细拆解六种最常见的PWM波形是如何通过配置AQ模块生成的。我会解释每一步配置的意图,并附上完整的C代码示例(基于C2000寄存器结构)。假设系统时钟SYSCLKOUT为100MHz,我们期望的PWM频率为20kHz。

4.1 案例一:独立非对称PWM(Active High)

波形特征:单边沿调制(上升沿固定,下降沿可调),EPWMxA和EPWMxB独立控制,高电平有效。

  • 应用场景:两个独立的Buck变换器开关信号。
  • 计数模式:Up-count (递增模式)。
  • 周期计算PWM_Period = (TBPRD + 1) * T_{TBCLK}。设TBCLK = SYSCLKOUT = 10ns,目标频率20kHz,周期50us。则TBPRD = (50us / 10ns) - 1 = 4999
  • 动作逻辑
    • CTR=ZERO时:将EPWMxA和EPWMxB置高AQ_SET),开始高电平。
    • CTR=CMPA时:将EPWMxA拉低AQ_CLEAR)。
    • CTR=CMPB时:将EPWMxB拉低AQ_CLEAR)。
    • 占空比 =CMPx / (TBPRD + 1)。例如,CMPA=3500,则EPWMxA占空比约为70%。
// 初始化配置 EPwm1Regs.TBPRD = 4999; // 周期寄存器,对应20kHz EPwm1Regs.CMPA.half.CMPA = 3500; // A通道比较值,占空比~70% EPwm1Regs.CMPB = 2000; // B通道比较值,占空比~40% EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 设置为递增模式 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载 EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // 周期寄存器使用影子模式 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // 禁止同步输出 EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 高速时钟预分频=1 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 时钟预分频=1,TBCLK=SYSCLKOUT // 配置CMPA/CMPB在CTR=ZERO时从影子寄存器加载,确保更新同步无毛刺 EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // 核心:配置动作限定器 EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // 计数为零时,EPWMxA置高 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 递增且等于CMPA时,EPWMxA拉低 EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // 计数为零时,EPWMxB置高 EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 递增且等于CMPB时,EPWMxB拉低 // 运行时动态更新占空比 EPwm1Regs.CMPA.half.CMPA = new_duty_a * (EPwm1Regs.TBPRD + 1); EPwm1Regs.CMPB = new_duty_b * (EPwm1Regs.TBPRD + 1);

4.2 案例二:独立非对称PWM(Active Low)

波形特征:单边沿调制(下降沿固定,上升沿可调),EPWMxA和EPWMxB独立控制,低电平有效。

  • 应用场景:某些需要低电平使能的功率开关或LED驱动。
  • 计数模式:Up-count。
  • 动作逻辑(与案例一相反):
    • CTR=PRD时:将EPWMxA和EPWMxB拉低AQ_CLEAR),开始低电平。
    • CTR=CMPA时:将EPWMxA置高AQ_SET)。
    • CTR=CMPB时:将EPWMxB置高AQ_SET)。
  • 关键区别:这里使用了PRD事件而非ZERO事件来初始化输出状态。在递增模式下,计数器达到PRD后,下一个时钟会归零。因此,PRD事件发生在周期末尾,ZERO事件发生在周期开始。这种配置下,占空比 =1 - CMPx / (TBPRD + 1)
// 初始化配置(TB、CMP等部分与案例一类似,故省略) EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // ... 其他TB、CMP配置 // 核心:配置动作限定器(Active Low) EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR; // 计数达到周期时,EPWMxA拉低 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 递增且等于CMPA时,EPWMxA置高 EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR; // 计数达到周期时,EPWMxB拉低 EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // 递增且等于CMPB时,EPWMxB置高

4.3 案例三:脉冲定位与非对称波形

波形特征:在单个PWM周期内产生一个独立的脉冲,脉冲的起始和结束位置由CMPA和CMPB独立控制。EPWMxB输出一个简单的50%占空比方波。

  • 应用场景:需要精确定位脉冲的应用,如雷达调制、特定时序控制。
  • 计数模式:Up-count。
  • 动作逻辑
    • EPWMxA:CAU = SET(CMPA匹配时置高),CBU = CLEAR(CMPB匹配时拉低)。脉冲宽度 =(CMPB - CMPA) * T_{TBCLK}
    • EPWMxB:ZRO = TOGGLE(每次计数归零时翻转),生成频率为PWM频率一半的方波。
// 初始化配置 EPwm1Regs.TBPRD = 4999; // 20kHz EPwm1Regs.CMPA.half.CMPA = 1500; // 脉冲起始点 EPwm1Regs.CMPB = 3500; // 脉冲结���点 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // ... 其他配置 // 核心:配置动作限定器 EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // CMPA匹配(上升沿)时置高 EPwm1Regs.AQCTLA.bit.CBU = AQ_CLEAR; // CMPB匹配(下降沿)时拉低 // 注意:没有配置ZRO或PRD事件,意味着周期开始和结束时AQ对EPWMxA无操作,电平由CMPA/B事件决定。 EPwm1Regs.AQCTLB.bit.ZRO = AQ_TOGGLE; // 仅在ZERO事件翻转,生成50%占空比方波

4.4 案例四:独立对称PWM(Active Low)

波形特征:双边沿调制(中心对称),EPWMxA和EPWMxB独立控制,低电平有效。波形关于周期中心对称。

  • 应用场景:用于电机驱动的两相独立控制,或需要对称波形的滤波后产生正弦波。
  • 计数模式:Up-Down-count (上下计数模式)。周期计算变为PWM_Period = 2 * TBPRD * T_{TBCLK}。为保持20kHz,需重新计算:TBPRD = (50us / (2 * 10ns)) = 2500
  • 动作逻辑
    • EPWMxA:CAU = SET(递增匹配CMPA时置高),CAD = CLEAR(递减匹配CMPA时拉低)。
    • EPWMxB:CBU = SET,CBD = CLEAR
  • 占空比计算:在对称模式下,高电平时间 =2 * (TBPRD - CMPA) * T_{TBCLK},占空比 =(TBPRD - CMPA) / TBPRD。当CMPA=0时,占空比100%(常高);当CMPA=TBPRD时,占空比0%(常低)。
// 初始化配置 EPwm1Regs.TBPRD = 2500; // Up-Down模式,20kHz对应TBPRD=2500 EPwm1Regs.CMPA.half.CMPA = 1000; // 计算占空比:(2500-1000)/2500 = 60% EPwm1Regs.CMPB = 500; // 占空比:(2500-500)/2500 = 80% EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 关键:设置为上下计数模式 // ... 其他TB、CMP配置(注意CMP加载点通常选CTR=ZERO或PRD) // 核心:配置动作限定器(对称,Active Low) EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 上数匹配CMPA时置高 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // 下数匹配CMPA时拉低 EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // 上数匹配CMPB时置高 EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR; // 下数匹配CMPB时拉低

4.5 案例五:互补对称PWM带死区(软件实现)

波形特征:EPWMxA和EPWMxB为一对互补的对称PWM,且通过CMPA和CMPB的差值自然形成一段两者均为低的“死区”时间。

  • 应用场景:H桥或三相逆变器的上下桥臂驱动,防止直通。
  • 计数模式:Up-Down-count。
  • 动作逻辑
    • EPWMxA (假设控制上桥臂):CAU = SET,CAD = CLEAR。高电平中心对称。
    • EPWMxB (控制下桥臂):CBU = CLEAR,CBD = SET。与EPWMxA反相,但边沿由CMPB控制。
  • 死区时间Deadtime = (CMPB - CMPA) * T_{TBCLK}。通过设置CMPB > CMPA,可以确保EPWMxA的下拉沿(发生在CAD)早于EPWMxB的置高沿(发生在CBD),反之,EPWMxA的置高沿(CAU)晚于EPWMxB的下拉沿(CBU),从而在切换瞬间产生一段两者都为低电平的死区。
// 初始化配置 EPwm1Regs.TBPRD = 2500; // 20kHz对称PWM EPwm1Regs.CMPA.half.CMPA = 1000; // 主占空比控制 EPwm1Regs.CMPB = 1200; // CMPB比CMPA大200,对应死区时间 = 200 * 10ns = 2us EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // ... 其他配置 // 核心:配置动作限定器(互补对称带死区) EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // A上桥臂:上数匹配CMPA时开启 EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // A上桥臂:下数匹配CMPA时关闭 EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // B下桥臂:上数匹配CMPB时关闭 (在A开启后) EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; // B下桥臂:下数匹配CMPB时开启 (在A关闭前) // 由于CMPB > CMPA,所以CBD事件在CAD之后,CBU事件在CAU之前,自然形成死区。

重要提示:这是一种通过AQ逻辑实现死区的“软件死区”方法。ePWM模块本身提供了更强大、更专业的死区(DB)子模块,可以自动插入可编程的上升沿延迟、下降沿延迟或两者,且支持多种输出极性模式。在实际工程中,尤其是对死区时间精度和稳定性要求高的电机驱动场合,强烈推荐使用硬件DB模块而非此处的软件方法。这里展示的软件方法有助于理解AQ的动作机制。

4.6 案例六:双边沿非对称定位

波形特征:在一个对称PWM周期内,波形的上升沿和下降沿可以独立地、非对称地放置,由CMPA和CMPB分别控制。EPWMxB输出一个固定的50%占空比信号。

  • 应用场景:需要复杂脉冲定位或特定谐波消除的场合。
  • 计数模式:Up-Down-count。
  • 动作逻辑
    • EPWMxA:CAU = SET(上升沿由CMPA上数匹配控制),CBD = CLEAR(下降沿由CMPB下数匹配控制)。注意这里上升沿和下降沿的控制事件来自不同的比较器(A和B)和不同的计数方向(Up和Down),实现了完全独立的定位。
    • EPWMxB:ZRO = CLEAR,PRD = SET,生成一个在周期开始时拉低、周期中点置高的对称方波。
// 初始化配置 EPwm1Regs.TBPRD = 2500; EPwm1Regs.CMPA.half.CMPA = 800; // 控制上升沿位置 EPwm1Regs.CMPB = 1800; // 控制下降沿位置 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // ... 其他配置 // 核心:配置动作限定器(双边沿非对称) EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 上数到CMPA时置高 EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR; // 下数到CMPB时拉低 // EPWMxB输出固定50%方波 EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // 周期开始拉低 EPwm1Regs.AQCTLB.bit.PRD = AQ_SET; // 周期中点置高

5. 高级话题与避坑指南

5.1 影子寄存器的加载时机与波形毛刺

这是ePWM应用中最常见的“坑”。错误地更新CMPA/CMPB或AQCTL寄存器会导致PWM波形出现意外的毛刺或跳动。

根本原因:在计数器运行过程中,如果你直接写入活动比较寄存器(CMPA Active),而写入的时刻恰好发生在“旧值”已比较过但“新值”即将生效的临界点,硬件可能在一个周期内使用新旧值的混合逻辑,或者错过一次比较,导致输出异常。

解决方案

  1. 始终使用影子寄存器:确保CMPCTL.SHDWAMODE/BAQCTLR.SHDWAQxMODE使能。
  2. 精心选择加载点
    • 对于Up-Down模式:通常选择在CTR=ZEROCTR=PRD时加载。如果CMP值在周期中间变化,选择CTR=PRD加载可以确保波形变化发生在周期的中心(对称点),对电机驱动等应用更友好。
    • 对于Up/Down模式:选择CTR=ZERO加载是最安全的,确保新值在一个完整周期开始时生效。
  3. 遵守CMPx值边界规则(前文已述):避免在加载边界使用0或TBPRD值,留出至少1个TBCLK的余量。

5.2 事件优先级冲突的调试

当PWM波形不符合预期,特别是边沿位置出现奇怪的跳变或缺失时,首先要怀疑事件优先级冲突。

调试步骤

  1. 检查CMPA、CMPB、TBPRD的值:计算它们是否相等或过于接近。在Up-Down模式下,CMPA=TBPRDCAD事件与PRD事件可能竞争。
  2. 对照优先级表分析:根据当前的计数模式和方向,列出所有可能同时发生的事件,并按照硬件优先级排序。确认你期望执行的动作对应的事件,其优先级是否被更高优先级的事件“覆盖”了。
  3. 使用“Do Nothing”进行隔离:如果怀疑某个事件干扰,可以尝试在AQCTL中将其动作临时配置为AQ_NO_ACTION,观察波形变化,从而定位问题事件。
  4. 利用仿真器或示波器:结合CCS的寄存器实时查看和硬件示波器,观察在事件发生时,计数器的实际值、比较匹配标志位以及输出引脚的电平,这是最直接的调试方法。

5.3 实现0%-100%全占空比范围

在某些电源控制中,需要PWM占空比能从0%线性变化到100%。单纯的AQ配置在边界条件下会遇到问题(如CMPA>=TBPRD时事件不产生)。

实现技巧

  • 对于Up-Down模式对称PWM:如手册所述,若要实现0%-100%,需配置CAU=SET, CAD=CLEAR。则:
    • CMPA = TBPRD时,CAU事件发生在CTR=PRD时(与PRD事件竞争),CAD事件也发生在CTR=PRD时。根据优先级,最终动作可能是SETCLEAR,结果不确定。可靠的方法是限制CMPA在[1, TBPRD-1]范围内,这样0%和100%实际上是无限接近但无法完全达到的理论值,通常一个TBCLK的脉冲在系统中可视为0%或100%。
  • 对于Up模式非对称PWM(Active High):手册提供了一个巧妙配置:ZRO = SET,CAU = CLEAR,并在CTR=PRD时加载CMPA影子寄存器。此时,占空比 =CMPA / (TBPRD+1)。当CMPA=0时,CAU事件在周期开始时立即发生(与ZRO事件竞争),由于CAU优先级高于ZRO,会执行CLEAR,输出常低(0%)。当CMPA = TBPRD+1时,CAU事件永远不会发生(因为计数器最大到TBPRD),只有ZROSET动作生效,输出常高(100%)。这里的关键是CMPA的更新点必须在PRD,且CMPA的值域需要扩展到TBPRD+1

5.4 与死区(DB)模块的协同工作

在实际电机驱动中,AQ模块很少单独使用,其输出会送入死区模块进行进一步处理。你需要理解数据流:AQ Output -> DB Module -> GPIO Mux -> Pin

配置要点

  1. AQ输出配置为互补模式:如案例五所示,生成一对原始的、无死区的互补信号。
  2. 在DB模块中配置延迟:通过DBRED(上升沿延迟)和DBFED(下降沿延迟)寄存器设置死区时间。DB模块会自动对AQ输出的上升沿和/或下降沿插入延迟。
  3. 选择输出极性:DB模块提供多种输出模式,如ACTIVE_HIGH_COMPLIMENTARY(高有效互补)、ACTIVE_LOW_COMPLIMENTARY(低有效互补)等。这决定了最终引脚上信号的极性,需要与功率器件的驱动逻辑匹配。
  4. 时序计算:死区时间 =DBRED/DBFED * T_{TBCLK}。确保死区时间大于功率器件的开关延迟和恢复时间。

6. 常见问题与排查实录

问题1:配置了动作,但引脚没有输出任何波形。

  • 检查清单
    1. 时钟使能:确认ePWM模块的系统时钟SYSCLK已使能(通过PCLKCR0/1/2寄存器)。
    2. TBCLK时钟:检查TBCTL[CLKDIV]TBCTL[HSPCLKDIV]分频器配置,确保TBCLK不为零。
    3. 计数器模式:确认TBCTL[CTRMODE]不是FREEZESTOP模式。
    4. GPIO复用:确认对应的GPIO引脚已配置为ePWM功能(通过GPxMUX寄存器),而非普通I/O。
    5. 输出使能:某些芯片的ePWM输出可能需要额外的使能位(如AQCTL中的OSHT相关位或TZ模块未强制拉低),检查相关寄存器。

问题2:PWM波形有毛刺,占空比偶尔跳动。

  • 排查方向
    1. 影子寄存器更新冲突:这是最大嫌疑。确认你在更新CMPA/CMPBAQCTL时,写的是影子寄存器,并且加载事件(如CTR=ZERO)发生在你期望的、安全的时刻。在调试时,可以在中断服务程序中更新影子寄存器,并确保中断由加载事件触发(如CTR=ZERO中断)。
    2. 变量类型与寄存器访问:确保你赋给CMPA/CMPB的值没有溢出(例如,CMPA是16位寄存器,赋值不能超过65535)。对于C2000,注意CMPA寄存器有时被拆分为CMPA.half.CMPACMPA.half.CMPAHR(高分辨率)。
    3. 中断干扰:如果PWM更新是在高优先级中断中进行的,确保中断服务程序执行时间足够短,不会错过下一个PWM周期的加载事件。

问题3:生成的对称PWM波形不对称。

  • 可能原因
    1. 计数模式错误:确认TBCTL[CTRMODE]设置为TB_COUNT_UPDOWN
    2. 动作配置错误:对称PWM需要同时配置CAUCAD(或CBUCBD)。检查是否只配置了一个方向的动作。
    3. CMP值加载点不当:在Up-Down模式下,如果在CTR=ZERO加载CMP,但CMP值设置为0,会导致CAUZERO事件在第一个计数周期就冲突(如优先级部分所述)。尝试将CMP最小值设为1。

问题4:如何用示波器验证AQ事件?

  • 间接验证:除了直接看PWM输出,还可以利用ePWM的事件触发(ET)子模块。可以将CTR=CMPACTR=PRD等事件连接到ET模块,并配置ET模块在事件发生时产生一个短脉冲输出到另一个GPIO(或触发ADC)。用示波器同时观察这个“事件脉冲”和PWM波形,可以精确验证事件发生的时刻是否与理论计算一致。
  • 寄存器监控:在CCS的寄存器视图中,实时观察TBCTR的值,以及ETFLG寄存器中事件标志位的置位情况,结合代码单步调试,是逻辑排查的利器。

理解并熟练运用ePWM的动作限定器,是解锁高级电机控制和数字电源设计能力的关键。它从简单的“定时器比较输出”中抽象出来,提供了一个基于事件的、声明式的波形描述框架。刚开始接触时,可能会觉得寄存器配置繁琐,但一旦掌握了“事件-方向-动作”这个核心思维模型,并结合实际的波形图进行反复演练,你就会发现它的设计是如此优雅和强大。在实际项目中,我习惯在Excel或MATLAB中先画出期望的波形图,标出所有边沿对应的事件和动作,再翻译成寄存器配置代码,这种方法几乎可以避免所有的配置逻辑错误。最后,别忘了充分利用芯片的数据手册、技术参考指南以及TI提供的driverlib库函数,它们能帮你节省大量底层配置的时间。