dffzh 发表于 2025-3-20 16:08

使用定时器实现编码器脉冲计数功能

本帖最后由 dffzh 于 2025-3-26 15:22 编辑

#申请原创# @21小跑堂
雅特力MCU AT32F403ACCT7的部分定时器自带编码器模式,可以实现编码器的脉冲计数功能,比如使用定时器2 TMR2实现对编码器的脉冲计数功能。编码器模式的内部结构如下:
编码器模式分类及BSP初始化配置如下:

编码器模式的计数方向如下:
配置过程:1、 配置通道模式寄存器CM1的C1DF,设置通道1输入信号的滤波值;配置通道模式寄存器CM1的C2DF,设置通道2输入信号的滤波值;
2、 配置通道控制寄存器CCTRL的C1P和C1CP,设置通道1输入信号的有效电平;配置通道控制寄存器CCTRL的C2P和C2CP,设置通道2输入信号的有效电平;


3、 配置通道模式寄存器CM1的C1C,设置通道1为输入模式;配置通道模式寄存器CM1的C2C,设置通道2为输入模式;


4、 配置次定时器控制寄存器STCTRL的SMSEL,选择编码器模式;选择哪种编码器模式是配置的重点:经过竞品分析和确认,项目上需选择4倍频模式,即选择编码模式C;5、配置寄存器PR的PR,设置计数器计数周期;开启增强模式,PR值扩展至32位;配置寄存器DIV的DIV,设置计数器计数周期;

6、 配置定时器2的增强模式,将PR值扩展至32位;
7、 配置TMR2_CH1和TMR2_CH2对应的IO为复用模式;但是看官方库里配置的是普通输入模式;
8、 配置CTRL1寄存器的TMREN,使能计数器;脉冲计数:在main程序里循环调用以下接口即可读取到脉冲值:返回值类型是一个 32位无符号整型数据,那如何与项目产品需求规格对应上呢?比如需求规格为计数器范围[-2147483648, 2147483647],而脉冲读取接口返回值范围为,则可以直接按如下代码操作即可:int32_tencoder_pulse_data = tmr_counter_value_get(TRM2);encoder_pulse_data即为脉冲计数值,即: 对应 ; 对应 [-2147483648,-1];合在一起,其实就是一个环形计数器。


当然还有其他实现编码器脉冲读取的方法,如下所示:
1、IO查询法;速度太慢,会丢脉冲;2、外部中断法;丢包概率较低,但频繁的中断触发会比较占用CPU资源; 以下简要介绍使用外部中断法实现编码器脉冲计数,供参考:脉冲向上计数和向下计数的逻辑如下表所示:
中断触发源A相电平B相电平计数方向手轮转动方向备注
A相上升沿10向上正转A相触发中断:AB相不同电平则向上,同电平向下;B相触发中断:正好相反
1

1向下反转
A相下降沿00向下反转
01向上正转
B相上升沿01向下反转
11向上正转
B相下降沿00向上正转
10向下反转


中断实现的代码如下,其中encoder_pulse_data即为脉冲计数值:


综上所述,优先使用定时器的编码器模式实现脉冲读取功能,如果MCU资源有限,则可以考虑使用外部中断法。

dffzh 发表于 2025-3-20 16:21

@21小跑堂,申请原创,敬请审核。

电竞孔乙己 发表于 2025-3-20 20:37

这个实际运行的结果有没有,实现效果咋样。

我喜欢打游戏 发表于 2025-3-20 20:45

可以支持多高的采样率

qinlu123 发表于 2025-3-21 08:13

当年芯片荒的时候,推荐雅特力替代stm32,单片机确实不赖结果比stm32还难买,我现在还有几片雅特力的样片呢

绝影孤狼 发表于 2025-3-21 08:35

使能计数器后,脉冲计数的实时性如何保证呢

xionghaoyun 发表于 2025-3-21 08:50

给萌新的教程

dffzh 发表于 2025-3-21 09:12

我喜欢打游戏 发表于 2025-3-20 20:45
可以支持多高的采样率

我们的项目规格是支持最高输入频率为50KHz,脉冲输入方式是正交相位脉冲(x4).

dffzh 发表于 2025-3-21 09:15

电竞孔乙己 发表于 2025-3-20 20:37
这个实际运行的结果有没有,实现效果咋样。

我们应用在工业EtherCAT模块上,目前能满足项目规格最高输入频率50KHz.

dffzh 发表于 2025-3-21 09:18

绝影孤狼 发表于 2025-3-21 08:35
使能计数器后,脉冲计数的实时性如何保证呢

我们应用在工业EtherCAT总线模块上,对实时性要求较高(最低支持1ms周期),目前将其放在main里轮询调用,满足应用需求;或者可以再尝试使用两个外部中断检测脉冲的方式试试实时性效果.

dffzh 发表于 2025-3-21 09:21

xionghaoyun 发表于 2025-3-21 08:50
给萌新的教程

定时器的编码器模式驱动配置代码基本如下,可以参考一下:

dffzh 发表于 2025-3-21 09:23

qinlu123 发表于 2025-3-21 08:13
当年芯片荒的时候,推荐雅特力替代stm32,单片机确实不赖结果比stm32还难买,我现在还有几片雅特力的样片呢 ...

较STM32相比,雅特力的SPI外设使用起来稍微有些区别,需要注意.

jwdxu2009 发表于 2025-3-21 10:02

学习和参考,很适用,写的,交流,学习,参考应用,好机会

丙丁先生 发表于 2025-3-21 13:28

感谢分享。

穷得响叮当侠 发表于 2025-3-22 12:22

比如机器人、自动化设备等,这种定时器实现编码器脉冲计数的功能应该很有价值

dffzh 发表于 2025-3-23 11:52

穷得响叮当侠 发表于 2025-3-22 12:22
比如机器人、自动化设备等,这种定时器实现编码器脉冲计数的功能应该很有价值
...

是的,在工业自动化设备或者PLC设备上,可以得到应用。

作业天敌在此 发表于 2025-3-23 16:16

这个配置过程看起来挺复杂的,不过很详细

蚊子的噩梦 发表于 2025-3-23 17:10

将PR值扩展至32位,可以满足更大范围的计数需求

dffzh 发表于 2025-3-23 20:50

作业天敌在此 发表于 2025-3-23 16:16
这个配置过程看起来挺复杂的,不过很详细

是的,产品项目实测通过。

dffzh 发表于 2025-3-23 20:53

蚊子的噩梦 发表于 2025-3-23 17:10
将PR值扩展至32位,可以满足更大范围的计数需求

是的,我们使用环形计数器,计数范围是从﹣2147483648~2147483647
页: [1]
查看完整版本: 使用定时器实现编码器脉冲计数功能