TIM编码器测速

编码器接口简介

  • Encoder Interface 编码器接口
  • 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
  • 每个高级定时器和通用定时器都拥有1个编码器接口
  • 两个输入引脚借用了输入捕获的通道1和通道2

在这里插入图片描述
当编码器两个相的位置如图时为正向或者反相。

编码器测速的实质:
实质:测频法测正交脉冲的频率
CNT计次,然后每隔一段时间去一次计次,其实是测频法的思路

如果一个定时器配置成了编码机接口模式,则基本干不了其他活,C8T6芯片只有(TIM1、TIM2、TIM3、TIM4,4个定时器,故最多只能接4个编码器,接完后就没定时器可以用了

用正交信号的好处:

  • 正交信号精度更高,因为A、B相都可以计次,相当关于计次频率提高了一倍
  • 其次正交信号可以以抗噪声,因为正交信号两个信号必须是交替跳变的,可以设计一个抗噪声电路,如果一个信号不变,另一个信号连续跳变,也就是产生了噪声,这时计次值是不会变化的

编码器接口的设计逻辑

首先把A相和B相的边沿作为计数器的计数时钟(此时不使用内部时钟了,编码器相当于外部时钟),出现边沿信号时就计数自增或自减,增还是减由另一相的高低电平决定。所以这是一个硬件自动执行的过程。当每个相的边沿产生变化后,计数器CNT就会增加或者减少。

定时器中的编码器

在这里插入图片描述
编码器的输入是CH1,CH2。输出相当于是从模式控制器,控制CNT计数的控制速度和计数方向。 编码器接口有使用CH1和CH2的输入捕获滤波器和边沿检测,没有使用后面的是否交叉、预分频器、CCR寄存器与编码器接口无关。
流程:如果出现了边沿信号,并且另外一相为正转,则控制CNT自增。否则控制CNT自减。
ARR为65535 正转最大值是65535。
那么反转直接将无符号数据改为有符号对应的 65534就是 -1

编码器接口基本结构

在这里插入图片描述

编码器接口的三种工作模式

在这里插入图片描述
图中TI1FP1信号就是A相,TI2FP2信号就是B相。中间相对信号的电平就是另一相的电平。仅在TI1计数就是在A相边沿计数,B相边沿变化无效。另外两个同理。这就是三个模式。
计数就是CNT根据边沿信号增加或者减少。

实例

在这里插入图片描述
图中列举了一个实例。采用的TI1和TI2都计数的模式。
图中也展示了抗噪声的原理,当产生噪声后并不是不计数了,而是通过我们的计数逻辑可以将错误的纠正回来。

在这里插入图片描述
上图时TI1反相TI2不反相的图。
TI1反相:输入从通道1进来以后,在极性选择部分,在使用输入捕获的时候这里是边沿极性的选择来触发输入捕获。但是此时上升和下降边沿我们都需要。所以此时就不再是边沿的极性的选择。而是高低电平的选择。在不反相的时候,是直接接到编码器接口的。反相后接了一个非门,此时TI1输出的信号和输入的信号就是相反的。所以图中要把TI1的电平反转一下再对照表格选择才是对的。
如果接一个编码器发现加减数的方向反了,此时就可以反转一下极性来控制。

编码器接口相当于一个带有方向选择的外部时钟。

代码

使用定时器3的通道 1 和 2 。

第一步:RCC开启时钟,开启GPIO和定时器的时钟
第二步:配置GPIO,PA6和PA7配置成输入模式
第三步:配置时基单元,预分频器选择不分频,自动重装,一般给最大65535,只需要给CNT执行计数即可
第四步:配置输入捕获单元(只有滤波器和极性两个参数)
第五步:配置编码器接口模式(调用库函数)
最后,调用TIM_Cmd开启定时器

void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
                                uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);

定时器编码接口配置函数。
第一个参数选择定时器,第二个参数选择编码器模式(计数方式,TI1计数或者TI2计数,或者两个都计数,)第三个和第四个参数是IC1和IC2的极性,就是是否反向。

void Encoder_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	//编码器接口的实质是一个带方向控制的外部时钟,故内部时钟没用
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//此时计数方向被编码器托管所以这个参数无用
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;		//ARR计数范围最大,且方便换算为负数
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;		//PSC不分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICStructInit(&TIM_ICInitStructure);//赋一个初始值
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	//参数重复,在TIM_EncoderInterfaceConfig中也有配置//TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//高低电平极性不反转
	TIM_ICInit(TIM3, &TIM_ICInitStructure);//调用后就写入硬件寄存器,故结构体可以继续使用
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICFilter = 0xF;
	//参数重复,在TIM_EncoderInterfaceConfig中也有配置//TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//高低电平极性不反转
	TIM_ICInit(TIM3, &TIM_ICInitStructure);

	TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);

	TIM_Cmd(TIM3, ENABLE);
}


int16_t Encoder_Get(void)
{
	return TIM_GetCounter(TIM3);
}

上述代码就是编码器测编码电机的代码,但是此时只是得到了CNT的值,并没有得到速度。所以只需要在设置一个定时器中断,每隔一段时间读取CNT的值,然后计算速度即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值