GD32定时器正交译码器使用

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

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);

在这里插入图片描述
测试结果为:
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值