基于TI的F2833xD的捕获模块应用

  • 文章信息
  • 开发环境
  • 捕获模块简介
  • 详细代码
  • 维护日志

文章信息

撰写日期 2018.12.20
完稿日期 2018.12.20
最近维护 2019.07.14
本文作者 multimicro
联系方式 multimicro@qq.com
GitHub https://github.com/wifialan
本文地址 https://blog.csdn.net/multimicro/article/details/85112066

开发环境

环境说明 详细信息 备注信息
操作系统 Win10_x64
CCS版本 Code Composer Studio v8 官网地址
controlSUITE controlSUITE for C2000 MCUs 官网地址
F28335 硬汉F28335开发板(150MHz时钟频率)
欧姆龙E6B2编码器 E6B2-CWZ6C 1000 P/R

捕获模块简介

F28335的Ecap模块捕获过程如下

该定时器是捕获模块专用定时器,在设定好捕获事件后,每捕获一个事件,对应的各级捕获寄存器就会把时间记录在捕获寄存器里面,通过这些时间信息即可计算出速度信息。
Ecap模块中比较重要的寄存器

  • eCAP控制寄存器ECCTL1
    用于配置触发捕获事件的条件和对应的计数器(一共四级,详见程序注释)
  • eCAP控制寄存器ECCTL2
    用于配置eCAP的工作模式,包括进入中断的方式等
  • eCAP捕获寄存器eCAPx
    用于记录各级捕获事件发生时的时间
  • 其余寄存器在代码中查看其作用

对与F2837xD,其配置捕获模块的程序和F28335的程序完全一样,唯一的不同就是配置Ecap输入引脚方式不同,F28335有固定的Ecap输入引脚,而F2837xD的捕获输入因为加入了Crossbar(X-BAR)机制,使得配置输入引脚其他C2000系列DSP更加灵活,可以使用任何一个GPIO口作为捕获输入,在TI官方的F2837xD文档Technical Reference Manual上面可以看到如下配置捕获引脚的说明(P1955):

F2837xD配置捕获输入的GPIO口的程序就两行:

若想进一步了解X-BAR,参考上面提到的文档P1151页。


详细代码

