F28335第十篇——增强型捕获模块(eCAP)

admin 5808 2025-05-28 02:08:41

简介

F28335共有6个独立的捕获通道,如下表:

eCAPGPIO结构体变量15/24/34ECap1Regs27/25/37ECap2Regs39/26ECap3Regs411/27ECap4Regs53/48ECap5Regs61/49ECap6Regs

对应CMD中地址分配为:

ECAP1 : origin = 0x006A00, length = 0x000020 /* Enhanced Capture 1 registers */

ECAP2 : origin = 0x006A20, length = 0x000020 /* Enhanced Capture 2 registers */

ECAP3 : origin = 0x006A40, length = 0x000020 /* Enhanced Capture 3 registers */

ECAP4 : origin = 0x006A60, length = 0x000020 /* Enhanced Capture 4 registers */

ECAP5 : origin = 0x006A80, length = 0x000020 /* Enhanced Capture 5 registers */

ECAP6 : origin = 0x006AA0, length = 0x000020 /* Enhanced Capture 6 registers */

关于CMD文件更多知识,可以参见——F28335第四篇——存储器及CMD文件

除此之外,每个捕获通道还具有以下资源:

32位时钟计数器4个32位时钟标识寄存器(CAP1到CAP4):这是四个寄存器,用来储存捕获事件时钟值。只是寄存器的名称命名为CAP1到CAP4,不要和捕获通道混淆。可以为4个捕获事件设定独立的边沿极性。配置单词捕获和连续捕获功能。4个捕获事件都可以触发中断。

eCAP可以工作在两种模式:

捕获模式:用于获取属于信号时间属性,例如,信号周期,占空比等。脉冲发生器模式(APWM):计数器只能工作在递增模式下,产生不对称的PWM波。加上ePWM模块的12路,F28335最多可以同时产生18路PWM波。

APWM模式

在APWM模式下,CAP1到CAP4分别用作:

CAP1:周期当前寄存器(Period active reg)CAP2:比较当前寄存器(Compare active reg)CAP3:周期映射寄存器(Period shadow reg)CAP4:比较映射寄存器(Compare shadow reg)

对CAP1及CAP2进行写操作,同样的内容也会被写入到CAP3和CAP4中。如果对CAP3或CAP4进行写操作,将会启动映射模式。

在初始化过程中,必须首先当前寄存器。在程序运行过程中,可以通过写入映射寄存器来修改占空比或PWM周期。

在APWM模式中,可触发两种中断事件:

CTR=PRD:计数器的值等于周期寄存器CTR=CMP:计数器的值等于比较寄存器

捕获模式

捕获模式分成单次捕获和连续捕获两种模式。可以通过ECCTL2[CONT/ONESHT]寄存器来选择模式类型。

32位时钟计数器及相位控制

直接由系统时钟SYSCLKOUT驱动。相位寄存器通过软件或者硬件的方式将多个eCAP模块计数器进行同步。

CAP1到CAP4寄存器

寄存器的输入端直接与32位时钟计数器相连。当捕获事件发生时,直接将时钟计数器的值装载入对应的CAP寄存器中。通过ECCTCL1[CAPLDEN]寄存器可以开启/禁止装载功能。

预分频

通过ECCTL1[PRESCALE]控制。一般选择不分频,以提高捕获精度。

边沿设定

可以分别将4个捕获事件配置成上升沿或者下降沿。在ECCTL1寄存器中设定。

MOD4计数器

mod4计数器(2bit位)在捕获事件触发时进行增计数。在连续模式下,mod4计数模式为:0-1-2-3-0,捕获值会连续不断放入到CAP1到CAP4寄存器中。在单次模式下,mod4计数模式默认为由1到3停止。即共发生4次捕获,分别存入CAP1到CAP4寄存器中。可以通过ECCTL2[STOP_WRAP]寄存器来修改捕获的次数。

中断控制

eCAP模块共可以产生7种中断事件:

CEVT1:CAP1发生捕获事件CETV2:CAP2发生捕获事件CETV3:CAP3发生捕获事件CETV4:CAP4发生捕获事件CNTOVF:计数器溢出事件CTR=PRD:计数器的值等于周期寄存器CTR=CMP:计数器的值等于比较计数器

其中,前5种工作在捕获模块,后2种工作在APWM模块。

