第一步,RCC开启时钟,开启GPIO和定时器的时钟
第二步,配置GPIO,这里需要把PA6和PA7配置成输入模式
第三步,配置时基单元,这里预分频器我们一般选择不分频,自动重装,一般给最大65535,只需要个CNT执行计数就行了
第四步,配置输入捕获单元,这里输入捕获单元只有滤波器和极性这两个参数有用
第五步,配置编码器接口模式,这个直接调用一个库函数就可以了
最后,调用TIM Cmd,启动定时器
CNT就会随着编码器旋转而自增自减。 如果想要测量编码器的位置,那直接读出CNT的值就行了。 如果想测量编码器的速度和方向,那就需要每隔一段固定的闸门时间,取出一次CNT,然后再把CNT清零,这样就是测频法测量速度了
库函数
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity);
定时器编码器接口配置,第一个参数选择定时器,第二个参数选择编码器模式,后面两个参数,分别选择通道1和通道2的电平极性
第一步,RCC开启时钟,开启GPIO和定时器的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
第二步,配置GPIO
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_InternalClockConfig(TIM3);//因为编码器接口会托管时钟,编码器接口就是一个带有方向控制的外部时钟,所以这个内部时钟就没有用了
第四步,配置输入捕获单元
可以看出输入捕获单元并没有全部使用到,只使用了通道一和通道二的滤波器和极性选择,所以我们只需要配置这两部分的参数即可, TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);//为了防止结构体中出现不确定值,可能会造成的问题,使用StructInit给结构体赋一个初始值
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
这里的上升沿并不代表上升沿有效,因为编码器接口始终都是上升沿、下降沿都有效的。 这里的上升沿参数代表的是高低电平极性不反转,也就是TI1、TI2是否反向,对应通道给上升沿就是不反向,给下降沿就是反向这个意思。
实例(均不反相)
实例(TI1反相)
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
第五步,配置编码器接口模式
void TIM_EncoderInterfaceConfig(TIM_TypeDef* TIMx, uint16_t TIM_EncoderMode,uint16_t TIM_IC1Polarity, uint16_t TIM_IC2Polarity)
工作模式
TIM_EncoderMode:对应PPT工作模式
TIM_EncoderMode_TI1: 仅在TI1FP1计数
TIM_EncoderMode_TI2: 仅在TI2FP2计数
TIM_EncoderMode_TI12: 就是T1和T2都计数
TIM_IC1Polarity:IC1和IC2的极性
TIM_ICPolarity_Falling:通道反相
TIM_ICPolarity_Rising:通道不反相
一定要保证TIM_EncoderInterfaceConfig函数位于TIM_ICInit函数的下面,否则的话就是TIM_ICInit 覆盖encoder函数的配置。
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
开启定时器
TIM_Cmd(TIM3,ENABLE);
获取计数器值
int16_t Encoder_Get(void)
{
int16_t tmp;
tmp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return tmp;
}
main
中断每隔一秒获取编码器接口计数器值
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//检查更新中断标志位
{
Num = Encoder_Get();
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
}
}
总结
Encode.c
#include "stm32f10x.h" // Device header
void Encoder_Init(void)
{
//第一步,RCC开启时钟,开启GPIO和定时器的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//第二步,配置GPIO
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_InternalClockConfig(TIM3);
//第三步,配置时基单元,
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_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
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)
{
int16_t tmp;
tmp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return tmp;
}
点击数:2