本文记录dsp28335的eCAP、eQEP的配置方法:
目录
F28335 内含有 6 组 eCAP 模块。每个模块有两种模式:APWM,捕获模式。
如果 eCAP 模块不用作输入捕获,可以将它用来产生一个单通道的 PWM。计数 器工作在计数增模式,可以提供时基能产生不同占空比的 PWM。CAP1 与 CAP2 寄存器作为主要的周期和比较寄存器,CAP3 与 CAP4 寄存器作为周期和比较寄存器 的影子寄存器,其原理框图如下:
28335中已经有6路增强PWM了,基本上用不上这个。主要还是用它的捕获功能。
先说一下CAP捕获功能的作用:测量信号的频率,占空比,脉冲时间长度等等。
基本原理就是:内部一个时钟脉冲,捕获输入信号的边沿信号,触发事件来记录脉冲数来换算输入信号的高低电平时间长度。
150MHz 系统时钟的情况下,32 位的时基的时间分辨率为 6.67ns,且32位计数器溢出需要28秒多,所以时钟不用分频,计数器完全够用。
有4个时间标志寄存器(CAP1,CAP2,CAP3,CAP4),可以分别设置边沿信号的极性触发。
这4个寄存器是轮流触发的事件触发的,对应4个沿的到来。
触发事件到来时,寄存器存放的值是绝对时间,还是相对时间。这个要注意设置清楚。
可以参考下这篇博客:增强型捕获模块(eCAP)
例程,
- void eCAP1_Init(void)
- {
- EALLOW;
- SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
- EDIS;
-
-
- //GPIO初始化
- InitECap1Gpio();
-
- //ECAP1初始化
- ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
- ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
- ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
- ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
-
-
- //设置ecap
- ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // 1:单次触发 0:连续模式
- ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // 单次触发模式时,当4次捕获事件时,停止。连续模式时,继续
- ECap1Regs.ECCTL1.bit.CAP1POL = 1; // 上升沿捕获
- ECap1Regs.ECCTL1.bit.CAP2POL = 0; // 下升沿捕获
- ECap1Regs.ECCTL1.bit.CAP3POL = 1; // 上升沿捕获
- ECap1Regs.ECCTL1.bit.CAP4POL = 0; // 下升沿捕获
- ECap1Regs.ECCTL1.bit.CTRRST1 = 1; // 1:相对时间模式;0:绝对时间模式
- ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // 1:相对时间模式;0:绝对时间模式
- ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // 1:相对时间模式;0:绝对时间模式
- ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // 1:相对时间模式;0:绝对时间模式
- ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // 使能同步模式
- ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // 选择同步输入事件为同步信号输出
- ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // 使能计数器加载
- ECap1Regs.ECCTL1.bit.PRESCALE = 0; // 输入信号1分频,1-62分频
- ECap1Regs.ECCTL1.bit.FREE_SOFT = 0; // 仿真模式。仿真暂停,计数器暂停
-
-
- ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // 启动计数器
- ECap1Regs.ECCTL2.bit.REARM = 1; // 单次重加载
- // ECap1Regs.ECEINT.bit.CEVT1 = 1; // 当CAP1发生捕获事件,发生中断
- // ECap1Regs.ECEINT.bit.CEVT2 = 1; // 当CAP2发生捕获事件,发生中断
- // ECap1Regs.ECEINT.bit.CEVT3 = 1; // 当CAP3发生捕获事件,发生中断
- ECap1Regs.ECEINT.bit.CEVT4 = 1; // 当CAP4发生捕获事件,发生中断
- // ECap1Regs.ECEINT.bit.CTROVF = 1; // 当计数器溢出,发生中断
-
- EALLOW;
- PieVectTable.ECAP1_INT = &ecap1_isr; //中断地址重映射
- EDIS;
-
- IER |= M_INT4;
- PieCtrlRegs.PIEIER4.bit.INTx1 = 1; //PIE通道使能
-
- // Enable global Interrupts and higher priority real-time debug events:
- EINT; // Enable Global interrupt INTM
- ERTM; // Enable Global realtime interrupt DBGM
- }
-
-
-
-
-
- __interrupt void ecap1_isr(void)
- {
- //32位计数器,150M系统时钟的情况下,计数器溢出是28.633115s,
- //就是这么豪横。一般不用担心溢出的事情.
-
- // if(ECap1Regs.ECFLG.bit.CTROVF == 1) //计数器溢出进入中断
- // {
- //
- // }
-
- Uint32 HighTimer = ECap1Regs.CAP1; //相对时间模式下,CAP1上升沿触发,所以存放的是上升沿后的高电平持续脉冲个数。
- Uint32 LowTimer = ECap1Regs.CAP2; //相对时间模式下,CAP2下降沿触发,所以存放的是下降沿后的低电平持续脉冲个数。
-
-
- if(ECap1Regs.ECFLG.bit.CEVT4 == 1) //捕获事件4进入中断
- {
- //占空比
- eCAP1Result.Duty = (float)(HighTimer) /
- (float)(LowTimer + HighTimer);
- //频率
- eCAP1Result.Frequency = (float)150000000 / (float)(HighTimer + LowTimer);
- //完成标志位
- eCAP1Result.CompleteFlag = 1;
- }
-
-
-
-
-
- // ECap1Regs.ECCLR.bit.CEVT1 = 1;
- // ECap1Regs.ECCLR.bit.CEVT2 = 1;
- // ECap1Regs.ECCLR.bit.CEVT3 = 1;
- ECap1Regs.ECCLR.bit.CEVT4 = 1;
- // ECap1Regs.ECCLR.bit.CTROVF = 1;
- ECap1Regs.ECCLR.bit.INT = 1;
- ECap1Regs.ECCTL2.bit.REARM = 1;
-
- // Acknowledge this interrupt to receive more interrupts from group 4
- PieCtrlRegs.PIEACK.bit.ACK4 = 1;
- }
-
-
正交解码模块,主要是解码下图这种光电编码器的信号的。
光电编码器原理很简单,码盘转动时,边沿小孔会断断续续的透过光,两路受光元件放置间隔一段距离,所以他俩的信号有相位差,目前编码器上设置的差90度,也固定就是差1/4周期。
码盘转动方向会造成AB两路的超前滞后不同。所以,我们可以通过AB超前滞后判断方向,脉冲宽度判断速度。
另外,一般除了AB两路信号,还有两路:
eQEP 主要包含以下几个功能单元:
--通过 GPIO MUX 寄存器编程锁定 QEPA 或者 QEPB 功能。
--正交解码单元(QDU)。
--位置计数器和位置计算控制单元(PCCU)。
--正交边沿捕获单元,用于低速测量(QCAP)。
--用于速度/频率测量的时基单元(UTIME)。
--用于检测的看门狗模块。
在正交-计数模式下,正交解码器产生方向信号和时钟信号送给位置计数器。 通过确定 QEPA 和 QEPB 两个脉冲信号哪一个超前,来解码出旋转方向逻辑, 并且将此方向逻辑更新到 QEPSTS 的 QDF 位。下图是方向解码逻辑的真值表以及 状态机。
可以配置为如下几种模式:
--在索引事件到来时,位置计数器复位。
--在计数值达到设定的最大值时,位置计数器复位。
--第一个索引事件到来时,位置计数器复位。 -
-在定时事件到达时,位置计数器复位。
上述所有的操作模式,位置计数器都会在上溢时复位到 0,在下溢时复位到 QPOSMAX 最大值。
有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法
结合以上两种的优点。
简单的说:
M/T法的优点可以同时满足高速,低速。
当然适用范围仍然是,高速不能超过时钟频率,低速不能低于单位时间段。否则误差将非常大。
公式:
其中,
m1:单位时间内,AB信号个数,
m2:单位时间内,时钟脉冲个数,
P:编码器一周输出AB脉冲个数,
fc:时钟脉冲频率。
解释:m1/P是单位时间内,编码器转的圈数;fc/m2是一秒有多少个单位时间;相乘就是一秒转几圈,乘60就是一分钟转几圈。
需要配置的有:
1,单位定时器
2,正交解码模块模式
3,位置计数器
3.1 复位模式
3.2 最大位置
3.3 单位定时器使能
3.4 位置锁存模式
4,边沿捕获
4.1 时基脉冲分频
4.2 边沿脉冲分频
4.3 捕获使能
例程,
- #if (CPU_FRQ_150MHZ)
- EQep1Regs.QUPRD=1500000; // Unit Timer for 100Hz at 150 MHz SYSCLKOUT
- #endif
- #if (CPU_FRQ_100MHZ)
- EQep1Regs.QUPRD=1000000; // Unit Timer for 100Hz at 100 MHz SYSCLKOUT
- #endif
-
- //正交解码模块
- EQep1Regs.QDECCTL.bit.QSRC=00; // 正交计数模式
-
- //位置计数模块
- EQep1Regs.QEPCTL.bit.FREE_SOFT=2; //软件仿真,仿真暂停,计数不停
- EQep1Regs.QEPCTL.bit.PCRM=00; //模式1: 索引事件触发,计数器复位
- EQep1Regs.QEPCTL.bit.UTE=1; //单位定时器使能
- EQep1Regs.QEPCTL.bit.QCLM=1; // 当单位时间事件发生,锁存
- EQep1Regs.QPOSMAX=0xffffffff; //最大位置
- EQep1Regs.QEPCTL.bit.QPEN=1; // QEP 使能
-
- //边沿捕获模块
- EQep1Regs.QCAPCTL.bit.UPPS=5; // 正交解码器输出的AB边沿脉冲 QCLK/32 分频。
- EQep1Regs.QCAPCTL.bit.CCPS=7; // 单位时基脉冲 = 系统时钟/128 分频。
- EQep1Regs.QCAPCTL.bit.CEN=1; // QEP 捕获使能
结果在哪里?再看一下框图:LAT结尾就是锁存器,当事件到来会把计数结果记录进去。
其中,
QPOSLAT:事件触发锁存当前的位置数,
QPOSSLAT:选通事件触发锁存当前的位置数,
QPOSILAT:索引事件触发锁存当前的位置数,
QCPRDLAT:事件触发锁存当前的时钟数,且计数器复位。
例如要测速,用M/T法:
单位事件内,
m1 就是QPOSLAT当前值 - QPOSLAT前一个值。
m2 就是QCPRDLAT。
P值和编码器有关,fc就是边沿捕获模块的时基脉冲频率,这两个是常数。
暂告一段落吧。
通信协议I2C, SPI 等等后面再整吧。