寄存器

所有相关寄存器

struct ECAP_REGS

{

Uint32 TSCTR; // 时钟计数器:可读写,默认值0

Uint32 CTRPHS; //计数器相位寄存器:可读写,默认值0

Uint32 CAP1; // 捕获寄存器1:可读写,默认值0

Uint32 CAP2; // 捕获寄存器2:可读写,默认值0

Uint32 CAP3; // 捕获寄存器3:可读写,默认值0

Uint32 CAP4; // 捕获寄存器4:可读写,默认值0

Uint16 rsvd1[8]; // reserved

union ECCTL1_REG ECCTL1; // 捕获控制寄存器1

union ECCTL2_REG ECCTL2; // 捕获控制寄存器2

union ECEINT_REG ECEINT; // ECAP中断使能寄存器

union ECFLG_REG ECFLG; // ECAP中断标志寄存器

union ECFLG_REG ECCLR; // ECAP中断标志清除寄存器

union ECEINT_REG ECFRC; // ECAP中断强制寄存器(测试)

Uint16 rsvd2[6]; // reserved

};

ECCTL1

struct ECCTL1_BITS

{

Uint16 CAP1POL:1; // 0[R/W-0] 捕获事件1触发极性选择。0:上升沿触发,1:下降沿触发

Uint16 CTRRST1:1; // 1[R/W-0] 捕获事件1计数器复位控制。0:捕获发生不复位计数器(绝对时间模式),1:捕获发生复位计数器(相对时间模式)

Uint16 CAP2POL:1; // 2[R/W-0] 捕获事件2触发极性选择

Uint16 CTRRST2:1; // 3[R/W-0] 捕获事件2计数器复位控制

Uint16 CAP3POL:1; // 4[R/W-0] 捕获事件3触发极性选择

Uint16 CTRRST3:1; // 5[R/W-0] 捕获事件3计数器复位控制

Uint16 CAP4POL:1; // 6[R/W-0] 捕获事件4触发极性选择

Uint16 CTRRST4:1; // 7[R/W-0] 捕获事件4计数器复位控制

Uint16 CAPLDEN:1; // 8[R/W-0] 控制捕获事件发生时是否装载CAP1-CAP4。0:禁止装载,1:使能装载

Uint16 PRESCALE:5; // 13:9[R/W-0] 事件预分频控制位。0:不分频,0000-1111(k):2k分频

/*

* 仿真控制位。

* 00:仿真挂起时,TSCTR立即停止

* 01:仿真挂起时,TSCTR计数到0停止

* 1x:TSCTR不受影响

*/

Uint16 FREE_SOFT:2; //15:14[R/W-0]

};

ECCTL2

struct ECCTL2_BITS

{

Uint16 CONT_ONESHT:1; // 0[RW-0] 连续/单次捕获模式。0:连续模式,1:单次模式

/*

*00-11(k):

* 在单次模式下,捕获k+1次后停止。

* 在连续模式下,捕获k+1次后,mod4计数器归0。

* 总结:mod4计数器的最大值。即只使用到CAP(K+1)寄存器

*/

Uint16 STOP_WRAP:2; // 2:1[RW-11] 单次模式下停止值。

Uint16 REARM:1; // 3[RW-0] 重新装载控制位。0:无反应,1:将mod4复位到0,解冻mod4计数器,重新捕获

Uint16 TSCTRSTOP:1; // 4[RW-0] 时钟计数器使能。0:计数器停止;1:计数器继续计数

Uint16 SYNCI_EN:1; // 5[RW-0] 时钟计数器同步使能。0:禁止同步功能;1:使能同步功能

Uint16 SYNCO_SEL:2; // 7:6[RW-00] 同步输出使能。00:将SYNC_IN作为同步输出SYNC_OUT。

//01:CTR=PRD作为同步输出SYNC_OUT。1x:禁止同步输出

Uint16 SWSYNC:1; // 8[RW-0] 软件强制同步。0:无反应;1:产生一次强制同步信号

Uint16 CAP_APWM:1; // 9[RW-0] 工作模式选择。0:工作在铺货模式。1:工作在APWM模式。

Uint16 APWMPOL:1; // 10[RW-0] APWM输出极性选择。0:高电平有效。1:低电平有效

Uint16 rsvd1:5; // 15:11[R-0] 保留

};

