C2000 eCAP模块实战:从信号捕获到多路同步PWM生成
1. 项目概述与eCAP模块核心价值
在嵌入式系统,尤其是电机控制、数字电源和精密测量领域,我们常常面临两个看似矛盾的核心需求:一是需要以极高的精度和实时性去“感知”外部世界的变化,比如测量一个PWM信号的频率、占空比,或者捕捉一个编码器脉冲的精确到达时间;二是需要以同样的高精度和确定性去“控制”外部世界,比如生成多路严格同步且相位可调的PWM波去驱动一个三相电机。如果这两项工作都交给CPU软件循环去处理,不仅会消耗大量宝贵的计算资源,更难以保证在复杂中断环境下的时序精度和确定性。这时,一个强大的硬件外设就成了项目成败的关键。德州仪器(TI)在其C2000系列等微控制器中集成的增强型捕获(Enhanced Capture, eCAP)模块,正是为解决这类问题而生的“瑞士军刀”。
简单来说,eCAP模块是一个高度可配置的硬件单元,它身兼二职。在捕获(CAP)模式下,它是一个“超级记录员”,能在外部输入信号(ECAPx引脚)的指定边沿(上升沿、下降沿或两者)触发时,自动将内部32位时间戳计数器(TSCTR)的当前值“抓拍”并存入四个独立的捕获寄存器(CAP1-CAP4)。这个过程完全由硬件完成,不占用CPU,精度高达一个系统时钟周期。在APWM模式下,它又摇身一变,成为一个“精准信号发生器”,利用相同的计数器比较逻辑,在APWMx引脚上输出频率和占空比均可动态调整的PWM波形。更厉害的是,多个eCAP模块之间可以通过同步信号链起来,实现多路PWM的严格同步或精确的相位差控制,这对于无刷直流电机(BLDC)驱动、三相逆变器、交错并联电源等拓扑是至关重要的。
我最初接触eCAP是在一个伺服电机控制项目上,需要同时处理来自光电编码器的ABZ信号(用于位置和速度反馈)和生成驱动三相全桥的六路PWM。如果只用通用定时器,代码会变得异常复杂且脆弱。而eCAP的硬件四深度序列器(Sequencer)和自动边沿极性检测,让我用极简的配置就实现了四倍频计数和索引捕获,同时还能空出CPU资源运行复杂的FOC算法。本文将结合官方手册的精华和我的实战踩坑经验,为你彻底拆解eCAP模块,从最基础的时间戳捕获原理,到复杂的多通道同步PWM生成,手把手带你吃透这个强大外设的每一个细节。
2. eCAP模块架构与核心寄存器深度解析
要驾驭eCAP,必须先理解它的“五脏六腑”。它的核心是一个32位的向上计数时间戳计数器(TSCTR),这是所有时间测量的基准。围绕这个计数器,构建了一套精巧的捕获与比较逻辑。我们可以把eCAP模块想象成一个拥有四个“抓拍点位”(对应CAP1-CAP4寄存器)的高速摄影系统,而MOD4计数器(一个2位状态机)就是控制哪个点位准备“拍照”的调度员。
2.1 核心工作流程与寄存器映射
当模块配置为捕获模式时,其工作流程如下:外部信号从ECAPx引脚输入,经过可配置的边沿极性选择(上升沿、下降沿)和事件预分频滤波后,成为一个有效的“捕获事件”(CEVT)。这个事件会触发两个动作:第一,将当前TSCTR的值锁存到当前由MOD4计数器指向的捕获寄存器中(例如,MOD4=0时存入CAP1);第二,根据配置,决定是否在捕获后复位TSCTR(这是区分“绝对时间戳”和“差值时间戳”模式的关键);第三,MOD4计数器加1,指向下一个捕获寄存器,为下一次事件做准备。这个过程形成一个循环缓冲区,实现了连续、不间断的事件记录。
所有这些都是通过一组内存映射寄存器来控制的。下表是eCAP模块的核心寄存器概览,理解它们的用途是进行任何配置的前提:
| 偏移地址 | 寄存器缩写 | 全称 | 核心功能描述 |
|---|---|---|---|
| 0x00 | TSCTR | 时间戳计数器 | 32位自由运行或可复位的基础计数器,是所有时间测量的基准。 |
| 0x04 | CTRPHS | 计数器相位控制寄存器 | 存放相位偏移值,用于在同步事件(SYNCI)发生时加载到TSCTR,实现多模块间的相位对齐。 |
| 0x08 | CAP1 | 捕获1寄存器 | 在CAP模式,存储第1个事件的时戳;在APWM模式,作为周期值(APRD)的主动寄存器。 |
| 0x0C | CAP2 | 捕获2寄存器 | 在CAP模式,存储第2个事件的时戳;在APWM模式,作为比较值(ACMP)的主动寄存器。 |
| 0x10 | CAP3 | 捕获3寄存器 | 在CAP模式,存储第3个事件的时戳;在APWM模式,作为周期值(APRD)的影子寄存器。 |
| 0x14 | CAP4 | 捕获4寄存器 | 在CAP模式,存储第4个事件的时戳;在APWM模式,作为比较值(ACMP)的影子寄存器。 |
| 0x28 | ECCTL1 | 捕获控制寄存器1 | 模式配置核心。控制每个捕获事件的边沿极性(CAPxPOL)、是否复位计数器(CTRRSTx)、事件预分频(PRESCALE)等。 |
| 0x2A | ECCTL2 | 捕获控制寄存器2 | 工作模式与同步控制核心。决定模块工作在CAP还是APWM模式(CAP/APWM位)、启动/停止计数器(TSCTRSTOP)、选择连续/单次模式、配置同步输入输出(SYNCI_EN, SYNCO_SEL)等。 |
| 0x2C | ECEINT | 中断使能寄存器 | 使能或禁用特定事件(如CEVT1-4, CTROVF等)触发中断。 |
| 0x2E | ECFLG | 中断标志寄存器 | 指示特定事件是否已发生。需软件查询或在中斷服務程式(ISR)中判斷。 |
| 0x30 | ECCLR | 中断清除寄存器 | 用于清除ECFLG中对应的标志位。注意:在ISR中必须手动清除标志,否则会持续触发中断。 |
| 0x32 | ECFRC | 中断强制寄存器 | 可以软件强制设置某个事件标志,用于测试或特殊控制。 |
注意:在APWM模式下,CAP1/CAP2是“主动寄存器”,其值直接参与和TSCTR的比较,从而决定PWM周期和翻转点。而CAP3/CAP4是它们的“影子寄存器”。上电初始化时,你需要同时写入主动寄存器和影子寄存器(通常写CAP1/CAP2,硬件会自动拷贝到CAP3/CAP4)。在运行时动态更新PWM参数(如改变占空比),必须只写入影子寄存器(CAP3/CAP4),硬件会在下一个PWM周期开始时安全地将影子寄存器的值加载到主动寄存器,避免在周期中间产生毛刺或错误的脉冲。这是一个非常重要的“影子寄存器”机制,在电机控制中频繁更新占空比时务必遵守。
2.2 关键控制位详解与配置逻辑
理解了寄存器布局,我们深入看看几个最关键的配置位,它们直接决定了eCAP的行为模式。
ECCTL1寄存器:这是捕获行为的“雕刻刀”。
- CAPxPOL (位0,2,4,6):分别对应4个捕获事件的边沿极性。0为上升沿触发,1为下降沿触发。通过交替设置(如CAP1POL=0上升沿,CAP2POL=1下降沿),可以同时捕获一个PWM波的周期和占空比信息。
- CTRRSTx (位1,3,5,7):这是绝对时间戳与差值时间戳模式的分水岭。如果设置为0(EC_ABS_MODE),则在对应事件捕获后,TSCTR继续自由运行,捕获到的是自计数器启动以来的“绝对时间”。如果设置为1(EC_DELTA_MODE),则在对应事件捕获后,TSCTR会立即复位到0,那么下一次捕获到的值就是两次事件之间的“时间差”。差值模式极大简化了软件计算,捕获值本身就是周期或脉宽。
- CAPLDEN (位8):必须置1,才能使能捕获事件发生时硬件自动加载时间戳到CAP1-CAP4寄存器。
- PRESCALE (位13-9):事件预分频。用于滤除输入信号上的高频毛刺。例如,设置为2(除以4)意味着需要连续4个时钟周期的有效边沿才被认为是一个捕获事件。在噪声较大的工业环境中,合理设置此值至关重要。
ECCTL2寄存器:这是模块的“模式与同步总开关”。
- CAP/APWM (位9):最根本的模式选择。0为捕获模式,1为APWM模式。两种模式下,其他寄存器的功能有根本性变化。
- CONT/ONESHT (位0):在捕获模式下,选择连续捕获(0)还是单次捕获(1)。连续模式下,MOD4计数器在达到STOP_WRAP值后会回绕,循环覆盖CAP1-CAP4。单次模式下,捕获指定次数(由STOP_WRAP决定)后停止,需要软件重新“武装”(RE-ARM)才能再次启动。
- STOP_WRAP (位2-1):在单次模式下,定义在哪个捕获事件后停止(1-4)。在连续模式下,定义循环缓冲区的深度(1-4)。通常设置为3(即0b11,对应事件4),以充分利用四个捕获寄存器。
- SYNCI_EN (位5):使能同步输入。置1后,当外部同步信号(SYNCI)到来时,TSCTR会被CTRPHS寄存器的值重载。这是实现多模块相位同步的关键。
- SYNCO_SEL (位7-6):选择同步输出信号源。可以禁用、直通SYNCI、或者选择当TSCTR等于周期值(CTR=PRD)时产生同步脉冲。在多模块级联时,主模块通常设置为
EC_CTR_PRD输出同步,从模块设置为EC_SYNCI输入并使能SYNCI_EN。
3. 核心操作模式实战:从捕获到生成
理论铺垫完毕,现在我们进入实战环节。我将通过几个典型的配置案例,展示如何将寄存器配置转化为具体的功能。
3.1 模式一:绝对时间戳捕获(测量周期与占空比)
这是最直观的捕获模式。TSCTR自由运行,每次捕获事件发生时,硬件将此刻TSCTR的“快照”存入寄存器。软件需要读取两次捕获值并相减,才能得到时间间隔。
应用场景:测量一个未知PWM信号的频率和占空比。配置目标:在信号的上升沿和下降沿都进行捕获,用CAP1和CAP2分别记录上升沿和下降沿的时间戳。寄存器配置逻辑:
- 边沿配置:设置CAP1POL=0(上升沿),CAP2POL=1(下降沿)。这样,第一个上升沿触发CEVT1,时间戳存CAP1;紧接着的下降沿触发CEVT2,时间戳存CAP2;下一个上升沿触发CEVT3,存CAP3;下一个下降沿触发CEVT4,存CAP4,如此循环。
- 计数器模式:设置CTRRST1-4 = EC_ABS_MODE(0),即捕获后不复位TSCTR。
- 工作模式:ECCTL2.CAP/APWM = EC_CAP_MODE (0),模块工作在捕获模式。
- 连续捕获:ECCTL2.CONT/ONESHT = EC_CONTINUOUS (0),STOP_WRAP = 0x3(在事件4后回绕),实现四个寄存器的循环使用。
根据上述逻辑,我们可以整理出具体的寄存器配置表,这与官方手册的示例一致:
| 寄存器 | 位字段 | 配置值 | 说明 |
|---|---|---|---|
| ECCTL1 | CAP1POL | EC_RISING (0) | 事件1:上升沿触发 |
| ECCTL1 | CAP2POL | EC_FALLING (1) | 事件2:下降沿触发 |
| ECCTL1 | CAP3POL | EC_RISING (0) | 事件3:上升沿触发 |
| ECCTL1 | CAP4POL | EC_FALLING (1) | 事件4:下降沿触发 |
| ECCTL1 | CTRRST1-4 | EC_ABS_MODE (0) | 绝对时间戳模式,捕获后计数器不复位 |
| ECCTL1 | CAPLDEN | EC_ENABLE (1) | 使能捕获加载 |
| ECCTL2 | CAP_APWM | EC_CAP_MODE (0) | 设置为捕获模式 |
| ECCTL2 | CONT_ONESHT | EC_CONTINUOUS (0) | 连续捕获模式 |
| ECCTL2 | TSCTRSTOP | EC_RUN (1) | 启动时间戳计数器 |
软件处理流程(以中断服务程序为例): 通常,我们会在第四个捕获事件(CEVT4)中断中读取所有四个寄存器,进行一次完整的计算。因为此时一个完整的“上升-下降-上升-下降”周期已经捕获完毕,CAP1和CAP3是相邻两个上升沿的时间,CAP1和CAP2是同一个脉冲的上升沿和下降沿时间。
// 假设在CEVT4中断服务程序中 uint32_t t1, t2, t3, t4; uint32_t period, duty_on, duty_off; float duty_cycle_percent; // 1. 读取时间戳 t1 = ECAP1Regs.CAP1; // 第一个上升沿 t2 = ECAP1Regs.CAP2; // 第一个下降沿 t3 = ECAP1Regs.CAP3; // 第二个上升沿 t4 = ECAP1Regs.CAP4; // 第二个下降沿 // 2. 计算第一个完整周期的参数 period = t3 - t1; // 周期 = 第二个上升沿 - 第一个上升沿 duty_on = t2 - t1; // 高电平时间 = 下降沿 - 上升沿 duty_off = t3 - t2; // 低电平时间 = 下一个上升沿 - 下降沿 duty_cycle_percent = (float)duty_on / (float)period * 100.0f; // 3. 清除中断标志(必须做!) ECAP1Regs.ECCLR.bit.CEVT4 = 1; ECAP1Regs.ECCLR.bit.INT = 1;实操心得:在绝对时间戳模式下,要特别注意32位计数器的溢出问题。TSCTR是32位无符号整数,当它从0xFFFFFFFF加1回到0x00000000时,会发生溢出(CTROVF标志置位)。如果两次捕获事件间隔时间很长,跨越了溢出点,直接相减会得到错误结果。一个稳健的做法是:在中断服务程序中,不仅读取捕获值,也检查CTROVF标志。如果发生溢出,需要在软件中维护一个64位或更高精度的扩展计数器。例如,设置一个全局变量
overflow_count,在CTROVF中断中将其加1。计算时间差时,公式应为:delta = (current_overflow * (0xFFFFFFFF + 1) + current_capture) - (previous_overflow * (0xFFFFFFFF + 1) + previous_capture)。
3.2 模式二:差值时间戳捕获(直接获取时间间隔)
这是更高效的模式。硬件在每次有效捕获事件发生后,自动将TSCTR复位到0。因此,捕获寄存器中存储的值,直接就是本次事件与上一次事件之间的时间间隔(Delta Time)。
应用场景:测量方波的周期(仅上升沿)或同时测量周期与脉宽(上升沿和下降沿)。配置目标:在上升沿和下降沿都捕获,并直接得到高电平和低电平时间。寄存器配置逻辑:
- 边沿配置:与上例类似,CAP1POL=0(上升沿),CAP2POL=1(下降沿),交替设置。
- 计数器模式:这是关键!设置CTRRST1-4 = EC_DELTA_MODE(1)。这样,每次捕获后,TSCTR立即归零,下一个时间间隔从零开始计数。
- 其他配置(模式、连续运行等)与绝对时间戳模式类似。
配置表如下:
| 寄存器 | 位字段 | 配置值 | 说明 |
|---|---|---|---|
| ECCTL1 | CAP1POL | EC_RISING (0) | 上升沿 |
| ECCTL1 | CAP2POL | EC_FALLING (1) | 下降沿 |
| ECCTL1 | CAP3POL | EC_RISING (0) | 上升沿 |
| ECCTL1 | CAP4POL | EC_FALLING (1) | 下降沿 |
| ECCTL1 | CTRRST1-4 | EC_DELTA_MODE (1) | 差值模式,捕获后计数器复位 |
| ECCTL1 | CAPLDEN | EC_ENABLE (1) | 使能捕获加载 |
| ECCTL2 | CAP_APWM | EC_CAP_MODE (0) | 捕获模式 |
| ECCTL2 | CONT_ONESHT | EC_CONTINUOUS (0) | 连续模式 |
| ECCTL2 | TSCTRSTOP | EC_RUN (1) | 启动计数器 |
软件处理流程: 在差值模式下,计算变得极其简单。CAP1存储的是第一个上升沿到第一个下降沿的时间(高电平时间),CAP2存储的是第一个下降沿到第二个上升沿的时间(低电平时间),以此类推。在CEVT1中断(或任何你选择的中断点)中读取,值本身就是时间间隔。
// 假设在CEVT1中断服务程序中读取(此时CAP1-CAP4均已更新) uint32_t high_time1, low_time1, high_time2, low_time2; uint32_t period1, period2; // 直接读取即��时间间隔 high_time1 = ECAP1Regs.CAP2; // T2: 第一个高电平时间 (CAP2对应事件2,下降沿) low_time1 = ECAP1Regs.CAP3; // T3: 第一个低电平时间 (CAP3对应事件3,上升沿) high_time2 = ECAP1Regs.CAP4; // T4: 第二个高电平时间 low_time2 = ECAP1Regs.CAP1; // T1: **注��循环**,第二个低电平时间(下一个周期的CAP1) // 计算周期(高+低) period1 = high_time1 + low_time1; period2 = high_time2 + low_time2; // 清除中断标志 ECAP1Regs.ECCLR.bit.CEVT1 = 1; ECAP1Regs.ECCLR.bit.INT = 1;注意事项:在差值模式下,由于计数器每次捕获后都复位,因此不存在绝对时间戳模式下的计数器溢出问题。但是,你必须确保输入信号的最大时间间隔不会超过TSCTR从0计数到0xFFFFFFFF的时间。例如,系统时钟SYSCLKOUT为100MHz,则TSCTR每个计数代表10ns。0xFFFFFFFF ≈ 42.9亿,对应最大可测量时间间隔约为42.9秒。如果信号间隔可能超过此值,就必须在软件中监控CTROVF标志,或者使用预分频器(ECCTL1.PRESCALE)来降低时间基准的频率,以扩展测量范围,但这会牺牲分辨率。
3.3 模式三:APWM模式——单通道PWM生成
eCAP模块在APWM模式下,化身为一个完整的PWM发生器。其核心原理与通用PWM模块类似:TSCTR向上计数,与两个比较值(CAP1作为周期寄存器APRD,CAP2作为比较寄存器ACMP)进行比较,从而在APWMx引脚上输出波形。
配置要点:
- 模式切换:将ECCTL2.CAP/APWM位设置为EC_APWM_MODE (1)。
- 影子寄存器机制:如前所述,CAP1/CAP2是主动寄存器,CAP3/CAP4是它们的影子寄存器。初始化时必须同时写入主动和影子寄存器(通常直接写CAP1和CAP2,硬件会自动拷贝)。运行时更新参数(如改变占空比)必须只写入影子寄存器CAP4(对于比较值)或CAP3(对于周期值)。
- 输出极性:通过ECCTL2.APWMPOL位选择。0为高有效(比较值代表高电平时间),1为低有效(比较值代表低电平时间)。
- 同步与相位:CTRPHS寄存器在此模式下用于设置相位偏移。当同步事件(SYNCI)发生时,TSCTR会被加载为CTRPHS的值,从而实现与其他eCAP或ePWM模块的相位对齐。
一个简单的单通道PWM生成配置示例: 假设我们需要生成一个周期为0x1000个时钟 ticks,初始占空比为50%(即比较值=0x800)的PWM波。
// 初始化代码片段 // 停止计数器 ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_STOP; // 1. 配置为APWM模式,高有效输出,禁止同步 ECAP1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; // APWM模式 ECAP1Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; // 高有效 ECAP1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // 禁用同步输入 ECAP1Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCO_DIS; // 禁用同步输出 // 2. 设置周期和占空比 (同时写入主动和影子寄存器) ECAP1Regs.CAP1 = 0x1000; // 设置周期值 APRD (会同时加载到CAP3) ECAP1Regs.CAP2 = 0x800; // 设置比较值 ACMP,占空比50% (会同时加载到CAP4) // 3. 启动计数器 ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // 运行时动态改变占空比到25% (0x400) ECAP1Regs.CAP4 = 0x400; // **只写入影子寄存器CAP4**,硬件会在下一个周期开始时安全更新4. 高级应用:多通道同步与相位控制实战
eCAP真正强大的地方在于多个模块之间的协同工作能力,这对于需要多路精确时序控制的应用(如三相电机驱动、多相交错电源)是必不可少的。
4.1 多通道同步PWM生成
场景:需要生成4路PWM,它们的频率成整数倍关系(例如F1, 2F1, 4F1, 5*F1),并且所有PWM波的周期起点必须严格对齐,以避免产生有害的差拍频率。
解决方案:指定一个eCAP模块作为主模块(Master),其余为从模块(Slave)。主模块在其TSCTR等于周期值(CTR=PRD)时,产生一个同步输出脉冲(SYNCO)。从模块配置为接收外部同步输入(SYNCI),并在同步事件发生时,将其TSCTR重载为CTRPHS的值(通常设为0以实现对齐)。
配置步骤:
- 主模块 (例如 ECAP1):
- 设置其SYNCO_SEL = EC_CTR_PRD,使其在计数器等于周期时发出同步脉冲。
- 设置其SYNCI_EN = EC_DISABLE(通常主模块不需要外部同步)。
- 根据所需的最低频率设置其CAP1(APRD)为最大周期值。
- 从模块 (例如 ECAP2, ECAP3, ECAP4):
- 设置其SYNCI_EN = EC_ENABLE,使能同步输入。
- 设置其SYNCO_SEL = EC_SYNCI(直通同步信号,如果它还需要级联)或EC_SYNCO_DIS(如果它是链的末端)。
- 将CTRPHS设置为0,以确保同步时所有从模块的TSCTR都从0开始,与主模块对齐。
- 根据各自所需的频率(主频的整数倍)设置自己的CAP1(APRD)值。APRD值 = 主模块APRD / 频率倍数。例如,主频为F1,APRD=20000;2倍频的从模块APRD应设为10000。
连接方式:主模块的SYNCO输出引脚需要连接到所有从模块的SYNCI输入引脚(在芯片内部或通过GPIO MUX配置)。
代码示意:
// 主模块 ECAP1 初始化 (生成基础频率F1) ECAP1Regs.CAP1 = 20000; // 周期值,对应频率F1 ECAP1Regs.CTRPHS = 0; ECAP1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; ECAP1Regs.ECCTL2.bit.SYNCO_SEL = EC_CTR_PRD; // 关键:CTR=PRD时输出同步 ECAP1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // 从模块 ECAP2 初始化 (生成2倍频, 2*F1) ECAP2Regs.CAP1 = 10000; // 周期值为主模块的一半 ECAP2Regs.CTRPHS = 0; // 相位偏移为0,与主模块对齐 ECAP2Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; ECAP2Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCI; // 同步输出直通输入(可选) ECAP2Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; // 关键:使能同步输入 // 类似地初始化 ECAP3 (4*F1, CAP1=5000), ECAP4 (5*F1, CAP1=4000) // ... ECAP3Regs.CAP1 = 5000; ... // ... ECAP4Regs.CAP1 = 4000; ... // 最后统一启动所有计数器 ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; ECAP2Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // ... 启动ECAP3, ECAP44.2 多通道带相位控制的PWM生成
场景:在三相交错并联DC/DC转换器中,需要3路PWM,它们频率相同,但相位依次相差120度。这可以减小输入电流纹波和输出电容应力。
解决方案:依然使用主从同步结构。关键区别在于,从模块的CTRPHS寄存器不再设置为0,而是设置为一个特定的相位偏移值。这个偏移值需要根据PWM周期和期望的相位差来计算。
计算相位偏移值: 假设PWM周期寄存器值(APRD)为Period,期望的相位差为Phase_shift_degrees(例如120°)。 相位偏移寄存器值CTRPHS = (Phase_shift_degrees / 360) * Period。 由于TSCTR是整数计数器,计算结果需要取整。
配置示例:三相交错,主模块(ECAP1)相位为0°,从模块2(ECAP2)滞后120°,从模块3(ECAP3)滞后240°。设APRD = 1200。
- ECAP1.CTRPHS = 0 (0°)
- ECAP2.CTRPHS = (120 / 360) * 1200 = 400
- ECAP3.CTRPHS = (240 / 360) * 1200 = 800
配置表核心:
| 模块 | CAP1 (APRD) | CTRPHS | SYNCI_EN | SYNCO_SEL | 说明 |
|---|---|---|---|---|---|
| ECAP1 | 1200 | 0 | 禁用 (0) | EC_CTR_PRD | 主模块,0°相位,CTR=PRD时发出同步 |
| ECAP2 | 1200 | 400 | 使能 (1) | EC_SYNCI | 从模块,同步输入,相位滞后120° |
| ECAP3 | 1200 | 800 | 使能 (1) | EC_SYNCO_DIS | 从模块,同步输入,相位滞后240°,末端不输出同步 |
软件实现:
// 初始化 // 主模块 ECAP1 ECAP1Regs.CAP1 = 1200; // 周期 ECAP1Regs.CTRPHS = 0; // 0度相位 ECAP1Regs.ECCTL2.bit.SYNCO_SEL = EC_CTR_PRD; ECAP1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // 从模块 ECAP2 (120度滞后) ECAP2Regs.CAP1 = 1200; // 相同周期 ECAP2Regs.CTRPHS = 400; // 120/360 * 1200 = 400 ECAP2Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; ECAP2Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCI; // 传递同步信号 // 从模块 ECAP3 (240度滞后) ECAP3Regs.CAP1 = 1200; // 相同周期 ECAP3Regs.CTRPHS = 800; // 240/360 * 1200 = 800 ECAP3Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; ECAP3Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCO_DIS; // 末端模块,禁用同步输出 // 设置相同的占空比(例如700/1200 ≈ 58.3%) ECAP1Regs.CAP2 = 700; // 会拷贝到CAP4 ECAP2Regs.CAP2 = 700; ECAP3Regs.CAP2 = 700; // 启动计数器(建议先启动从模块,最后启动主模块,以确保第一次同步即生效) ECAP2Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; ECAP3Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; ECAP1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // 主模块最后启动,产生第一个同步脉冲关键技巧:在启动顺序上,一个常见的经验是先启动从模块,最后启动主模块。这样可以确保从模块的同步功能已使能并准备就绪,当主模块启动并产生第一个CTR=PRD同步脉冲时,所有从模块能同时被正确同步和加载相位偏移。如果先启动主模块,从模块可能错过第一个同步脉冲,导致初始相位错乱。
5. 常见问题、调试技巧与实战心得
即使理解了原理和配置,在实际项目中调试eCAP模块时,依然会遇到各种问题。下面是我总结的一些常见坑点和调试方法。
5.1 常见问题排查速查表
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 捕获不到任何事件 | 1. 输入引脚复用功能未正确配置。 2. ECCTL1.CAPLDEN 未使能。 3. 事件预分频(PRESCALE)设置过高,滤除了正常信号。 4. 输入信号边沿不满足设置极性。 | 1. 检查GPIO MUX配置,确保引脚功能设置为ECAP。 2. 确认ECCTL1.CAPLDEN = 1。 3. 尝试将PRESCALE设为0(不分频)。 4. 用示波器检查输入信号,确认边沿与CAPxPOL设置匹配。 |
| 捕获值全为0或不变 | 1. TSCTR计数器未启动(ECCTL2.TSCTRSTOP=0)。 2. 在APWM模式下误操作了CAP1-4寄存器。 3. 中断标志未清除,导致后续中断被阻塞。 | 1. 确认ECCTL2.TSCTRSTOP = 1。 2. 在CAP模式确认是捕获模式;在APWM模式确认是APWM模式,且操作正确的寄存器(影子/主动)。 3. 在中断服务程序中,检查并清除对应的ECFLG标志位和全局INT标志。 |
| PWM无输出或输出异常 | 1. APWM输出引脚未正确配置。 2. 比较值(ACMP)大于或等于周期值(APRD)。 3. 影子寄存器机制使用错误,运行时写入了主动寄存器。 4. 输出极性(APWMPOL)设置与电路预期相反。 | 1. 检查GPIO输出使能和复用配置。 2. 确保ACMP < APRD。若相等,占空比将为100%或0%(取决于极性)。 3.运行时更新占空比/周期,务必只写CAP3/CAP4(影子寄存器)。 4. 检查APWMPOL位,根据驱动电路需求调整。 |
| 多模块间不同步 | 1. 同步信号(SYNCI/SYNCO)未正确连接或使能。 2. 主从模块的启动顺序有误。 3. 从模块的CTRPHS寄存器未正确设置。 4. 主模块的SYNCO_SEL配置错误。 | 1. 检查芯片数据手册,确认SYNCI/SYNCO的内部映射或外部连接。 2.尝试先启动从模块,最后启动主模块。 3. 核对相位计算:CTRPHS = (期望相位/360) * APRD。 4. 主模块SYNCO_SEL应设为EC_CTR_PRD;从模块SYNCI_EN应使能,SYNCO_SEL按需设置。 |
| 中断无法进入 | 1. 外设级中断未使能(ECEINT寄存器)。 2. PIE或CPU级中断未使能或向量表配置错误。 3. 中断标志在初始化前已置位,未清除。 | 1. 确认ECEINT中对应事件位(如CEVT4)已置1。 2. 检查PIE相关配置,确认中断函数已正确关联到PIE向量表。 3. 在初始化eCAP模块之前,先清除ECFLG和ECCLR中所有可能残留的标志位。 |
5.2 调试技巧与心得
善用仿真器与寄存器观察窗口:在CCS等IDE中,实时观察TSCTR、CAP1-CAP4、ECFLG等关键寄存器的值变化,是理解模块行为最直接的方式。你可以单步执行代码,看看配置后寄存器是否按预期改变;在捕获模式下,给一个输入信号,看CAP寄存器是否被更新;在APWM模式下,看TSCTR是否在0和APRD之间循环,以及ACMP是否起作用。
利用强制中断(ECFRC)进行测试:在开发初期,硬件信号可能还不稳定。你可以利用ECFRC寄存器,通过软件强制置位某个事件标志(如CEVT1),来测试你的中断服务程序是否能被正确触发和执行。这是一个隔离硬件依赖,验证软件逻辑的好方法。
理解“影子寄存器”更新时机:在APWM模式下,写入影子寄存器(CAP3/CAP4)后,新值并不会立即生效。它会在下一个TSCTR=0的时刻(即下一个PWM周期开始)被加载到主动寄存器(CAP1/CAP2)。这意味着你可以在任何时候安全地更新影子寄存器,而不会导致当前周期出现毛刺。但这也带来了一个延迟:你写入的新参数,最快在下一个周期生效。在要求快速响应的闭环控制中,需要考虑这个单周期延迟。
精度与范围的权衡:在捕获模式下,TSCTR的计数时钟决定了时间戳的分辨率。时钟越快,分辨率越高,但计数器溢出也越快,限制了最大可测量间隔。你需要根据信号频率和测量范围来权衡。例如,测量100kHz的PWM(周期10us),系统时钟150MHz(计数周期6.67ns),则一个周期约对应1500个计数,分辨率足够。若要测量1Hz的信号(1秒),计数器需要计数1.5亿次,远超32位范围,此时必须使用预分频或软件扩展计数器。
抗干扰与滤波:在工业现场,输入信号可能伴有毛刺。ECCTL1中的PRESCALE(事件预分频)就是一个简单的数字滤波器。它要求输入边沿持续一定数量的时钟周期才被认定为有效事件。合理设置此值可以滤除高频噪声,但过高的值可能会滤掉合法的窄脉冲。需要根据实际信号质量进行调整。
eCAP模块的灵活性和强大功能,使其成为C2000系列DSP在实时控制领域的王牌外设之一。从简单的信号测量到复杂的多相PWM生成,只要理解了其内部状态机、寄存器配置逻辑以及影子寄存器、同步等核心机制,就能将它运用自如,为你的嵌入式控制系统提供精准可靠的“时间感知”与“信号生成”能力。希望这篇结合了手册原理与实战经验的解析,能帮助你少走弯路,更快地上手这个强大的工具。
