MSPM0系列外设 TIMER——Compare mode 编码器模式的使用 编码器测速
文章目录
思考 讨论
开两个TIMER 分别捕捉 AB 相
但是 一个向上计数从0 一个向下计数从65536
(10) 0 + (10) 65536 = (2)1<<16 (溢出但是等于零 在 16bit变量)
(10) 1 + (10) 65535 = (2)1<<16 (溢出但是等于零 在 16bit变量)
(10) 2 + (10) 65535 = (2) 1<<16 + 1<<0 = (int16_t) +1 ( 16bit 变量中 ) (A相领先相位 多一个pulse )
(10) 1 + (10) 65534 = (2) 0<<0 = (int16_t) -1 ( 16bit 变量中 ) (B相领先相位 多一个pulse )
不用中断 也能实现 判断正反转
只要将两相的值相加 ==溢出了也无所谓 (就是要溢出) == 放进一个有符号变量中
这一步和 stm32 强制(short)类型转换获取正反转 一个思路但是会有0的情况出现没必要的误差
如果能够在任意AB相捕获到一个边沿时再做判断 可以消除这个误差
有想法的能发邮件联系我吗 我的邮箱在评论区 和你的讨论我会感到很愉悦
(有兴趣的可以去了解)
(stm32 编码器模式 强制(short)类型转换获取正反转 )
(符号同模原反补码)
前言
(搞不懂本文原理的就直接照抄 只允许修改 Number of Edges to detect 那一参数 在sysconfig中)
MSPM0系列有着丰富的外设但是不像STM32一样有着编码器接口
本文提出一种全新的编码器接口基于MSPM0开发但是不需要使用到QEI接口
利用TIMER的 COMPARE mode 边沿捕获计数 不需要像网上的使用外部中断来进行电机测速
对于使用者如果使用线数比较多的编码电机有着更强的处理能力 优化中断反复读取打断代码
如果有四个编码电机也是足够使用的
对于他的定时器资源 在COMPARE Mode 下 只能单通道捕获
一、硬件
同样需要 AB phase 两根线
只不过一根测速 一根测正反转
原理就是利用相位 领先 或者 落后 的这一特性
还有就是利用定时器上升沿和下降沿捕获来计数
二、SYSCONFIG 配置
一、TIMER 配置
如图配置TIMER COMPARE MODE
(线数高的电机记得开高一点)
Number of Edges to Detect 可以自行选择数量根据编码电机线数自行调整
不要调太大尽量小一点如果线数少 要让中断能够触发才能判断正反转
意味着多少个脉冲捕获进入中断
Count up 选择 Load event 中断
Count down 选择 Zero event 中断
(搞不懂原理的照做)
(不能开 both edges to detect 在 Edge Detection Mode 要么 Raising 或者 Falling)
关闭 Enable Input Giltch Filter 测速更准 (有特殊需求 自己调节的来使用)
二、GPIO 配置
如图配置GPIO INPUT MODE
引脚的选择看喜好和方便
三、代码
一、使能定时器比较中断
使能定时器比较中断
//使能比较中断
NVIC_EnableIRQ(COMPARE_0_INST_INT_IRQN);
二、启动定时器比较中断
启动定时器比较中断
强烈建议配置在PWM输出前面
//编码定时器
DL_TimerA_startCounter(COMPARE_0_INST);
三、找到对应的中断服务函数 和 IO 端口
找到对应的中断服务函数 和 IO 端口
/* Defines for COMPARE_0 */
#define COMPARE_0_INST (TIMA1)
#define COMPARE_0_INST_IRQHandler TIMA1_IRQHandler
#define COMPARE_0_INST_INT_IRQN (TIMA1_INT_IRQn)
/* GPIO defines for channel 0 */
#define GPIO_COMPARE_0_C0_PORT GPIOB
#define GPIO_COMPARE_0_C0_PIN DL_GPIO_PIN_0
#define GPIO_COMPARE_0_C0_IOMUX (IOMUX_PINCM12)
#define GPIO_COMPARE_0_C0_IOMUX_FUNC IOMUX_PINCM12_PF_TIMA1_CCP0
/* Port definition for Pin Group GPIO_ENCODER */
#define GPIO_ENCODER_PORT (GPIOB)
/* Defines for PIN_19: GPIOB.14 with pinCMx 31 on package pin 2 */
#define GPIO_ENCODER_PIN_19_PIN (DL_GPIO_PIN_14)
#define GPIO_ENCODER_PIN_19_IOMUX (IOMUX_PINCM31)
复写对应的中断服务函数
(对于复写这一概念有兴趣的可以去学习 weak 和 启动文件等知识)
关于正反转数字详细需要看你的实际情况
关键关键关键
(成型根本)
readpins这一函数的使用 利用 AB phase difference 当A触发上升沿时 B phase 处于高电平 或者 低电平来判断 电机正反转
(搞不懂readpins函数的用法的就照抄)
F 变量设置为全局变量
c 变量设置为全局变量
核心判断代码
正反转 还有 计数
void COMPARE_0_INST_IRQHandler(void)
{
switch (DL_TimerA_getPendingInterrupt(COMPARE_0_INST))
{
case DL_TIMERA_IIDX_LOAD:
c++;
if (!DL_GPIO_readPins(GPIO_ENCODER_PORT, GPIO_ENCODER_PIN_19_PIN))
{
// 反转
F = -1;
}
else
{
// 正转
F = 1;
}
break;
default:
break;
}
}
四、速度解算
data 变量设为全局变量
c 变量设为全局变量
now 变量设为全局变量
重点看 c * 10 如果 前面 SYSCONFIG 配置中 Number of Edges to detect 你修改了 10 改成那个值
可以 把 下面代码 放在定时器中定时读取
data = c * 10 ;
c=0;
data += TIMA1->COUNTERREGS.CTR;
TIMA1->COUNTERREGS.CTR=0;
if(F==-1)
{
now = data ;
now = - now;
}
else if(F==1)
{
now = data;
}
总结
以上就是今天要讲的内容,本文介绍了MSPM0系列外设 TIMER——Compare mode 编码器模式的一种全新的使用
方法。
我是辛尘大海