ECINT

寄存器中除了保留位,所有都是可读写。0:禁止对应中断,1:使能对应中断。

struct ECEINT_BITS { // bits description

Uint16 rsvd1:1; // 0 reserved

Uint16 CEVT1:1; // 1 Capture Event 1 Interrupt Enable

Uint16 CEVT2:1; // 2 Capture Event 2 Interrupt Enable

Uint16 CEVT3:1; // 3 Capture Event 3 Interrupt Enable

Uint16 CEVT4:1; // 4 Capture Event 4 Interrupt Enable

Uint16 CTROVF:1; // 5 Counter Overflow Interrupt Enable

Uint16 CTR_EQ_PRD:1; // 6 Period Equal Interrupt Enable

Uint16 CTR_EQ_CMP:1; // 7 Compare Equal Interrupt Enable

Uint16 rsvd2:8; // 15:8 reserved

};

ECFLG

中断标志位。所有位都是只读的。0:无中断发生;1:有中断发生。

struct ECFLG_BITS { // bits description

Uint16 INT:1; // 0 Global Flag

Uint16 CEVT1:1; // 1 Capture Event 1 Interrupt Flag

Uint16 CEVT2:1; // 2 Capture Event 2 Interrupt Flag

Uint16 CEVT3:1; // 3 Capture Event 3 Interrupt Flag

Uint16 CEVT4:1; // 4 Capture Event 4 Interrupt Flag

Uint16 CTROVF:1; // 5 Counter Overflow Interrupt Flag

Uint16 CTR_EQ_PRD:1; // 6 Period Equal Interrupt Flag

Uint16 CTR_EQ_CMP:1; // 7 Compare Equal Interrupt Flag

Uint16 rsvd2:8; // 15:8 reserved

};

ECCLR

中断标志清除位。除了保留位,都是可读写。默认值为0。0:无反应,读取始终返回0;1:清除响应的中断标志位。寄存器位定义和ECFLG完全相同。

例程

功能

将eCAP1配置为APWM模式。输出PWM的频率为15K Hz,占空比为30%,并通过GPIO5输出。 将eCAP2配置为捕获模式。其中,CAP1和CAP3寄存器配置为上升沿捕获,CAP2和CAP4寄存器配置为下降沿捕获。使用绝对时间模式。使用GPIO25做为输入。 将GPIO5和GPIO25短接。通过eCAP2捕获eCAP1发出PWM波,获得每个PWM周期内的高电平与低电平时间。

源代码

主程序

/*

* main.c

*

* 主程序实现两种功能:

* 1.利用CAP模块发出PWM

* 2.利用CAP捕捉到PWM

*/

int main(void)

{

//1.系统初始化

InitSysCtrl();

//2.中断

//2.1关闭中断

DINT;

IER = 0x0000;

IFR = 0x0000;

InitPieCtrl();

InitPieVectTable();

//2.2开CAP2中断

EALLOW;

PieVectTable.ECAP2_INT = &IsrEcap2; //写入中断服务函数

EDIS;

PieCtrlRegs.PIECTRL.bit.ENPIE = 1; //使能PIE向量表

PieCtrlRegs.PIEIER4.bit.INTx2 = 1; //打开第四组第二个中断

IER |= M_INT4; //打开CPUj级第四组中断

EINT;//打开全局中断

//3.初始化GPIO

InitECap1Gpio(); //用于生成PWM波

InitECap2Gpio(); //用于捕捉PWM

//4.自定义功能

InitECap();

while (1);

}

GPIO初始化

void InitECap1Gpio(void)

{

EALLOW;

GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; //上拉电阻使能

GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; //系统时钟同步输入

GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3; //功能选择为eCAP1

EDIS;

}

void InitECap2Gpio(void)

{

EALLOW;

GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0; // 上拉电阻使能

GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 0; //系统时钟同步输入

GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 1; // 功能选择为eCAP2

EDIS;

}

eCAP功能初始化

void InitECap(void)

