编码器接口介绍
Encoder Interface 编码器接口
编码器接口可接收增量(正交) 编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
每个高级定时器和通用定时器都拥有1个编码器接口
两个输入引脚借用了输入捕获的通道1和通道2
正交编码器
因为正交编码器中A相和B相检测的位置相差了90度,那么当编码器旋转时就会有A相或B相就会有不同的对应状态,通过与图中表的边沿和另一相的状态关系的比较,我们就能得出正转和反转。
根据此图,编码器的A相和B相与TI1FP1和TI2FP2相连,可知编码器的输入引脚就是定时器的CH1和CH2引脚,而编码器的功能可以理解为从模式控制器,来控制CNT的计数时钟和计数方向。
编码器接口基本结构
工作模式
TI1FP1信号和TI2FP2信号就是A相和B相,仅在TI1计数代表A相产生上升沿或下降沿时向上计数或向下计数,同理可知TI2计数和在TI1和TI2计数。在TI1和TI2计数相较于其他两种的计数精度更高。
实例(均不反相)
这里反相指的是当信号通过滤波器进入极性选择时,如果不反向TI1FP1保持原状,反相的话就是使TI1高低电平反转。
TI1反相
代码实现
第一步:RCC开启时钟,开启GPIO和定时器的时钟
第二步:配置GPIO
第三步:配置时基单元,分频器不分频,自动重装给65535
第四步:配置输入捕获单元,这里只有滤波器和极性选择用到
第五步:配置编码器接口模式
最后调用TIM_Cmd,启动定时器
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,
uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
第一个参数选择定时器,第二个参数选择编码器模式,后面的两个参数分别选择通道一与通道二的电平极性;
Encoder.c
#include "stm32f10x.h" // Device header
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_ICInit(TIM3,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
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)
{
int16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter (TIM3,0);
return Temp;
}
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"
int16_t Speed;
int main (void)
{
OLED_Init();
Timer_Init ();
Encoder_Init();
OLED_ShowString (1,1,"Speed:");
while(1)
{
OLED_ShowSignedNum (1,7,Speed,5);
}
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus (TIM2,TIM_IT_Update)==SET)
{
Speed = Encoder_Get();
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}