TI eCAP模块深度解析:从捕获到APWM,掌握嵌入式实时控制核心

TI eCAP模块深度解析:从捕获到APWM,掌握嵌入式实时控制核心

1. eCAP模块核心原理与设计思路拆解

在嵌入式实时控制领域,无论是测量一个旋转编码器的脉冲间隔,还是驱动一个三相电机的桥臂,其底层都离不开对时间基准的精确掌控。TI的增强型捕获模块,即eCAP模块,正是为此而生的瑞士军刀。它绝不仅仅是一个简单的定时器外设,而是一个集高精度时间戳捕获与灵活PWM生成为一体的多功能单元。理解它的设计哲学,是将其威力发挥到极致的前提。

eCAP模块的核心是一个32位的时间戳计数器。你可以把它想象成一个永不停止的精密秒表。在捕获模式下,这个“秒表”的读数会在你预设的特定事件(比如输入引脚的电平跳变)发生时,被瞬间“冻结”并存入专门的捕获寄存器。通过读取连续两次“冻结”的数值,我们就能计算出事件之间的精确时间间隔。而在APWM模式下,这个计数器则化身为一个周期发生器,配合一个比较寄存器,通过不断比较计数值与设定值来产生占空比可调的PWM波形。

其设计的精妙之处在于“四深度”的捕获/比较寄存器组。模块内部有一个Mod4状态机,它像是一个旋转的指针,依次指向CAP1到CAP4这四个寄存器。在连续捕获模式下,每发生一次捕获事件,时间戳就存入当前指针指向的寄存器,然后指针自动步进到下一个。这意味着你可以连续捕获四个时间点而无需CPU立即干预,为处理高频信号或降低中断负载提供了可能。在APWM模式下,CAP1和CAP2寄存器被重新定义为周期寄存器(APRD)和比较匹配寄存器(ACMP),分别用于设定PWM的周期和占空比。

另一个关键设计是绝对时间戳差值时间戳两种模式的选择。这直接决定了你读取到的数据是“从计数器启动到现在经过了多久”,还是“从上一次事件发生到现在经过了多久”。绝对模式就像记录每次拍照的绝对时间(如10:00:00, 10:00:02),需要后续做减法才能得到间隔;而差值模式则在每次拍照后把秒表归零,读出的数据直接就是时间间隔。后者简化了CPU的计算,但需要注意计数器溢出的问题。

2. 捕获模式深度解析与配置要点

捕获模式是eCAP的“听诊器”,用于精确测量外部信号的时序。配置的关键在于理解几个核心控制位,它们共同决定了模块“听”什么以及如何“记录”。

2.1 边沿极性选择与信息获取

CAPxPOL位决定了模块对什么事件做出反应。仅配置为上升沿触发,你只能得到信号的周期信息。想象一下测量一个方波:你只在每个上升沿按下秒表,那么两次记录的时间差就是一个完整的周期。但如果你同时配置上升沿和下降沿触发(例如CAP1POL=上升,CAP2POL=下降,CAP3POL=上升,如此循环),你就能同时捕获到上升和下降的时刻。这样,相邻两个上升沿的时间差是周期,而一个上升沿和紧随其后的下降沿的时间差就是高电平时间(占空比)。原始资料中的图7-61完美诠释了这一点:t1(上升)、t2(下降)、t3(上升)… 周期 = t3 - t1, 高电平时间 = t2 - t1。

注意:在连续捕获且使能了所有四个捕获事件(CEVT1-4)的中断时,通常会在第四个事件(CEVT4)触发中断后,一次性读取四个捕获寄存器(CAP1-CAP4),这样可以最大化利用硬件缓冲,减少中断频率。代码示例也正是这样做的。

2.2 复位模式:绝对与差值的本质区别

CTRRSTx位是理解两种时间戳模式的关键。在绝对模式下,32位时间戳计数器自由运行,永不复位(除非手动或溢出)。捕获事件发生时,只是将计数器当前值复制到捕获寄存器。要计算间隔,必须在软件中做减法:Period = CAP2 - CAP1

而在差值模式下,逻辑完全不同。一旦发生捕获事件,模块在将计数器当前值存入捕获寄存器后,会立即将计数器复位为零。这意味着,下一个捕获事件发生时,计数器记录的就是从上一次事件到现在的精确时间间隔。因此,你读取到的CAPn寄存器的值,直接就是时间间隔,无需再做减法。如图7-62所示,T1, T2, T3, T4 就是直接可用的周期值。