/** ecap.c**  Created on: 2018年12月14日*      Author: multimicro*/#include "project.h"void InitECapture()
{InitECapture1();InitECapture2();InitECapture3();
}void InitECapture1()
{ECap1Regs.ECEINT.all = 0x0000;             // Disable all capture interruptsECap1Regs.ECCLR.all = 0xFFFF;              // Clear all CAP interrupt flagsECap1Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loadsECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped// Configure peripheral registersECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;      // 单次模式ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 eventsECap1Regs.ECCTL2.bit.SWSYNC = 1;            //同步所有的Ecap时钟//以下CAP1POL是配置捕获单元的极性/**      ____      ____      ____*     |    |    |    |    |    |* ____|    |____|    |____|    |____*     ↑    ↓    ↑    ↓*     A    B    C    D** */ECap1Regs.ECCTL1.bit.CAP1POL = 0;          // Rising edge  0ECap1Regs.ECCTL1.bit.CAP2POL = 1;          // Falling edge 1ECap1Regs.ECCTL1.bit.CAP3POL = 0;          // Rising edge  0ECap1Regs.ECCTL1.bit.CAP4POL = 1;          // Falling edge 1ECap1Regs.ECCTL1.bit.CTRRST1 = 0;          // 完成此次捕获后不重置计数器ECap1Regs.ECCTL1.bit.CTRRST2 = 0;          // 完成此次捕获后不重置计数器ECap1Regs.ECCTL1.bit.CTRRST3 = 0;          // 完成此次捕获后不重置计数器ECap1Regs.ECCTL1.bit.CTRRST4 = 1;          // 完成此次捕获后重置计数器ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;         // Enable sync inECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass throughECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture unitsECap1Regs.ECCTL2.bit.CAP_APWM = 0;          //工作在CAP捕获模式ECap1Regs.ECCTL2.bit.REARM = 1;            // arm one-shotECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
//    ECap1Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt//    ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
}void InitECapture2()
{ECap2Regs.ECEINT.all = 0x0000;             // Disable all capture interruptsECap2Regs.ECCLR.all = 0xFFFF;              // Clear all CAP interrupt flagsECap2Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loadsECap2Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped// Configure peripheral registersECap2Regs.ECCTL2.bit.CONT_ONESHT = 1;      // 单次模式ECap2Regs.ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 eventsECap2Regs.ECCTL2.bit.SWSYNC = 1;            //同步所有的Ecap时钟//以下CAP2POL是配置捕获单元的极性/**      ____      ____      ____*     |    |    |    |    |    |* ____|    |____|    |____|    |____*     ↑    ↓    ↑    ↓*     A    B    C    D** */ECap2Regs.ECCTL1.bit.CAP1POL = 0;          // Rising edge  0ECap2Regs.ECCTL1.bit.CAP2POL = 1;          // Falling edge 1ECap2Regs.ECCTL1.bit.CAP3POL = 0;          // Rising edge  0ECap2Regs.ECCTL1.bit.CAP4POL = 1;          // Falling edge 1ECap2Regs.ECCTL1.bit.CTRRST1 = 0;          // 完成此次捕获后不重置计数器ECap2Regs.ECCTL1.bit.CTRRST2 = 0;          // 完成此次捕获后不重置计数器ECap2Regs.ECCTL1.bit.CTRRST3 = 0;          // 完成此次捕获后不重置计数器ECap2Regs.ECCTL1.bit.CTRRST4 = 1;          // 完成此次捕获后重置计数器ECap2Regs.ECCTL2.bit.SYNCI_EN = 1;         // Enable sync inECap2Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass throughECap2Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture unitsECap2Regs.ECCTL2.bit.CAP_APWM = 0;          //工作在CAP捕获模式ECap2Regs.ECCTL2.bit.REARM = 1;            // arm one-shotECap2Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loads
//    ECap2Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt//    ECap2Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
}void InitECapture3()
{ECap3Regs.ECEINT.all = 0x0000;             // Disable all capture interruptsECap3Regs.ECCLR.all = 0xFFFF;              // Clear all CAP interrupt flagsECap3Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loadsECap3Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped// Configure peripheral registersECap3Regs.ECCTL2.bit.CONT_ONESHT = 0;      // 连续模式ECap3Regs.ECCTL2.bit.STOP_WRAP = 1;        // Stop at 2 eventsECap3Regs.ECCTL2.bit.SWSYNC = 1;            //同步所有的Ecap时钟//以下CAP3POL是配置捕获单元的极性/**        ________*       |        |*  _____|        |________________________*       ↑        ↓*       A        B** */ECap3Regs.ECCTL1.bit.CAP1POL = 0;          // Rising edge  0ECap3Regs.ECCTL1.bit.CAP2POL = 1;          // Falling edge 1ECap3Regs.ECCTL1.bit.CTRRST1 = 0;          // 完成此次捕获后不重置计数器ECap3Regs.ECCTL1.bit.CTRRST2 = 1;          // 完成此次捕获后重置计数器ECap3Regs.ECCTL2.bit.SYNCI_EN = 1;         // Enable sync inECap3Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass throughECap3Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture unitsECap3Regs.ECCTL2.bit.CAP_APWM = 0;          //工作在CAP捕获模式ECap3Regs.ECCTL2.bit.REARM = 1;            // arm one-shotECap3Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable CAP1-CAP4 register loadsECap3Regs.ECEINT.bit.CEVT2 = 1;            // 2 events = interruptECap3Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
}