{

/*CAP1配置输出PWM波*/

ECap1Regs.ECCTL2.bit.CAP_APWM = 1; //工作在APWM模式

ECap1Regs.ECCTL2.bit.APWMPOL = 0; //高电平有效(比较值决定高电平的时间,先高后低)

ECap1Regs.ECCTL2.bit.SYNCI_EN = 0; //禁止同步功能

ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2; //禁止同步输出

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; //使能计数器开始计数

ECap1Regs.TSCTR = 0; //时钟清零

//设置周期和占空比

ECap1Regs.CAP1 = 10000; //PWM周期为10K个时钟周期

ECap1Regs.CAP2 = 3000; //设置占空比

/*CAP2配置计数PWM波*/

ECap2Regs.TSCTR = 0; //时钟清零

ECap2Regs.ECCTL1.bit.PRESCALE = 0; //计时器使用系统时钟,不分频

ECap2Regs.ECCTL1.bit.CAPLDEN = 1; //使能捕获装载CAP

ECap2Regs.ECCTL1.bit.CTRRST1 = 0; //绝对时间试

ECap2Regs.ECCTL1.bit.CTRRST2 = 0; //绝对时间试

ECap2Regs.ECCTL1.bit.CTRRST3 = 0; //绝对时间试

ECap2Regs.ECCTL1.bit.CTRRST4 = 0; //绝对时间试

ECap2Regs.ECCTL1.bit.CAP1POL = 0; //上升沿触发捕获

ECap2Regs.ECCTL1.bit.CAP2POL = 1; //下降沿触发捕获

ECap2Regs.ECCTL1.bit.CAP3POL = 0; //上升沿触发捕获

ECap2Regs.ECCTL1.bit.CAP4POL = 1; //下降沿触发捕获

ECap2Regs.ECCTL2.bit.CAP_APWM = 0; //工作在捕获模式

ECap2Regs.ECCTL2.bit.SYNCI_EN = 0; //禁止同步功能

ECap2Regs.ECCTL2.bit.SYNCO_SEL = 2; //禁止同步输出信号

ECap2Regs.ECCTL2.bit.CONT_ONESHT = 0; //工作在连续模式下

ECap2Regs.ECCTL2.bit.TSCTRSTOP = 1; //计数器开始计数

//中断控制

ECap2Regs.ECEINT.all = 0x10; //只打开CEVT4中断

}

中断服务程序

Uint32 t1, t2, t3, t4;

long T1, T2, T3, T4;

interrupt void IsrEcap2()

{

PieCtrlRegs.PIEACK.bit.ACK4 = 1; //第四组已经响应中断

ECap2Regs.ECCLR.all = 0xFFFF; //将所有中断清除

t1 = ECap2Regs.CAP1;

T4 = t1 - t4;//上一次的第二个低电平时间

t2 = ECap2Regs.CAP2;

t3 = ECap2Regs.CAP3;

t4 = ECap2Regs.CAP4;

T1 = t2 - t1;//本次第一个高电平时间

T2 = t3 - t2;//本次第二个低电平时间

T3 = t4 - t3;//本次第二个高电平时间

}

结果

注意

关于APWM配置时候,TI官方文档有一处有问题。我花了一整天才找到问题所在,所以才下了决心写这篇博客。 其中,配置程序中,先设置PWM的周期时间,再配置其他寄存器是错误的。

//错误写法

//=======================

// ECAP module 1 config

//先配置PWM周期

ECap1Regs.CAP1 = 0x1000; // Set period value

ECap1Regs.CTRPHS = 0x0; // make phase zero

//配置其他寄存器

ECap1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE;

ECap1Regs.ECCTL2.bit.APWMPOL = EC_ACTV_HI; // Active high

ECap1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE; // Synch not used

ECap1Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCO_DIS; // Synch not used

ECap1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN; // Allow TSCTR to run

正确的写法,应该是eCAP功能初始化中的设定方式。摘取如下:

/*CAP1配置输出PWM波*/

ECap1Regs.ECCTL2.bit.CAP_APWM = 1; //工作在APWM模式

ECap1Regs.ECCTL2.bit.APWMPOL = 0; //高电平有效(比较值决定高电平的时间,先高后低)

ECap1Regs.ECCTL2.bit.SYNCI_EN = 0; //禁止同步功能

ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2; //禁止同步输出

ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; //使能计数器开始计数

ECap1Regs.TSCTR = 0; //时钟清零

//设置PWM周期和占空比

ECap1Regs.CAP1 = 10000; //PWM周期为10K个时钟周期

ECap1Regs.CAP2 = 3000; //设置占空比

上一篇
下一篇
相关文章