实操心得:选择哪种模式取决于应用需求。如果需要知道事件发生的绝对时间点(例如为多个异步事件打时间戳),用绝对模式。如果只关心事件之间的相对间隔(如测量脉冲频率),且希望减轻CPU负担,差值模式是更优选择。但要注意,在差值模式下,如果两个事件间隔过长,超过了32位计数器的最大值(取决于时钟频率),计数器会溢出,CNTOVF标志会被置位,这可能引入误差,需要软件处理。

2.3 关键寄存器配置速查与释义

根据技术手册的示例,一个典型的捕获模式初始化流程需要对两个主要控制寄存器进行配置。下表总结了关键位域的含义:

寄存器位域常用值(宏)含义与影响
ECCTL1CAPxPOLEC_RISING/EC_FALLING设定第x次捕获事件的触发边沿。
CTRRSTxEC_ABS_MODE/EC_DELTA_MODE设定第x次捕获事件后,时间戳计数器是否复位。
CAPLDENEC_ENABLE必须使能,否则捕获事件不会将时间戳加载到CAPx寄存器。
PRESCALEEC_DIV1(等)输入信号预分频器。EC_DIV1表示每个事件都捕获,EC_DIV2则每2个事件捕获一次,用于信号分频。
ECCTL2CAP/APWMEC_CAP_MODE设置为捕获模式。
CONT/ONESHTEC_CONTINUOUS连续捕获模式。单次模式(EC_ONESHOT)在指定次数事件后停止。
SYNCI_ENEC_DISABLE在独立捕获时,通常禁用外部同步输入。
TSCTRSTOPEC_RUN启动时间戳计数器。

一个典型的、用于绝对时间戳、上升沿触发的配置代码段看起来是这样的(以C语言伪代码风格表示):

// 初始化ECAP模块为绝对时间戳、上升沿捕获模式 ECAPxRegs.ECCTL1.bit.CAP1POL = EC_RISING; ECAPxRegs.ECCTL1.bit.CAP2POL = EC_RISING; ECAPxRegs.ECCTL1.bit.CAP3POL = EC_RISING; ECAPxRegs.ECCTL1.bit.CAP4POL = EC_RISING; ECAPxRegs.ECCTL1.bit.CTRRST1 = EC_ABS_MODE; // 绝对模式 ECAPxRegs.ECCTL1.bit.CTRRST2 = EC_ABS_MODE; ECAPxRegs.ECCTL1.bit.CTRRST3 = EC_ABS_MODE; ECAPxRegs.ECCTL1.bit.CTRRST4 = EC_ABS_MODE; ECAPxRegs.ECCTL1.bit.CAPLDEN = EC_ENABLE; // 使能捕获加载 ECAPxRegs.ECCTL1.bit.PRESCALE = EC_DIV1; // 不分频 ECAPxRegs.ECCTL2.bit.CAP_APWM = EC_CAP_MODE; // 设置为捕获模式 ECAPxRegs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS; // 连续模式 ECAPxRegs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // 禁用同步 ECAPxRegs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // 启动计数器

3. APWM模式实战:从单通道到复杂多相系统

当eCAP模块被配置为APWM模式时,它就从一名“记录员”转变为一名“指挥家”。CAP1和CAP2寄存器被重新赋予新的角色:CAP1成为周期寄存器(APRD),定义了PWM波的频率;CAP2成为比较寄存器(ACMP),定义了PWM波的高电平时间(在主动高极性下)。32位的时间戳计数器(TSCTR)从0开始递增,并与这两个值比较,从而在APWMx输出引脚上产生相应的波形。

3.1 单通道PWM生成基础

单通道PWM的配置相对直接。核心是设置工作模式、极性和周期/占空比。技术手册中的例程清晰地展示了这一点:

  1. 配置模式与极性:将ECCTL2中的CAP_APWM位设为EC_APWM_MODE,并将APWMPOL设为EC_ACTV_HI(高电平有效)。
  2. 设置周期:向CAP1寄存器写入周期值。例如0x1000
  3. 设置占空比:向CAP2寄存器写入比较值。例如0x300。占空比 = (CAP2 / CAP1) * 100%。
  4. 启动计数器:确保TSCTRSTOP位为EC_RUN

