GD32定时器正交译码器使用
前言
文章仅为个人学习记录或所遇到的问题记录,谢谢!
一、正交编码器描述
正交编码器可以用来获取速度或者方向信息,例如电机转动时,编码器输会出A,B方波信号,通过A,B信号可以获取电机转动的速度

二、GD32 定时器正交译码器功能描述
GD32一些定时器带有正交译码功能,具体哪些那些定时器带有这部分的功能,请查看对于的使用手册定时器章节的描述
1、带正交译码功能的定时器只能使用对应的定时器通道0和通道1来输入A,B信号
例如:TIMER1带有正交译码功能,则TIMER1_CH0和TIMER1_CH1作为连接A,B信号的通道,TIMER1_CH0和TIMER1_CH1分别对应手册上CI0FE0、CI1FE1。
2、正交译码器功能,支持3种计数模式

在编码器模式0下,定时器只在CI0FE0上升沿或下降沿向上或向下计数
在编码器模式1下,定时器只在CI1FE1上升沿或下降沿向上或向下计数
在编码器模式2下,定时器在CI0FE0和CI1FE1上升沿下降沿都进行计数
3、正交译码器支持输入的信号反相
可以通过设置TIMERx_CHCTL2的CHxP位设置对应信号是否反相
4、输入信号分析

标志1:CI0FE0出现上升沿,CI1FE1为0(低电平),向上计数
标志2:CI1FE1出现上升沿,CI0FE0为1(高电平),向上计数
标志3:CI0FE0出现下降沿,CI1FE1为1(高电平),向上计数
标志4:CI1FE1出现下降沿,CI0FE0为0(低电平),向上计数

对应关系如上图所示,其它情况都可按照表格关系进行推导
三、GD32 定时器正交译码器参考代码
#define ENCODER_TIMER_RCU RCU_TIMER1
#define ENCODER_TIMER TIMER1
#define TIMER_A_CH_RCU RCU_GPIOB
#define TIMER_B_CH_RCU RCU_GPIOB
#define TIMER_A_CH_PORT GPIOB
#define TIMER_B_CH_PORT GPIOB
#define TIMER_A_CH_PIN GPIO_PIN_8
#define TIMER_B_CH_PIN GPIO_PIN_9
//代码里面没有开启计数溢出中断,实际使用中,需要考虑计数溢出的情况
void timer_encoder_init_config(void)
{
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(ENCODER_TIMER_RCU);
rcu_periph_clock_enable(TIMER_A_CH_RCU);
rcu_periph_clock_enable(TIMER_B_CH_RCU);
gpio_af_set(TIMER_A_CH_PORT,GPIO_AF_1,TIMER_A_CH_PIN);
gpio_af_set(TIMER_B_CH_PORT,GPIO_AF_1,TIMER_B_CH_PIN);
gpio_mode_set(TIMER_A_CH_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,TIMER_A_CH_PIN);
gpio_mode_set(TIMER_B_CH_PORT,GPIO_MODE_AF,GPIO_PUPD_NONE,TIMER_B_CH_PIN);
gpio_output_options_set(TIMER_A_CH_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_25MHZ,TIMER_A_CH_PIN);
gpio_output_options_set(TIMER_B_CH_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_25MHZ,TIMER_B_CH_PIN);
timer_deinit(ENCODER_TIMER);
/* TIMER2 configuration */
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 65535;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(ENCODER_TIMER,&timer_initpara);
//TIMER_IC_POLARITY_RISING:信号不反相
//TIMER_IC_POLARITY_FALLING:信号反相
//timer_quadrature_decoder_mode_config函数的参数ic0polarity对应CI0FE0,ic1polarity对应CI1FE1
timer_quadrature_decoder_mode_config(ENCODER_TIMER,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_RISING);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(ENCODER_TIMER);
//设置初始计数值为0x50,用于判断计数个数和计数方向
timer_counter_value_config(ENCODER_TIMER,0x50);
/* TIMER2 counter enable */
timer_enable(ENCODER_TIMER);
}
四、代码测试
1、使用IO口模拟产生A,B信号,定时器初始值设置为0x50,CI0FE0、CI1FE1极性设置为不反相,可按照表格在编码器模式2的对应关系,可计算出计数方向向上,计数值为0x6C
timer_quadrature_decoder_mode_config(ENCODER_TIMER,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_RISING);

测试结果

2、使用IO口模拟产生A,B信号,定时器初始值设置为0x50,CI0FE0极性设置为反相,CI1FE1极性设置为不反相,可按照表格在编码器模式2的对应关系,可计算出计数方向向下,计数值为0x34
timer_quadrature_decoder_mode_config(ENCODER_TIMER,TIMER_ENCODER_MODE2,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_RISING);

测试结果为:

本文介绍了如何在GD32定时器中使用正交编码器获取电机速度和方向信息,详细讲解了正交译码器功能、不同计数模式以及如何配置定时器和GPIO以实现编码器操作。还提供了示例代码和测试结果。

350

被折叠的 条评论
为什么被折叠?



