DSP_TMS320F28377D_eCAP学习笔记

news2024/11/21 0:37:57

博主学习eCAP的使用主要是用于处理霍尔传感器,计算电机的电角度以及角速度。首先还是看了点哔哩哔哩的学习视频。

eCAP介绍

脉冲量的输入是在数字控制系统中最常见的一类输入量,控制器专门设置了脉冲捕获模块 (eCAP)来处理脉冲量,通过脉冲捕获模块捕获脉冲量上升沿下降沿,进而可以计算脉冲的宽度和占空比,可以采用脉冲信号进行相关控制。

捕获单元模块能够捕获外部输入引脚的逻辑状态(电平的高或低、电平翻转时的上升沿或下降沿),并利用内部定时器对外部事件或者引脚状态变化进行处理。

典型应用如下:

        1.电机测速

        2.测量脉冲电平宽度

        3.测量一系列脉冲占空比和周期

        4.电流/电压传感器的PWM编码信号的解码

谈一点自己的理解: 比如,配置好了eCAP后,eCAP就有一个定时器在跑了,说白了有个计数器在按照固有的周期在递增的计数,然后当外部输入引脚有一个上升沿的时候,我们的捕获模块,就捕获了,这时候捕获模块会把这个定时器的计数器的值加载到捕获寄存器里面去了。同时,这是可以触发中断的。当第二次上升沿再来的时候,我们又可以捕获到,那两个捕获寄存器都存的是计数值。计数值可以定时器频率换算成时间。 我们用两个计数值之差就能算出两个上升沿之间的间隔时间。

图1

脉冲捕获基本原理

控制器给每个捕获单元模块都分配一个捕获引脚(注意:这个分配动作会在代码中体现哟),在捕获引脚上输入待测脉冲波形,捕获模块会捕获到指定捕获的逻辑状态,如图1中的下降沿,捕获单元记录下定时器的时间,两个下降沿间的时间差就是脉冲周期,同理也可以捕获脉冲的上升沿计算上升沿与下降沿之间的时间差就可以获得占空比,所以捕获单元可以用于测量脉冲周期以及脉冲的宽度。在一些数字脉冲测速场合,如电机的常见测速方法之一,在电机某个固定位置通过光电传感器发出一个脉冲,每周一个脉冲,两个脉冲之间的时间,就是电机的转速。在一些精确控制的场合中公一周当然不止发出一个脉冲,这取决于传感器(光电编码器)的选型与性能。

eCAP主要特性