/********************************************************************************************************  Ecap 的基准时钟在150MHz的主频下约为6.67ns*  也就是说每过6.67ns ECap1Regs.CAPx的值就会递增1,通过CAP1和CAP3的时间差可以计算出速度********************************************************************************************************  1. 该 E6B2-CWZ6C 的分辨率为 1000 P/R 即改编码器每转一圈,固定输出1000个脉冲*  2. 若1s内转一圈,则每个脉冲的周期为: 1s/1000 = 1ms (下图中A→C的时间 , 从  A → C 为一个完整的脉冲)*  3. 由 E6B2-CWZ6C 技术文档可知,输出一共有三相A、B、Z相输出,其中Z相为同步相*  4. 计算转速时只需要A相或者B相一个即可。但计算转动方向时,需要配合A相和B相,必须用到Z相,下面会解释**     ____      ____      ____      ____*         |    |    |    |    |    |    |*         |____|    |____|    |____|    |____*         ↓    ↑    ↓    ↑*         A    B    C    D**  当  A 事件(捕获第一个下降沿)发生时 Ecap模块把当前时间记录在 ECap1Regs.CAP1中*  当  B 事件(捕获第一个上升沿)发生时 Ecap模块把当前时间记录在 ECap1Regs.CAP2中*  当  C 事件(捕获第二个下降沿)发生时 Ecap模块把当前时间记录在 ECap1Regs.CAP3中*  当  D 事件(捕获第二个上升沿)发生时 Ecap模块把当前时间记录在 ECap1Regs.CAP4中********************************************************************************************************   下面说明一下正转和反转时的三相输出波形**   捕获器1和2配置的**   1. 正转(forward)*           _____       _____       _____*  A       |     |     |     |     |     |*     _____|     |_____|     |_____|     |_____...*          ↑     ↓     ↑     ↓*          A1    B1    C1    D1**      以下变量可在函数中查看*      A1: Ecap1_TS1*      C1: Ecap1_TS3*               _____       _____       _____*  B           |     |     |     |     |     |*       _______|     |_____|     |_____|     |_____...*              ↑     ↓     ↑     ↓*              A2    B2    C2    D2**      以下变量可在函数中查看*      A2: Ecap2_TS1*      B2: Ecap2_TS2**          ___________*  Z      |           |*    _____|           |____________________________...*         ↑           ↓*         A3          B3**      没用到Ecap3的计数寄存器**   2. 反转(backward)*   标注见上*             _____       _____       _____*  A         |     |     |     |     |     |*       _____|     |_____|     |_____|     |_____...*            ↑     ↓     ↑     ↓*            A1    B1    C1    D1*          _____       _____       _____*  B      |     |     |     |     |     |*     ____|     |_____|     |_____|     |_____...*                     ↑     ↓     ↑     ↓*                     A2    B2    C2    D2*          ___________*  Z      |           |*    _____|           |____________________________*         ↑           ↓*         A3          B3***    需要注意,此种状态捕获模块捕获 B 相的上升沿如上图所示,而不是同步信号到来时的第一个上升沿*    应该是因为延时的原因,不影响测向。**    同步相到来时,才会启动捕获模块1和2来捕获A相和B相的脉冲,捕获器完成一次捕获事件后就停止工作*    等待下一次的同步信号再一次启动捕获*/
__interrupt void ecap1_isr(void)
{// 参考链接:https://blog.csdn.net/chenjiayu938/article/details/81349866ecap1_count = (++ ecap1_count) % 5;Ecap1_TS1 = ECap1Regs.CAP1;Ecap1_TS3 = ECap1Regs.CAP3;calc_pulse = Ecap1_TS3 - Ecap1_TS1;// calc_time unit is millseconds// 因为计数器每6.67ns递增一次,所以 ( 一个脉冲时间间隔内的计数器数值 ÷ 6.67 ) 就是一个脉冲持续的时间(ns),然后在除以1000000就换算得到ms// 此编码器的分辨率为 1000 P/R 转一圈固定输出1000个脉冲,1s转一圈输出的脉冲周期为1ms,因此可用   ( 1(ms) / 当前的脉冲周期(ms) )  来求得转速(r/s)calc_time = calc_pulse * 667.0 / 100.0 / 1000000.0;speed = 1 / calc_time;if(ecap1_count == 3)//降低刷新率,减小中断内部开销{memset(speed_char,'\0',8);doubleTochar(speed,speed_char,2);        //将浮点型speed数值转化为char型,用于LCD显示strcat(speed_char," r/s");memset(lcd_second_line,'\0',20);strcat(lcd_second_line," Speed:");strcat(lcd_second_line,speed_char);             //在"Speed:"后增添速度信息 最终信息格式为 "Speed:xx.xx r/s"if (Direction_flag == FORWARD) {Display_LCD1602(" Dire:forward",lcd_second_line);   //LCD1206显示速度和方向信息} else {Display_LCD1602(" Dire:backward",lcd_second_line);   //LCD1206显示速度和方向信息}}ECap1Regs.ECCLR.bit.CEVT4 = 1;      //使能第四级捕获事件发生后进入中断ECap1Regs.ECCLR.bit.INT = 1;        //清除Ecap全局中断标志位ECap1Regs.ECCTL1.bit.CAPLDEN = 1;   //使能在捕获事件中加载CAP1-4寄存器事件// Acknowledge this interrupt to receive more interrupts from group 4PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}__interrupt void ecap2_isr(void)
{Ecap2_TS1 = ECap2Regs.CAP1;Ecap2_TS2 = ECap2Regs.CAP2;Ecap2_gap_A_B = Ecap2_TS1 - Ecap1_TS1;Ecap2_gap_pulse = Ecap2_TS2 - Ecap2_TS1;//判断方向if ( Ecap2_gap_A_B < Ecap2_gap_pulse) {Direction_flag = FORWARD;} else {Direction_flag = BACKWARD;}ECap2Regs.ECCLR.bit.CEVT4 = 1;ECap2Regs.ECCLR.bit.INT = 1;ECap2Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture units// Acknowledge this interrupt to receive more interrupts from group 4PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}__interrupt void ecap3_isr(void)
{if (Z_frist_flag == 0) {//Z相检测到同步信号,启动A相和B相的检测ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;//启动Ecap1定时器ECap2Regs.ECCTL2.bit.TSCTRSTOP = 1;//启动Ecap2定时器ECap1Regs.ECEINT.bit.CEVT4 = 1;// 4 events = interruptECap2Regs.ECEINT.bit.CEVT4 = 1;// 4 events = interruptZ_frist_flag = 1;} else {//同步开启Ecap1和Ecap2ECap1Regs.ECCTL2.bit.REARM = 1;ECap2Regs.ECCTL2.bit.REARM = 1;}ECap3Regs.ECCLR.bit.CEVT2 = 1;ECap3Regs.ECCLR.bit.INT = 1;ECap3Regs.ECCTL2.bit.REARM = 1;ECap3Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture units// Acknowledge this interrupt to receive more interrupts from group 4PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}

维护日志

维护日期 维护内容
2019.07.14 增加了F2837xD系列DSP上的配置捕获输入GPIO的介绍

TI-C2000-捕获模块ECAP应用-以欧姆龙E6B2-CWZ6C测速编码器为例相关推荐

  1. STM32应用开发实践教程:智能小车电机测速模块的应用开发

    3.4.1 任务分析 本任务要求设计一个可实现智能小车电机测速的应用程序,具体要点如下. ① 取一个电机作为测速对象. ② 支持按键控制,使用 4 个按键,功能描述如下:  Key1 控制电机正转, ...

  2. TI C2000系列TMS320F2837xD开发板(DSP+FPGA)硬件规格参数说明书

    前 言 本文档主要介绍TMS320F2837xD开发板硬件接口资源以及设计注意事项等内容. 它是基于TI C2000系列TMS320F2837xD双核C28x 32位浮点DSP + 紫光同创Logos ...

  3. 输入捕获模块的使用–超声波测距

    输入捕获模块的使用–超声波测距 @(MSP432P401R) 输入捕获的配置 基本默认即可 输入捕获的API的使用 参数 Capture_Mode即捕获模式,经实际测试,MSP432P401R只能使用 ...

  4. 第二季5:配置视频捕获模块(step3:VI模块)

    以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除. 前言 本文将详细介绍博文第二季3:sample_venc.c的整体分析提及的"配置视频捕获模块". 分析方法上,我们 ...

  5. 从零开始研发GPS接收机连载——6、捕获模块设计与验证

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 从零开始研发GPS接收机连载--6.捕获模块设计与验证 前言 数据位宽 捕获算法选择 捕获参数设计 FPGA实现的一些组成模块 上板测 ...

  6. dsp软件单元测试,TMS320F2812DSP捕获单元测速 图文精.docx

    基于TMS320F2812 DSP捕获单兀测速 相关专题: 电子应用 时间:2009-10-13 10:24 来源: icbuy 亿芯网 1引言 应用于高层建筑.银行.机场和油田等场合的柴油发电机组, ...

  7. [解疑][TI]TI毫米波雷达系列(三):调频连续波雷达回波信号3DFFT处理原理(测距、测速、测角)

    本文是经过参考多个文章并整理的,相关程序已经经过验证其可行性.在此感谢原文作者(文末有相关链接)的无私分享. 1.测距.测速 毫米波雷达测距主要是通过检测回波时延来计算目标距离:测速是通过检测目标运动 ...

  8. STM32定时器捕获编码器模式测速和方向测不准问题

    ** STM32定时器捕获编码器模式测速和方向测不准问题 问题概述 关于STM32编码器模式电机测速的资料网上一抓一大把,却发现真的拿过来用还是有问题的,比如刚刚做了个东西,是个个头比较大的麦克纳姆轮 ...

  9. PYTHON通过psutil模块实时监测cpu、内存、网速运行情况

    PYTHON通过psutil模块实时监测cpu.内存.网速运行情况 运行多线程以后,随着设置更多的线程数,运行效率并没提升,一定是遇到了瓶颈,到底是CPU.内存还是网速到了上限?做了个实时监测,看看多 ...

  10. STM32应用(二)测速模块、寻迹模块、数码管显示、TFT显示屏

    文章目录 1. Zave测速模块红外槽型光耦对射光电传感器码盘计数器 1.1 实物图和接线 1.2 模块特色 1.3 使用说明 2. TCRT5000红外反射光电开关 2.1 实物图和接线 2.2 功 ...

最新文章

  1. mysql为什么每天0点就装东西_MySQL的详细安装教程
  2. html5 颜色弹窗 位置,HTML5之placeholder属性以及如何更改placeholder属性中文字颜色大小位置...
  3. TypeError: Cannot read property 'gc' of undefined 使用百度地图报错
  4. 题目1550:分糖果
  5. android 跑分软件,跑分软件安兔兔公布了6月份Android手机性能榜TOP10
  6. 虚拟机中安装MAC OS X教程(适用所有电脑方法,特别是cpu不支持硬件虚拟化的电脑)...
  7. Python 内置方法和属性应用:反射和单例
  8. my06_sysbench install for mysql 并初始化表数据
  9. 【WebRTC---入门篇】(十九)TURN协议
  10. 【Hbase】HBase 更改表名
  11. Server SAN:弄潮儿云计算时代
  12. 关于解决miui10国际版刷入之后无法认证的问题
  13. 定义一个list对象数组 java_javascript定义一个list
  14. Python网络流量监视程序设计与实现
  15. 微信小程序跳转其他外部网站上
  16. 怎么开通企业邮箱客户端授权密码功能?
  17. 光伏并网逆变器设计方案,附有相关的matlab电路仿真文件,以及DSP的程序代码
  18. Hadoop实战(二) 搭建Hadoop集群
  19. 一张图看明白电信云解决方案架构
  20. 物体检测--HOG特征

热门文章

  1. 屏幕录制专家,如何上传到优酷的高清视频?
  2. 【JAVA笔记】JAVA调用同一个包里的不同类的方法:
  3. win10电脑亮度调节失灵(win10电脑亮度调节失灵戴尔)
  4. 泡泡一分钟:Perception-aware Receding Horizon Navigation for MAVs
  5. Excel VBA入门(6) - Worksheet对象常用方法事件
  6. Predicting mRNA Abundance Directly from Genomic Sequence Using Deep Convolutional Neural Networks
  7. 陈一舟:以前创业占地就行 现在要做游击队
  8. SAT数学解题方法总结
  9. Windows编程 Windows程序的生与死(上)
  10. Bootstrap3【上手教程】