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

标签: DSP  eCAP  28335  TI文档出错

简介

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

eCAP GPIO 结构体变量
1 5/24/34 ECap1Regs
2 7/25/37 ECap2Regs
3 9/26 ECap3Regs
4 11/27 ECap4Regs
5 3/48 ECap5Regs
6 1/49 ECap6Regs

对应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文件

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

  1. 32位时钟计数器
  2. 4个32位时钟标识寄存器(CAP1到CAP4):这是四个寄存器,用来储存捕获事件时钟值。只是寄存器的名称命名为CAP1到CAP4,不要和捕获通道混淆。
  3. 可以为4个捕获事件设定独立的边沿极性。
  4. 配置单词捕获和连续捕获功能。
  5. 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计数器
  1. mod4计数器(2bit位)在捕获事件触发时进行增计数。
  2. 在连续模式下,mod4计数模式为:0-1-2-3-0,捕获值会连续不断放入到CAP1到CAP4寄存器中。
  3. 在单次模式下,mod4计数模式默认为由1到3停止。即共发生4次捕获,分别存入CAP1到CAP4寄存器中。可以通过ECCTL2[STOP_WRAP]寄存器来修改捕获的次数。

在这里插入图片描述

中断控制

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

  1. CEVT1:CAP1发生捕获事件
  2. CETV2:CAP2发生捕获事件
  3. CETV3:CAP3发生捕获事件
  4. CETV4:CAP4发生捕获事件
  5. CNTOVF:计数器溢出事件
  6. CTR=PRD:计数器的值等于周期寄存器
  7. 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; //设置占空比

版权声明:本文为qq_17525633原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_17525633/article/details/103105049

智能推荐

【MySQL】第十篇:MySQL事务详解

事务是MySQL等关系型数据库区别于NoSQL的重要方面,是保证数据一致性的重要手段。本文将首先介绍MySQL事务相关的基础概念,然后介绍事务的ACID特性,并分析其实现原理。 一、基础概念 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个sql语句,这些语句要么都执行,要么都不执行。作为一个关系型数据库,MySQL支持事务,本文介绍基于MySQL5.6。 ...

Postman第十篇:自动获取token

Postman请求自动获取token 添加一个环境 1 添加登录接口 添加一个集合 添加需要token的请求 在刚创建的集合中添加的请求, Headers中都会自动添加 token, 如果token失效, 重新请求一下登录接口即可...

Linux内核之进程调度3:进程调度

1. 吞吐率和响应 吞吐:单位时间内做的有用功; 响应:低延迟。 吞吐追求的整个系统CPU做有用功,响应追求的是某个特定任务的延迟低; 1GHZ的CPU切换线程保存恢复现场约几个微妙级别,看似消耗不了太多时间,但是由于系统的局部性原理,会保存当前线程数据的缓存,切换线程会打乱局部性引起cache miss,而CPU访问cache速度远大于内存访问,这样综合看来上下文切换花销还是很大的。无用功占用较...

restful+ci框架 实践

restful架构: 是就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。具体理论请看我上一篇写的restful理论。本篇主要记录下关于restful的实践。 restful实践: 工具: 这次在ci框架+restful 主要文件: 在控制器中添加控制器类:Restful.php。 在头部包含REST_Controller.php文件并继承...

Configuration, ConfigurationProperties和EnableConfigurationProperties用法

最近刚刚解决了个错误,突然又发现这个类在spring容器中找不到, 于是我就加一个 @Component的注解,哈哈直接启动成功,那我如果吧这个注解去掉,加上一个@Configuration的注解呢,哈哈还是可以的,毕竟里面已经有这个@Component的注解了。所以我就整理下Configuration,ConfigurationProperties,EnableConfigurationProp...

猜你喜欢

备战蓝桥杯--贪心算法刷题整理5

翻硬币(贪心算法) 看了一下网上的题解,感觉挺强,网友的做题思想值得借鉴,这里分享一下网友的链接,同时再分享一下自己的解题方案 链接:https://blog.csdn.net/qq_34594236/article/details/60326782 题目描述: 小明正在玩一个“翻硬币”的游戏。 桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母...

部署高可用RabbitMQ

安装 准备工作 这里我们使用三个RabbitMQ节点: 开通端口(具体见官方文档): 安装ErLang和RabbitMQ Server 安装文档见:https://www.rabbitmq.com/install-rpm.html。 采用RPM包而不是Repo的安装命令如下(以下的版本号可根据实际情况修改): 安装管理插件 安装文档见:https://www.rabbitmq.com/manage...

Opencv常用代码总结

文章目录 读取显示图像 保存图片 查看图片信息 读取视频 截取部分图像数据 颜色通道提取、融合与保留 边界填充 数值计算 图像融合 图像阈值 图像平滑(降噪) 形态学-腐蚀操作 形态学-膨胀操作 开运算与闭运算 梯度运算 礼帽与黑帽 图像梯度 Sobel算子 Scharr算子 laplacian算子 Canny边缘检测 图像金字塔 高斯金字塔:向下采样(缩小) 高斯金字塔:向上采样(放大) 拉普拉...

Numpy实现LDA

LDA与PCA的区别如下表: LDA的原理如下: 代码实现如下,这里使用的a,b是Nx2的二维点集合,经过LDA后,二维的点变为一维。更高维度的也是可以做到的。函数里的dim是原始数据的维度,d是想要降到的维度。  初始的数据如下图,红色点和蓝色点代表不同的分类。 经过LDA后,投影的一维数值如下图所示。 可见LDA实现了降维,而且两种分类的间距较大,类内的散度较小。...

Java反射机制

相关类型:  java.lang.Class  java.lang.reflect.Constructor  java.lang.reflect.Field  java.lang.reflect.Method  java.lang.reflect.Modifier 作用:  1、反编译 .class –> .java&n...