• DSP28335学习记录(五)——eCAP、eQEP


    本文记录dsp28335的eCAP、eQEP的配置方法:


    目录

    一、eCAP

    1.1 APWM模式

    1.2 捕获模式

    二、eQEP

    2.1 正交解码单元(QDU) 

    2.2 位置计数器(PCCU)

    2.3 单元捕获单元(QCAP)及M、T法

    2.4 eQEP模块配置

    2.5 结果计算


    一、eCAP

    F28335 内含有 6 组 eCAP 模块。每个模块有两种模式:APWM,捕获模式。

    1.1 APWM模式

    如果 eCAP 模块不用作输入捕获,可以将它用来产生一个单通道的 PWM。计数 器工作在计数增模式,可以提供时基能产生不同占空比的 PWM。CAP1 与 CAP2 寄存器作为主要的周期和比较寄存器,CAP3 与 CAP4 寄存器作为周期和比较寄存器 的影子寄存器,其原理框图如下:

     28335中已经有6路增强PWM了,基本上用不上这个。主要还是用它的捕获功能。

    1.2 捕获模式

    先说一下CAP捕获功能的作用:测量信号的频率,占空比,脉冲时间长度等等。

    基本原理就是:内部一个时钟脉冲,捕获输入信号的边沿信号,触发事件来记录脉冲数来换算输入信号的高低电平时间长度。

    150MHz 系统时钟的情况下,32 位的时基的时间分辨率为 6.67ns,且32位计数器溢出需要28秒多,所以时钟不用分频,计数器完全够用。

    有4个时间标志寄存器(CAP1,CAP2,CAP3,CAP4),可以分别设置边沿信号的极性触发。

    这4个寄存器是轮流触发的事件触发的,对应4个沿的到来。

    触发事件到来时,寄存器存放的值是绝对时间,还是相对时间。这个要注意设置清楚。

    可以参考下这篇博客:增强型捕获模块(eCAP)

    例程,

    1. void eCAP1_Init(void)
    2. {
    3. EALLOW;
    4. SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
    5. EDIS;
    6. //GPIO初始化
    7. InitECap1Gpio();
    8. //ECAP1初始化
    9. ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
    10. ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
    11. ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
    12. ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
    13. //设置ecap
    14. ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // 1:单次触发 0:连续模式
    15. ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // 单次触发模式时,当4次捕获事件时,停止。连续模式时,继续
    16. ECap1Regs.ECCTL1.bit.CAP1POL = 1; // 上升沿捕获
    17. ECap1Regs.ECCTL1.bit.CAP2POL = 0; // 下升沿捕获
    18. ECap1Regs.ECCTL1.bit.CAP3POL = 1; // 上升沿捕获
    19. ECap1Regs.ECCTL1.bit.CAP4POL = 0; // 下升沿捕获
    20. ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // 1:相对时间模式;0:绝对时间模式
    21. ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // 1:相对时间模式;0:绝对时间模式
    22. ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // 1:相对时间模式;0:绝对时间模式
    23. ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // 1:相对时间模式;0:绝对时间模式
    24. ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // 使能同步模式
    25. ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // 选择同步输入事件为同步信号输出
    26. ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // 使能计数器加载
    27. ECap1Regs.ECCTL1.bit.PRESCALE = 0; // 输入信号1分频,1-62分频
    28. ECap1Regs.ECCTL1.bit.FREE_SOFT = 0; // 仿真模式。仿真暂停,计数器暂停
    29. ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // 启动计数器
    30. ECap1Regs.ECCTL2.bit.REARM = 1; // 单次重加载
    31. // ECap1Regs.ECEINT.bit.CEVT1 = 1; // 当CAP1发生捕获事件,发生中断
    32. // ECap1Regs.ECEINT.bit.CEVT2 = 1; // 当CAP2发生捕获事件,发生中断
    33. // ECap1Regs.ECEINT.bit.CEVT3 = 1; // 当CAP3发生捕获事件,发生中断
    34. ECap1Regs.ECEINT.bit.CEVT4 = 1; // 当CAP4发生捕获事件,发生中断
    35. // ECap1Regs.ECEINT.bit.CTROVF = 1; // 当计数器溢出,发生中断
    36. EALLOW;
    37. PieVectTable.ECAP1_INT = &ecap1_isr; //中断地址重映射
    38. EDIS;
    39. IER |= M_INT4;
    40. PieCtrlRegs.PIEIER4.bit.INTx1 = 1; //PIE通道使能
    41. // Enable global Interrupts and higher priority real-time debug events:
    42. EINT; // Enable Global interrupt INTM
    43. ERTM; // Enable Global realtime interrupt DBGM
    44. }
    45. __interrupt void ecap1_isr(void)
    46. {
    47. //32位计数器,150M系统时钟的情况下,计数器溢出是28.633115s,
    48. //就是这么豪横。一般不用担心溢出的事情.
    49. // if(ECap1Regs.ECFLG.bit.CTROVF == 1) //计数器溢出进入中断
    50. // {
    51. //
    52. // }
    53. Uint32 HighTimer = ECap1Regs.CAP1; //相对时间模式下,CAP1上升沿触发,所以存放的是上升沿后的高电平持续脉冲个数。
    54. Uint32 LowTimer = ECap1Regs.CAP2; //相对时间模式下,CAP2下降沿触发,所以存放的是下降沿后的低电平持续脉冲个数。
    55. if(ECap1Regs.ECFLG.bit.CEVT4 == 1) //捕获事件4进入中断
    56. {
    57. //占空比
    58. eCAP1Result.Duty = (float)(HighTimer) /
    59. (float)(LowTimer + HighTimer);
    60. //频率
    61. eCAP1Result.Frequency = (float)150000000 / (float)(HighTimer + LowTimer);
    62. //完成标志位
    63. eCAP1Result.CompleteFlag = 1;
    64. }
    65. // ECap1Regs.ECCLR.bit.CEVT1 = 1;
    66. // ECap1Regs.ECCLR.bit.CEVT2 = 1;
    67. // ECap1Regs.ECCLR.bit.CEVT3 = 1;
    68. ECap1Regs.ECCLR.bit.CEVT4 = 1;
    69. // ECap1Regs.ECCLR.bit.CTROVF = 1;
    70. ECap1Regs.ECCLR.bit.INT = 1;
    71. ECap1Regs.ECCTL2.bit.REARM = 1;
    72. // Acknowledge this interrupt to receive more interrupts from group 4
    73. PieCtrlRegs.PIEACK.bit.ACK4 = 1;
    74. }

    二、eQEP

    正交解码模块,主要是解码下图这种光电编码器的信号的。

    光电编码器原理很简单,码盘转动时,边沿小孔会断断续续的透过光,两路受光元件放置间隔一段距离,所以他俩的信号有相位差,目前编码器上设置的差90度,也固定就是差1/4周期。

    码盘转动方向会造成AB两路的超前滞后不同。所以,我们可以通过AB超前滞后判断方向,脉冲宽度判断速度。

    另外,一般除了AB两路信号,还有两路:

    • I信号(有时叫z信号,索引信号):表示绝对起始位置信号。一周一个脉冲。
    • S信号 :选通信号,通常是限位开关的输出。

    eQEP 主要包含以下几个功能单元:

    --通过 GPIO MUX 寄存器编程锁定 QEPA 或者 QEPB 功能。

    --正交解码单元(QDU)。

    --位置计数器和位置计算控制单元(PCCU)。

    --正交边沿捕获单元,用于低速测量(QCAP)。

    --用于速度/频率测量的时基单元(UTIME)。

    --用于检测的看门狗模块。

    2.1 正交解码单元(QDU) 

    在正交-计数模式下,正交解码器产生方向信号和时钟信号送给位置计数器。 通过确定 QEPA 和 QEPB 两个脉冲信号哪一个超前,来解码出旋转方向逻辑, 并且将此方向逻辑更新到 QEPSTS 的 QDF 位。下图是方向解码逻辑的真值表以及 状态机。

    2.2 位置计数器(PCCU)

    可以配置为如下几种模式:

    --在索引事件到来时,位置计数器复位。

    --在计数值达到设定的最大值时,位置计数器复位。

    --第一个索引事件到来时,位置计数器复位。 -

    -在定时事件到达时,位置计数器复位。

    上述所有的操作模式,位置计数器都会在上溢时复位到 0,在下溢时复位到 QPOSMAX 最大值。

    2.3 单元捕获单元(QCAP)及M、T法

    有4个模块 :

    • 单位定时器:提供单位时间段
    • 系统分频时基信号:计数用的时钟脉冲,可设置分频。
    • 正交解码输出的边沿信号:编码器AB信号一周期4个边沿,可设置分频。
    • 捕获计数模块:计数模块。

    注意,和eCAP模块不同,这个计数器是16位,最大65535。时钟150M不分频,436.9us就会溢出。所以通常需要分频。

    1,T 法

    具体工作过程如下: 捕获时钟(QCTMR)以系统时钟分频后的时基作基准运行,在每个单位位置 事件发生时,QCTMR 的值会自动加载到捕获周期寄存器 QCPRD 中,之后捕获时钟 自动清零,同时 QEPSTS 中的 UPEVNT 标志位会置 1,表明有新值锁存到 QCPRD 寄 存器,通知 CPU 进行操作。下图为低速速度测量的时序,此种测量方式,只有在 下面两个条件满足时才是正确的。

    条件 1:单元位置事件之间不能超过捕获时钟的最大值,不能超过 65535。

    条件 2:没有换向发生。

    如果上述条件不满足,定时器上溢时,捕获单元的错误标志位 QEPSTS[COEF] 会置 1,如果两个单元位置事件发生方向变化,则状态寄存器 QEPSTS[COEF]错误标识被置位。所以该种方式只适用于低速的时候。

    2,M 法

    捕获时钟寄存器和捕获周期寄存器可以配置成如下事件发生时,会把值锁存 到 QCTMRLAT 和 QPPRDLAT 中。

    事件 1:CPU 读 QPOSCNT 寄存器时。

    事件 2:单位时间事件发生时。

    如果 QEPCTL[QCLM]位被清零了,那么当 CPU 读取位置计数器时,捕获时钟和 捕获周期寄存器的值分别被锁存到 QCTMRLAT 和 QPPRDLAT 寄存器中。EQEP 边沿 捕获单元时序图如下

     如果 QEPCTL[QCLM]位置 1,那么当单位时间事件发生时,位置计数器、捕获 时钟寄存器和捕获周期寄存器的值分别锁存到 QPOSLAT、QCTMRLAT 和 QCPRDLAT 中。

    3,M/T法

    结合以上两种的优点。

    简单的说:

    • T法就是测量一个A/B脉冲的周期,有多少个时钟脉冲。
    • M法就是测量一个固定(单位)时间段内,有几个周期的A/B信号。
    • M/T法就是测量个固定(单位)时间段内,有多少个时钟脉冲,有几个周期的A/B信号。

    M/T法的优点可以同时满足高速,低速。

    当然适用范围仍然是,高速不能超过时钟频率,低速不能低于单位时间段。否则误差将非常大。

    公式:

    其中,

    m1:单位时间内,AB信号个数,

    m2:单位时间内,时钟脉冲个数,

    P:编码器一周输出AB脉冲个数,

    fc:时钟脉冲频率。

    解释:m1/P是单位时间内,编码器转的圈数;fc/m2是一秒有多少个单位时间;相乘就是一秒转几圈,乘60就是一分钟转几圈。

    2.4 eQEP模块配置

    需要配置的有:

    1,单位定时器

    2,正交解码模块模式

    3,位置计数器

            3.1 复位模式

            3.2 最大位置

            3.3 单位定时器使能

            3.4 位置锁存模式

    4,边沿捕获

            4.1 时基脉冲分频

            4.2 边沿脉冲分频

            4.3 捕获使能

    例程,

    1. #if (CPU_FRQ_150MHZ)
    2. EQep1Regs.QUPRD=1500000; // Unit Timer for 100Hz at 150 MHz SYSCLKOUT
    3. #endif
    4. #if (CPU_FRQ_100MHZ)
    5. EQep1Regs.QUPRD=1000000; // Unit Timer for 100Hz at 100 MHz SYSCLKOUT
    6. #endif
    7. //正交解码模块
    8. EQep1Regs.QDECCTL.bit.QSRC=00; // 正交计数模式
    9. //位置计数模块
    10. EQep1Regs.QEPCTL.bit.FREE_SOFT=2; //软件仿真,仿真暂停,计数不停
    11. EQep1Regs.QEPCTL.bit.PCRM=00; //模式1: 索引事件触发,计数器复位
    12. EQep1Regs.QEPCTL.bit.UTE=1; //单位定时器使能
    13. EQep1Regs.QEPCTL.bit.QCLM=1; // 当单位时间事件发生,锁存
    14. EQep1Regs.QPOSMAX=0xffffffff; //最大位置
    15. EQep1Regs.QEPCTL.bit.QPEN=1; // QEP 使能
    16. //边沿捕获模块
    17. EQep1Regs.QCAPCTL.bit.UPPS=5; // 正交解码器输出的AB边沿脉冲 QCLK/32 分频。
    18. EQep1Regs.QCAPCTL.bit.CCPS=7; // 单位时基脉冲 = 系统时钟/128 分频。
    19. EQep1Regs.QCAPCTL.bit.CEN=1; // QEP 捕获使能

    2.5 结果计算

    结果在哪里?再看一下框图:LAT结尾就是锁存器,当事件到来会把计数结果记录进去。

     

     其中,

    QPOSLAT:事件触发锁存当前的位置数,

    QPOSSLAT:选通事件触发锁存当前的位置数,

    QPOSILAT:索引事件触发锁存当前的位置数,

    QCPRDLAT:事件触发锁存当前的时钟数,且计数器复位。

    例如要测速,用M/T法:

    单位事件内,

    m1 就是QPOSLAT当前值 - QPOSLAT前一个值。

    m2 就是QCPRDLAT。

    P值和编码器有关,fc就是边沿捕获模块的时基脉冲频率,这两个是常数。

    暂告一段落吧。

    通信协议I2C, SPI 等等后面再整吧。

  • 相关阅读:
    Control的Invoke和BeginInvoke
    企业为什么要选择通配符SSL证书使用?
    HWSD数据处理
    掌握Python爬虫实现网站关键词扩展提升曝光率
    Java8 list.stream()操作使用心得
    Apache Doris支持的数据类型详解
    Windows下安装Redis服务
    【CSS】自定义进度条
    MobileViT——论文简述
    unity-多线程异步下载HttpWebRequest
  • 原文地址:https://blog.csdn.net/qq_30835339/article/details/125492408