运行时,你可以通过修改CAP2寄存器的值来动态调整占空比。这里有一个至关重要的细节CAP1CAP2寄存器都有“活动”和“影子”寄存器。在APWM模式下,为了确保PWM周期和占空比在精确的时刻同步更新,避免产生毛刺或错误的脉冲,初始化时必须直接写入活动寄存器(即示例中的直接赋值)。而在运行过程中需要更新时,则应写入对应的影子寄存器(通常是CAP1CAP2本身,但具体写入哪个由CTR=PRDCTR=CMP事件触发加载,需参考具体芯片手册)。手册中强调:“During initialization, you must write to the active registers... For subsequent compare updates... only the shadow registers must be used.” 这是保证PWM输出稳定的关键。

3.2 多通道同步:消除“拍频”的艺术

在需要多个PWM通道的系统中(例如驱动多个电机或一个多相电源),如果各个通道的时钟不同步,即使频率相同,微小的相位差也会导致低频的“拍频”干扰,产生噪音和额外损耗。eCAP的同步功能就是为了解决这个问题。

如图7-65所示,多通道同步的核心是指定一个eCAP模块作为主设备,其他作为从设备

  • 主设备:将其SYNCO_SEL位配置为EC_CTR_PRD。这意味着每当主设备的TSCTR计数到周期值(APRD)时,它就会产生一个同步输出脉冲(SYNCO)。
  • 从设备:将其SYNCI_EN位配置为EC_ENABLE,并将SYNCO_SEL位配置为EC_SYNCI。这表示从设备使能了同步输入,并且其时间戳计数器的启动/停止受主设备的同步脉冲控制。

这样,所有从设备的PWM周期都与主设备严格同步开始。它们的频率可以是主设备频率的整数倍(通过设置不同的APRD值实现),但由于起点被同步,它们之间就不会产生非整数倍的差拍。例如,主频为F1,从设备2、3、4的APRD分别设置为F1/2、F1/4、F1/5,就能生成频率为2F1, 4F1, 5*F1且严格同步的PWM波。

3.3 多通道移相:交错并联的核心技术

在多相交错并联DC/DC转换器这类应用中,不仅要求各通道PWM同步,还需要它们之间存在特定的相位差(例如三相120°交错),以减小输入输出电流纹波,优化滤波器的体积。eCAP的相位控制寄存器CTRPHS正是为此设计。

如图7-66所示的三相交错示例:

  • 主设备(eCAP1)CTRPHS = 0SYNCO_SEL = EC_CTR_PRD。它作为相位参考(0°)。
  • 从设备2(eCAP2)CTRPHS = 800(假设APRD=1200,则相位延迟 = (800/1200)*360° = 240°。但注意,通常滞后一个相位差d,计算为 (APRD - d) / APRD * 360°,需根据波形图具体分析)。SYNCI_EN使能,SYNCO_SEL选择EC_SYNCI。它等待主设备的同步脉冲来启动自己的计数器。
  • 从设备3(eCAP3)CTRPHS = 400(对应120°相位延迟)。配置类似。

当主设备计数器归零并发出同步脉冲时,所有从设备的计数器开始从各自的CTRPHS值(而非0)开始计数。这样,当计数器达到比较值(ACMP)时,各通道PWM的上升沿就自然错开了设定的相位。这里的关键理解是CTRPHS设定的是计数器的初始值,因此从设备计数器需要从CTRPHS计数到APRD才完成一个周期,这就天然地引入了相位延迟。

4. 从寄存器到代码:完整配置流程与避坑指南

理解了原理,最终要落地到代码。下面我将以一个具体的场景——配置eCAP1为带相位延迟的PWM主通道,eCAP2为同步的从通道——来展示完整的配置流程和需要注意的陷阱。

4.1 硬件与软件环境准备

假设我们使用TI的AM263P LaunchPad开发板,集成开发环境为Code Composer Studio (CCS)。首先,需要正确初始化系统时钟和引脚复用。eCAP模块的输入/输出引脚需要通过PINMUX配置为ECAP功能。通常,这会在TI提供的驱动库driverlib或直接操作寄存器来完成。确保你已正确导入芯片的支持包和头文件(如hw_ecap.hecap.h)。