F28335共有6组eCAP模块,每个eCAP不但具有捕获功能,而且还可用作PWM输出功能F28335捕获模块的主要特征如下:(F28377只会模块更多、功能更强)

  1. 150MHz系统时钟的情况下,32位时基的时间分辨率为6.67ns;(1/150MHz
  2. 4组32位的时间标志寄存器;(时间计数器
  3. 4级捕获事件序列,可以灵活配置捕获事件边沿极性;
  4. 四级触发事件均可以产生中断;
  5. 软件配置一次捕获可以最多得到4个捕获时间; (也即是有4级深度
  6. 可连续循环4级捕获;
  7. 绝对时间捕获;
  8. 不同模式的时间捕获:
  9. 所有捕获都发生在一个输入引脚上:
  10. 如果eCAP模块不作捕获使用,可以配置成一个单通道输出的PWM模式

eCAP模块中一个捕获通道完成一次捕获任务,需要以下关键资源

  1. 专用捕获输入引脚;
  2. 32位时基(计数器);
  3. 4*32位时间标签捕获寄存器;
  4. 4级序列器,与外部eCAP引脚的上升/下降沿同步;
  5. 4个事件可独立配置边沿极性;
  6. 输入捕获信号预定标 (2-62);
  7. 一个2位的比较寄存器,一次触发后可以捕获4个时间标签事件;
  8. 采用4级深度的循环缓冲器以进行连续捕获;
  9. 4个捕获事件中任意一个都可以产生中断。

值得关注的点

eCAP这部分可能最困惑的,就是对于4级深度的理解。首先当eCAP工作时,肯定会有个定时器会从0开始一直往上计数的。如果定时器的频率是150M,那么每个计数值代表的就是(1/150M)s。然后我们有4个捕获的深度。每一级捕获都可以设置边沿的极性(上升沿/下降沿)。

比如对于双极性-开关型的霍尔传感器,当S级靠近传感器正面的时候,霍尔传感器会产生一个上升沿并保持高电平,当N级靠近传感器正面的时候,霍尔会产生下降沿并保持低电平。 考虑电机是1极对的简单情况,如果电机一直不停的旋转的话, 霍尔传感器对eCAP产生如图2的输入波形。

图2 开关型霍尔传感器的波形

 

我们可以把eCAP捕获的4级深度的边沿极性分别配置成: 第一个是上升沿 第二个是下降沿 第三个是上升沿 第四个是下降沿。 当我们完成这4次捕获之后,实际上电机旋转了360°的机械角(若是N极对电机,则是旋转了360°/N的机械角)

咱们的eCAP模块会把这4个边沿信号对应的计数数值存到4个对应的CAP寄存器。 比如,CAP1 = 1000, CAP2 = 2000, CAP3 = 4000, CAP4 = 8000(说明速度在增加)。咱们可以用 T = (CAP3 – CAP1) *(1/150M)  |  T = (CAP4 – CAP2) *(1/150M)得到电机旋转1圈需要的时间,然后就可以 360°/T得到转速了。 根据上面举例的CAP寄存器计数值易知了两种计算转速的方式算出来的速度是不一样的。

当然我们也可以用   T =  (CAP2 – CAP1) *(1/150M) | T =  (CAP3 – CAP2) *(1/150M) | T =  (CAP4 – CAP3) *(1/150M), 然后180°/T得到速度,这样做的好处是分辨率更高。

我们算速度就是用旋转过的角度除以所用的时间。 旋转过的角度越小,分辨率越高。 比如我电机是10极对,那么我们每次计算速度的时候转过的角度是 360°/10/2 = 18°,也就是每旋转18°就能计算一次角速度。

但! 第二种分辨率更高的计算方式的前提是霍尔传感器的方波高低电平所对应的机械角度占空比一致。不幸的是,我们这个电机他就不是一致的(前辈讲的),那就不能使用上面说的第二种计算速度的方式了。

eCAP可以设置在这4级捕获的每一级都进入中断, 我们可以在每一级都进入中断,根据中断标志位可判断是从哪一级捕获进入的中断。

eCAP配置(上代码了)

eCAP配置主要包含 3个方面。

引脚复用配置

 正式配置之前,我们首先参考一下官方样例提供的代码

    /* Reference code
     *
     * Example ecap_capture_pwm_cpu01's eCAP GPIO initialization code:
     *
     * InitECap1Gpio(19);
     * GPIO_SetupPinOptions(19, GPIO_INPUT, GPIO_ASYNC);
     *
     * Definition of InitECap1Gpio
     *
     * void InitECap1Gpio(Uint16 pin)
     * {
     *      EALLOW;
     *      InputXbarRegs.INPUT7SELECT = pin;         // Set eCAP1 source to GPIO-pin
     *      EDIS;
     * }
     *
     */

参考代码中我们得知,配置引脚复用之前,我们需要配置InputXbarRegs这个寄存器来指定eCAP模块分配的引脚(在前文有讲相关的内容哟)

InputXbarRegs.INPUT7SELECT对应eCAP1指定的引脚编号

InputXbarRegs.INPUT8SELECT对应eCAP2指定的引脚编号

InputXbarRegs.INPUT9SELECT对应eCAP3指定的引脚编号

那么最终的引脚复用配置代码如下:

void ecap_gpio_init(void){

    /* Reference code
     *
     * Example ecap_capture_pwm_cpu01's eCAP GPIO initialization code:
     *
     * InitECap1Gpio(19);
     * GPIO_SetupPinOptions(19, GPIO_INPUT, GPIO_ASYNC);
     *
     * Definition of InitECap1Gpio
     *
     * void InitECap1Gpio(Uint16 pin)
     * {
     *      EALLOW;
     *      InputXbarRegs.INPUT7SELECT = pin;         // Set eCAP1 source to GPIO-pin
     *      EDIS;
     * }
     *
     */


    // Our eCAP initialization code
    EALLOW;
        InputXbarRegs.INPUT7SELECT          =   24;
        InputXbarRegs.INPUT8SELECT          =   25;
        InputXbarRegs.INPUT9SELECT          =   26;
    EDIS;

    EALLOW;

        // eCAP1
        GpioCtrlRegs.GPAPUD.bit.GPIO24      =   0;  //  使能上拉        0: Enables the Pull-Up
                                                    //              1: Disables the Pull-Up

        GpioCtrlRegs.GPAGMUX2.bit.GPIO24    =   0;  // 复用为GPIO  参考手册 Page 959
        GpioCtrlRegs.GPAMUX2.bit.GPIO24     =   0;  //              8.7 GPIO and Peripheral Muxing

        GpioCtrlRegs.GPADIR.bit.GPIO24      =   0;  // 方向配置输入   0: Configures pin as input
                                                    //              1: Configures pin as output.

        GpioCtrlRegs.GPACSEL4.bit.GPIO24    =   0;  // Selects which master's GPIODAT/SET/CLEAR/TOGGLE registers control this GPIO pin
                                                    // xx00: CPU1 selected
                                                    // xx01: CPU1.CLA1 selected
                                                    // xx10: CPU2 selected
                                                    // xx11: CPU2.CLA1 selected

        GpioCtrlRegs.GPAQSEL2.bit.GPIO24    =   3;  // 配置异步输入模式提升精度,example也是设置成GPIO_ASYNC(异步)
                                                    // Using synchronized inputs can help with noise immunity
                                                    // but will 【affect】 the eCAP's accuracy by ±2 cycles.
                                                    // 0,0 Sync
                                                    // 0,1 Qualification (3 samples)
                                                    // 1,0 Qualification (6 samples)
                                                    // 1,1 Async (no Sync or Qualification)

        // eCAP2
        GpioCtrlRegs.GPAPUD.bit.GPIO25      =   0;
        GpioCtrlRegs.GPAGMUX2.bit.GPIO25    =   0;
        GpioCtrlRegs.GPAMUX2.bit.GPIO25     =   0;
        GpioCtrlRegs.GPADIR.bit.GPIO25      =   0;
        GpioCtrlRegs.GPACSEL4.bit.GPIO25    =   0;
        GpioCtrlRegs.GPAQSEL2.bit.GPIO25    =   3;

        // eCAP3
        GpioCtrlRegs.GPAPUD.bit.GPIO26      =   0;
        GpioCtrlRegs.GPAGMUX2.bit.GPIO26    =   0;
        GpioCtrlRegs.GPAMUX2.bit.GPIO26     =   0;
        GpioCtrlRegs.GPADIR.bit.GPIO26      =   0;
        GpioCtrlRegs.GPACSEL4.bit.GPIO26    =   0;
        GpioCtrlRegs.GPAQSEL2.bit.GPIO26    =   3;

    EDIS;


}

寄存器的配置

void ecap_register_init(void){
    ECap1Regs.ECCTL1.bit.CAP1POL    = 1;        // 事件1上升沿    //0--上升沿    1--下降沿
    ECap1Regs.ECCTL1.bit.CAP2POL    = 0;        // 事件2下降沿
    ECap1Regs.ECCTL1.bit.CAP3POL    = 1;        // 事件3上升沿
    ECap1Regs.ECCTL1.bit.CAP4POL    = 0;        // 事件4下降沿

    ECap1Regs.ECCTL1.bit.CTRRST1    = 0;        // 捕获到事件清空计数器        //0--不清空计数器  1--清空计数器
    ECap1Regs.ECCTL1.bit.CTRRST2    = 0;        // 捕获到事件清空计数器
    ECap1Regs.ECCTL1.bit.CTRRST3    = 0;        // 捕获到事件清空计数器
    ECap1Regs.ECCTL1.bit.CTRRST4    = 0;        // 捕获到事件清空计数器

    ECap1Regs.ECCTL1.bit.CAPLDEN    = 1;        // 使能寄存器装载
    ECap1Regs.ECCTL1.bit.PRESCALE   = 0;        // 输入信号不分频
    ECap1Regs.ECCTL2.bit.CAP_APWM   = 0;        // 配置为捕获模式
    ECap1Regs.ECCTL2.bit.CONT_ONESHT    = 0;    // 连续计数模式
    ECap1Regs.ECCTL2.bit.SYNCO_SEL  = 2;    //
    ECap1Regs.ECCTL2.bit.SYNCI_EN   = 0;
    ECap1Regs.ECEINT.all            = 0x0000;   // stop all interrupt
    ECap1Regs.ECCLR.all             = 0xFFFF;   // clear all flag
    ECap1Regs.ECCTL2.bit.TSCTRSTOP  = 1;        // 时间戳计数器自由运行

    ECap1Regs.ECEINT.bit.CEVT1      = 1;        // Enable cevt1 interrupt
    // ECap1Regs.ECEINT.bit.CEVT2      = 1;        // Enable cevt2 interrupt
    ECap1Regs.ECEINT.bit.CEVT3      = 1;        // Enable cevt3 interrupt
    // ECap1Regs.ECEINT.bit.CEVT4      = 1;        // Enable cevt4 interrupt
    // ECap1Regs.ECEINT.bit.CTROVF     = 1;        // Enable Counter Overflow interrupt
    // CTROVF Counter Overflow Interrupt Enable
}

中断配置

void interrupt_init(void){
    DINT;
	EALLOW;         //设置中断入口函数
        PieVectTable.ECAP1_INT  =   &Ecap1Handler;
        PieVectTable.ECAP2_INT  =   &Ecap2Handler;
        PieVectTable.ECAP3_INT  =   &Ecap3Handler;
    EDIS;

    IER |=  M_INT4;

    PieCtrlRegs.PIEIER4.bit.INTx1   =   1;    //使能PIE中断   // ECAP1
    PieCtrlRegs.PIEIER4.bit.INTx2   =   1;    //使能PIE中断   // ECAP2
    PieCtrlRegs.PIEIER4.bit.INTx3   =   1;    //使能PIE中断   // ECAP3

    EINT;  // 使能全局中断
    ERTM;  // 使能实时仿真中断
}

中断处理函数

interrupt void Ecap1Handler(void)
{
    ECap1Regs.ECCLR.all     = 0xFFFF;       // Clear all flag
    PieCtrlRegs.PIEACK.all  = PIEACK_GROUP4;
}

interrupt void Ecap2Handler(void)
{
    ECap2Regs.ECCLR.all     = 0xFFFF;       // Clear all flag
    PieCtrlRegs.PIEACK.all  = PIEACK_GROUP4;
}

interrupt void Ecap3Handler(void)
{
    ECap3Regs.ECCLR.all     = 0xFFFF;       // Clear all flag
    PieCtrlRegs.PIEACK.all  = PIEACK_GROUP4;
}

感谢您的阅读,欢迎留言讨论、收藏、点赞、分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

路由器的工作原理(计算机网络-网络层)

目录 路由器的构成 转发和路由选择的区别 典型的路由器结构 交换结构 输出端口 路由器与交换机的比较 两种基于存储转发的分组交换设备的比较 交换机和路由器各有的应用场合 三层交换机 三层交换机的应用 路由器的构成 路由器的任务 路由器是一种具有多个输入端口和多…

MT8385 Android AB分区系统升级(命令模式)

AB系统分区升级使用的是update_engine,RecoverySystem 只适用于单分区的系统升级 1.解压开update.zip 可以查看到palyload的属性 2.使用ADB命令update_engine_client即可对AB分区进行升级 使用adb shell 命令进行升级 update_engine_client --payload xxx --update --header…

【TypeScript】TS类型声明(二)

🐱个人主页:不叫猫先生 🙋‍♂️作者简介:前端领域新星创作者、华为云享专家、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀! 💫系列专栏&#xff…

k8s HPA升级 KEDA 基于prometheus的数据指标进行弹性伸缩

说明:KEDA有啥用,相对HPA有啥优势。HPA针对于cpu,内存来进行弹性伸缩,有点不太精确。KEDA可以接入prometheus,根据prometheus的数据指标进行弹性伸缩,相比更加的精准实用。 安装k8s环境部署prometheus 创建ns&#xf…

【软件测试】那些35岁以上的测试人哪去了?

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 先根据大体年龄阶段…

B+树详解,一次就懂

⭐注意:不会直接讲 B树的结构,会从最简单的二叉树开始讲起来。如果认真看完,我想你对树类型的数据结构的理解又上了一个新的台阶。 ⭐如果有误,请大家指出。下文均是在B站学习的过程中,总结的笔记和心得体会 索引结构 …

四、网络层(五)IP组播

目录 5.1 组播的概念 5.2 IP组播的地址 5.3 因特网组管理协议(IGMP) 5.4 组播路由算法 5.1 组播的概念 为了更好地支持像视频会议这类一对多的通信,需要源主机一次发送的单个分组,能抵达用一个组地址标识的若干台目的主…

【老保姆教程】:Tesseract-OCR图片文字识别

文章目录🌟介绍一波🌟小安装🌟配置环境变量⭐️tesseract-ocr配置⭐️tessdata语言配置⭐️检测环境变量是否安装成功🌟语言包的配置使用🌟CMD命令框中进行图片识别操作⭐️举例一:识别数字⭐️举例二&…

@PostConstruct(重点,初始化加载)和@PreDestroy 注解

PostConstruct和PreDestroy 注解 PostConstruct和PreDestroy都是属于Bean生命周期的一部分; PostConstruct:在bean创建完成并且属性赋值完成之后来执行初始化方法,常用于:项目启动完成后的初始化操作,比如不经常变的Redis缓存Pr…

二、LVS的安装部署

LVS的安装部署LVS的安装部署一、LVS的安装1、yum安装2、源码包安装二、ipvsadm命令详解LVS 相关软件ipvsadm 命令ipvsadm 工具用法:防火墙标记LVS 持久连接三、部署LVS NAT1、LVS NAT模式注意事项2、实验环境3、部署RS1和RS2的nginx4、将RS1和RS2的网关配置为DR的内…

maven私服

分模块开发时,被引用的模块不可能拷来拷去,应该放在单位内部的某一个服务器上,这就是私服。这里使用nexus作为私服软件。 Nexus ● Nexus是Sonatype公司的一款maven私服产品 ●下载地址 Nexus安装、启动与配置 ● 解压即安装 ● 修改基…

我国登山鞋行业参与者越发广泛带来广阔潜在需求 女性市场值得期待

登山鞋属于户外运动鞋,是专门为爬山和旅行而设计制造的鞋子,具有防水性、防滑性、足部保护功能、耐用性等功能,其中防水性是现代登山鞋的首要功能。 资料来源:中国登山鞋行业发展趋势研究与未来投资分析报告(2022-2029…

StarRocks Join Reorder 源码解析

导读:欢迎来到 StarRocks 源码解析系列文章,我们将为你全方位揭晓 StarRocks 背后的技术原理和实践细节,助你逐步了解这款明星开源数据库产品。 本期 StarRocks 技术内幕将介绍 Join Reorder 算法如何找到最优解的原理。 背景介绍 多表 Join…

vue之watchEffect

在Options API中,我们可以通过watch选项来侦听data或者props的数据变化,当数据变化时执行某一些操作。 在Composition API中,我们可以使用watchEffect和watch来完成响应式数据的侦听。 watchEffect用于自动收集响应式数据的依赖,需…

Jmeter实现websocket协议接口测试

一.为了方便使用,首先将jmeter设置成中文,有两种方法: 1.在Jmeter界面进行设置,Options ->Choose Language ->Chinese(Simplified),这种方法在关闭jmeter重启后又会恢复成默认的英文,如果…

学习Python编程好找工作吗?

说起编程语言,不少人都会推荐学习Python,但很多人对Python不太了解,所以比较好奇“学习Python编程是否好找工作”,关于这个问题,小编通过下文为大家详细解答一下。 从市场情况来讲,Python职位比较多&…

阿里内部进阶学习SpringBoot+Vue全栈开发实战文档

前言 Spring 作为一个轻量级的容器,在JavaEE开发中得到了广泛的应用,但是Spring 的配置烦琐臃肿,在和各种第三方框架进行整合时代码量都非常大,并且整合的代码大多是重复的,为了使开发者能够快速上手Spring&#xff0…

105.(leaflet之家)leaflet态势标绘-聚集地修改

地图之家总目录(订阅之前请先查看该博客) 地图之家:cesium+leaflet+echart+地图数据+地图工具等相关内容的介绍 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html>…

Python函数总结

在Python中&#xff0c;函数是一个带有名字的代码块&#xff0c;可以被反复调用。函数可以帮助你组织和重用代码&#xff0c;使你的程序更整洁&#xff0c;更易于维护。本文将会深入探索Python的秘密 目录 定义函数 自定义函数 内置函数 函数式方程 高阶函数 函数标注 …

Linux5.4.0内存分配器核心代码解析

理论 伙伴系统 核心代码解析 __rmqueue_smallest函数 在zone的free_list上进行搜索,找到符合migratetype的、大小为order的空闲页面块 static __always_inline struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,int migratetype