本帖最后由 dffzh 于 2025-3-26 15:22 编辑
#申请原创# @21小跑堂
雅特力MCU AT32F403ACCT7的部分定时器自带编码器模式,可以实现编码器的脉冲计数功能,比如使用定时器2 TMR2实现对编码器的脉冲计数功能。 编码器模式的内部结构如下:
编码器模式分类及BSP初始化配置如下:
编码器模式的计数方向如下:
配置过程: 1、 配置通道模式寄存器CM1的C1DF[7:4],设置通道1输入信号的滤波值; 配置通道模式寄存器CM1的C2DF[15:12],设置通道2输入信号的滤波值;
2、 配置通道控制寄存器CCTRL的C1P和C1CP,设置通道1输入信号的有效电平; 配置通道控制寄存器CCTRL的C2P和C2CP,设置通道2输入信号的有效电平;
3、 配置通道模式寄存器CM1的C1C[1:0],设置通道1为输入模式; 配置通道模式寄存器CM1的C2C[9:8],设置通道2为输入模式;
4、 配置次定时器控制寄存器STCTRL的SMSEL[2:0],选择编码器模式; 选择哪种编码器模式是配置的重点: 经过竞品分析和确认,项目上需选择4倍频模式,即选择编码模式C; 5、配置寄存器PR的PR[15:0],设置计数器计数周期;开启增强模式,PR值扩展至32位; 配置寄存器DIV的DIV[15:0],设置计数器计数周期;
6、 配置定时器2的增强模式,将PR值扩展至32位;
7、 配置TMR2_CH1和TMR2_CH2对应的IO为复用模式; 但是看官方库里配置的是普通输入模式;
8、 配置CTRL1寄存器的TMREN,使能计数器; 脉冲计数: 在main程序里循环调用以下接口即可读取到脉冲值: 返回值类型是一个 32位无符号整型数据,那如何与项目产品需求规格对应上呢? 比如需求规格为计数器范围[-2147483648, 2147483647],而脉冲读取接口返回值范围为[0, 4294967295],则可以直接按如下代码操作即可: int32_tencoder_pulse_data = tmr_counter_value_get(TRM2); encoder_pulse_data即为脉冲计数值,即: [0,2147483647] 对应 [0,2147483647]; [2147483648,4294967295] 对应 [-2147483648,-1]; 合在一起,其实就是一个环形计数器。
当然还有其他实现编码器脉冲读取的方法,如下所示:
1、IO查询法;速度太慢,会丢脉冲; 2、外部中断法;丢包概率较低,但频繁的中断触发会比较占用CPU资源; 以下简要介绍使用外部中断法实现编码器脉冲计数,供参考: 脉冲向上计数和向下计数的逻辑如下表所示: 中断触发源 | | | | | | | | | | | A相触发中断:AB相不同电平则向上,同电平向下; B相触发中断:正好相反 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
中断实现的代码如下,其中encoder_pulse_data即为脉冲计数值:
综上所述,优先使用定时器的编码器模式实现脉冲读取功能,如果MCU资源有限,则可以考虑使用外部中断法。
|
使用AT32F403ACCT7定时器的正交编码功能,实现增量式编码器的脉冲计数功能。