4.2 主通道(eCAP1)配置详解

我们的目标是让eCAP1产生一个频率为10kHz(周期100us),初始占空比为50%,高电平有效的PWM波,并作为同步源。

第一步:计算寄存器值。假设系统提供给eCAP的时钟SYSCLK为200MHz。eCAP的TSCTR计数器每个SYSCLK周期递增一次。

  • 周期值APRD = (SYSCLK / PWM_Freq) - 1 = (200,000,000 / 10,000) - 1 = 19999
  • 初始比较值ACMP = APRD * DutyCycle = 19999 * 0.5 ≈ 9999(取整)。
  • 相位值CTRPHS = 0(主通道通常为0)。

第二步:编写初始化函数。

void ECAP1_PWM_Master_Init(void) { // 1. 确保模块处于复位状态以便配置(如果支持) // ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_FREEZE; // 2. 配置ECCTL1 (本例中APWM模式,部分ECCTL1位可能无关或保持默认) ECAP1Regs.ECCTL1.bit.CAPLDEN = EC_DISABLE; // APWM模式下,捕获加载禁用 ECAP1Regs.ECCTL1.bit.PRESCALE = EC_DIV1; // 预分频设为1 // 3. 配置ECCTL2 - 核心控制 ECAP1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; // APWM模式 ECAP1Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; // 高电平有效 ECAP1Regs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS; // 连续模式 ECAP1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // 主设备禁用同步输入 ECAP1Regs.ECCTL2.bit.SYNCO_SEL = EC_CTR_PRD; // 计数器等于周期时产生同步输出 ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_FREEZE; // 先停止计数器,等待配置完成 // 4. 写入周期、比较和相位值(初始化时写入活动寄存器) ECAP1Regs.CAP1 = 19999; // APRD 周期寄存器 ECAP1Regs.CAP2 = 9999; // ACMP 比较寄存器 (初始占空比50%) ECAP1Regs.CTRPHS = 0; // 相位寄存器 (主设备为0) // 5. 清除可能存在的旧中断标志(可选) ECAP1Regs.ECEINT.all = 0x0000; // 禁用所有中断 ECAP1Regs.ECCLR.all = 0xFFFF; // 清除所有中断标志 // 6. 启动计数器 ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; }

4.3 从通道(eCAP2)同步配置详解

现在配置eCAP2,使其产生一个频率为20kHz(主频的2倍),相位滞后主通道90°(即1/4周期)的PWM波。

第一步:计算寄存器值。

  • 周期值APRD = (SYSCLK / PWM_Freq) - 1 = (200,000,000 / 20,000) - 1 = 9999
  • 初始比较值ACMP = 4999(占空比50%)。
  • 相位值CTRPHS:为了实现90°滞后(即滞后1/4个从通道自身的周期),CTRPHS = APRD * (PhaseDelay / 360°) = 9999 * (90 / 360) = 2499.75 ≈ 2500。更精确的思考是:我们希望从通道的波形比主通道晚90°(主通道周期100us,90°对应25us)。从通道周期50us。在同步点(主通道周期开始),从通道计数器从CTRPHS开始计数。为了在25us后达到比较点,CTRPHS应设为APRD - (Delay / T_slave * APRD) = 9999 - (25us / 50us * 9999) ≈ 5000?这里需要仔细分析:我们希望从通道的上升沿比主通道晚25us。主通道周期开始(同步点)时,从通道计数器从CTRPHS开始向上计数。当计数器达到APRD时,它归零并开始新周期。上升沿发生在计数器等于ACMP时。因此,为了在同步点之后25us产生上升沿,我们需要CTRPHS + 25us内的计数值 = ACMP。25us内的计数值 =SYSCLK * 25us = 200MHz * 0.000025s = 5000。所以CTRPHS = ACMP - 5000 = 4999 - 5000 = -1?这显然不对,因为CTRPHS是32位���符号数。实际上,当CTRPHS值较大时,计数器会从CTRPHS计数到APRD(溢出),再从0计数到ACMP。因此,延迟时间 =(APRD - CTRPHS + 1 + ACMP) * T_clk。设定这个值等于25us来反推CTRPHS较为复杂。一个更简单的方法是:让从通道的计数器在同步点从0开始,但设置一个ACMP值使其在25us后触发。但这需要ACMP=5000,且CTRPHS=0。然而,这要求从通道的周期起点与主通道对齐,但我们需要的是相位差,而不是对齐。因此,正确的方法是使用CTRPHS来偏移计数器的起始点。设CTRPHS = X。从同步点开始,计数器从X计数到9999(计数值 = 9999 - X + 1),然后从0计数到ACMP(计数值 = ACMP + 1)。总计数 = (9999 - X + 1) + (ACMP + 1) = 10000 - X + ACMP + 1。令其等于25us对应的计数5000:10001 - X + ACMP = 5000。如果我们保持ACMP=4999(50%占空比),则10001 - X + 4999 = 5000=>15000 - X = 5000=>X = 10000。但CTRPHS不能大于APRD(9999)。这里揭示了APWM模式下相位控制的一个关键点:CTRPHS引入的延迟,最大只能接近一个从通道自身的周期。要实现90°滞后(25us),这已经是从通道周期(50us)的一半,是可行的。我们重新计算:延迟计数 = 5000。计数器从X开始到9999,再到ACMP。总步数 = (9999 - X + 1) + (ACMP + 1) = 10000 - X + ACMP + 1。设其为5000。代入ACMP=4999:10000 - X + 4999 + 1 = 5000->15000 - X = 5000->X = 10000。仍然大于APRD。这意味着,对于50%占空比,要产生25us延迟,需要的CTRPHS超出了范围。我们需要调整ACMP或接受一个近似的延迟。例如,设ACMP=2500,则方程变为:10000 - X + 2500 + 1 = 5000->12501 - X = 5000->X = 7501。这个值有效。因此,相位延迟CTRPHS、占空比ACMP和周期APRD是相互耦合的,需要联合设计。为简化,我们假设设计为:从通道频率20kHz,占空比25%,相位滞后主通道90°。则ACMP = 9999 * 0.25 ≈ 2500。延迟计数5000。解方程:10000 - X + 2500 + 1 = 5000->12501 - X = 5000->X = 7501。这个配置是可行的。

第二步:编写初始化函数。

void ECAP2_PWM_Slave_Init(void) { // 1. 停止计数器 ECAP2Regs.ECCTL2.bit.TSCTRSTOP = EC_FREEZE; // 2. 配置ECCTL1 ECAP2Regs.ECCTL1.bit.CAPLDEN = EC_DISABLE; ECAP2Regs.ECCTL1.bit.PRESCALE = EC_DIV1; // 3. 配置ECCTL2 - 注意同步设置 ECAP2Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; ECAP2Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; ECAP2Regs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS; ECAP2Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; // 使能同步输入 ECAP2Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCI; // 同步源选择为SYNCI(即主设备的SYNCO) ECAP2Regs.ECCTL2.bit.TSCTRSTOP = EC_FREEZE; // 保持停止,等待同步信号启动 // 4. 写入周期、比较和相位值 ECAP2Regs.CAP1 = 9999; // APRD, 对应20kHz ECAP2Regs.CAP2 = 2500; // ACMP, 初始占空比25% ECAP2Regs.CTRPHS = 7501; // CTRPHS, 计算得到的相位延迟值 // 5. 清除中断标志(可选) ECAP2Regs.ECEINT.all = 0x0000; ECAP2Regs.ECCLR.all = 0xFFFF; // 6. 注意:从设备的计数器不会立即启动,它会等待主设备(ECAP1)发出的第一个SYNCO同步脉冲。 // 当主设备计数器运行并第一次达到APRD时,会发出同步脉冲,此时从设备的TSCTR才会从CTRPHS值开始计数。 }

避坑指南:配置顺序的重要性

  1. 先配置从设备,再启动主设备:这是一个最佳实践。确保所有从设备的SYNCI_EN已使能并正确配置后,再启动主设备的计数器。这样可以避免主设备发出同步脉冲时,从设备还未准备好,导致同步错乱。
  2. 相位值CTRPHS的加载时机CTRPHS值是在同步脉冲到来时加载到计数器中的。因此,在同步脉冲到来之前修改CTRPHS是有效的。如果你想在运行中动态调整相位,需要在两个同步脉冲之间修改CTRPHS,并且要确保写入的是影子寄存器(如果支持),以避免当前周期出现毛刺。
  3. 影子寄存器的使用:动态更新CAP1(APRD)或CAP2(ACMP)时,务必查阅芯片手册确认正确的影子寄存器写入方式。通常,写入CAP1CAP2本身,更新会在下一个CTR=PRD事件时生效。错误的写入方式可能导致PWM输出出现非预期的跳变。

4.4 运行时代码与动态控制

初始化完成后,PWM波形会自动产生。在应用程序中,你可能需要动态调整占空比。这通过更新CAP2寄存器(比较值)实现。

// 动态改变ECAP1的占空比为75% uint32_t new_cmp = 19999 * 0.75; // 计算新的比较值 ECAP1Regs.CAP2 = new_cmp; // 注意:根据手册,运行时通常应写入影子寄存器。此处直接写入CAP2,取决于芯片具体实现。 // 对于某些器件,可能需要使用特定的影子寄存器加载机制,例如: // ECAP1Regs.CAP2 = new_cmp; // 写入活动寄存器? // 或者通过CTR=PRD事件加载影子寄存器。请务必参考具体的数据手册或技术参考手册。

对于需要精密相位控制的场景,如多相交错电源,你可能需要在运行时微调某个通道的CTRPHS值,以补偿硬件布线延迟或元件差异。

// 微调ECAP2的相位,增加少量延迟(例如,对应计数器增加100个时钟) uint32_t current_phase = ECAP2Regs.CTRPHS; uint32_t adjusted_phase = (current_phase + 100) % (ECAP2Regs.CAP1 + 1); // 确保不溢出 ECAP2Regs.CTRPHS = adjusted_phase; // 在下一个同步脉冲生效

5. 常见问题排查与调试技巧实录

即使理解了原理和配置,在实际调试中依然会遇到各种问题。下面是我在多个项目中总结出的常见问题及其排查思路。

5.1 问题一:无PWM输出或输出不正确

现象:引脚没有波形,或者波形频率、占空比与预期不符。

排查步骤

  1. 时钟与引脚检查

    • 确认系统时钟:首先确认提供给eCAP模块的系统时钟(SYSCLK)是否已使能且频率正确。检查系统时钟配置寄存器。
    • 确认引脚复用:这是最容易被忽略的一步!使用芯片的引脚复用工具(如TI的PinMux工具)或直接检查PINMUX寄存器,确保你使用的ECAPx引脚已被正确配置为ECAP功能,而不是默认的GPIO或其他功能。
    • 确认引脚方向:eCAP的APWM输出引脚应自动配置为输出。但如果是捕获模式输入,则需确保外部信号已正确连接到引脚。
  2. 寄存器配置复查

    • 模式选择ECCTL2.CAP_APWM位是否已正确设置为EC_APWM_MODE(PWM模式)或EC_CAP_MODE(捕获模式)?
    • 计数器状态ECCTL2.TSCTRSTOP位是否已设置为EC_RUN?在调试初期,可以在配置完成后,通过调试器读取该寄存器确认。
    • 周期与比较值:读取CAP1CAP2寄存器,确认写入的值是否正确。特别注意在APWM模式下,CAP1是周期,CAP2是比较值。一个常见的错误是写反了。
    • 极性设置:检查ECCTL2.APWMPOL位。如果设置为EC_ACTV_LO(低电平有效),而你用示波器在默认高电平有效的逻辑下观察,可能会误以为没有输出。尝试翻转极性测试。
  3. 同步配置检查(仅限多通道)

    • 主设备同步输出:主设备的SYNCO_SEL是否配置为EC_CTR_PRD
    • 从设备同步输入:从设备的SYNCI_EN是否使能?SYNCO_SEL是否配置为EC_SYNCI
    • 物理连接:有些芯片的eCAP同步信号是内部连接的,无需外部布线;有些则需要通过外部引脚或交叉开关连接。务必查阅数据手册的“信号描述”章节。

5.2 问题二:捕获模式读数全为零或不变

现象:在捕���模式下,无论输入信号如何变化,读取的CAP1-CAP4寄存器值始终为0或固定值。

排查步骤

  1. 输入信号与边沿检测

    • 信号质量:使用示波器检查输入到ECAP引脚的实际信号。是否存在毛刺?电平幅度是否满足芯片的VIH/VIL要求?
    • 边沿极性:确认ECCTL1.CAPxPOL位设置是否与输入信号的跳变方向一致。如果你期待上升沿捕获,但配置成了下降沿,当然捕获不到。
    • 预分频器:检查ECCTL1.PRESCALE。如果被设置为EC_DIV2或更高,你需要两个事件才能触发一次捕获。
  2. 捕获使能与计数器

    • 捕获加载使能这是最关键的一步!ECCTL1.CAPLDEN位必须设置为EC_ENABLE。如果禁用,即使发生捕获事件,时间戳也不会被加载到CAPx寄存器中,你读到的永远是初始值(可能是0)。
    • 计数器运行:确认ECCTL2.TSCTRSTOP位为EC_RUN。你可以尝试在调试器中连续读取TSCTR寄存器的值,看它是否在递增。
    • 中断与状态:使能CEVT1-CEVT4等中断,或在主循环中轮询ECFLG寄存器中的对应标志位。确认捕获事件是否真的发生了。
  3. 读取时机与寄存器映射

    • 影子寄存器:在连续捕获模式下,CAP1-CAP4寄存器是双缓冲的。确保你是在捕获事件发生后(例如CEVT4中断中)读取数据。直接读取可能得到旧值。
    • 寄存器地址:确认你访问的是正确的eCAP模块实例(如ECAP1RegsECAP2Regs)和正确的寄存器。

5.3 问题三:多通道PWM不同步或相位错误

现象:多个eCAP通道输出的PWM频率虽然是整数倍关系,但起始边沿没有对齐,或者相位差与设定值不符。

排查步骤

  1. 同步信号路径验证

    • 主设备同步输出:确认主设备的SYNCO_SEL配置正确,并且其TSCTR在达到CAP1(APRD)时确实能产生内部同步脉冲。可以通过配置主设备在CTR=PRD时产生中断来验证。
    • 从设备同步感知:检查从设备的ECFLG寄存器中是否有SYNCI标志位被置起,这表明它收到了同步脉冲。如果没有,检查SYNCI_EN配置。
  2. 相位值计算与加载

    • CTRPHS计算逻辑:重新审视CTRPHS的计算公式。记住,它设定的是计数器在同步脉冲到来时的起始值。相位延迟 =( (APRD - CTRPHS + 1) / (APRD + 1) ) * 360°(当CTRPHS > ACMP时,逻辑更复杂,涉及计数器溢出)。使用第4.3节中的方法进行仔细计算和验证。
    • CTRPHS生效时机CTRPHS值是在同步脉冲边沿被加载到计数器中的。确保你在同步脉冲之间修改CTRPHS,并且修改的是正确的寄存器(活动寄存器还是影子寄存器?)。一个调试技巧是:先将所有从设备的CTRPHS设为0,观察它们是否与主设备完全同步(起始边沿对齐)。然后再逐步增加CTRPHS值,观察相位偏移是否符合预期。
  3. 计数器启动顺序

    • 确保所有从设备的计数器都处于“等待同步”状态(TSCTRSTOP可能为RUN,但实际由SYNCI控制),然后再启动主设备计数器。错误的启动顺序可能导致第一个周期不同步。

5.4 调试技巧与工具使用

  1. 寄存器视图实时监控:在CCS的调试视图中,添加eCAP相关寄存器的监视窗口。特别是TSCTRCAP1-CAP4ECCTL1ECCTL2ECFLG。单步执行初始化代码,观察寄存器值的变化是否符合预期。
  2. 利用中断调试捕获:在捕获模式下,使能CEVT4中断,并在中断服务程序里设置断点。当断点触发时,检查CAP1-CAP4的值,并计算它们之间的差值是否与信号发生器设置的周期相符。
  3. 逻辑分析仪或示波器:这是最直观的工具。同时测量主从设备的PWM输出,可以清晰看到同步和相位关系。对于捕获模式,可以测量输入信号和某个GPIO(在中断中翻转)之间的时序,来验证捕获的准确性。
  4. 软件模拟信号:在硬件连接不便时,可以编写一个简单的GPIO翻转程序来模拟输入信号,用于验证捕获功能的软件逻辑是否正确。
  5. 查阅勘误表:TI的芯片有时存在特定的硅片勘误。如果你遇到了非常诡异且无法解释的现象,去TI官网搜索该芯片的勘误表,看看是否有与eCAP模块相关的问题描述和解决方案。