该实验用的是最小系统板和面包板,先上接线图:
为什么选择PA6和PA7口呢,看张图:
可以看到编码器接口的两个输入TI1FP1和TI2PF2来自定时器的输入捕获的两个通道TIMx_CH1和TIMx_CH2 ,所以在选择引脚时要选择能复用为某定时器通道1和通道2的引脚,可以再参考引脚定义:
PA6和PA7确实可以被复用为定时器TIM3的两个通道TIM3_CH1和TIM3_CH2。于是大致流程就是先配置引脚时钟和定时器时钟,初始化引脚和时基单元,注意配置时基单元时计数模式的配置是不起作用的,计数方向是由我们之后使用编码器接口配置的库函数所决定的,接口定时器运行控制使能。再配置输入捕获通道,因为输入捕获通道只有包含极性选择和滤波之前的配置对编码器接口起作用,这里配置时只用先给相关结构体赋默认值,再对少数参数进行修改,但是极性选择这一配置再之后编码器接口的配置里也会涉及到,所以只用配置滤波。配置完输入捕获通道后最后便可以用库函数配置编码器接口了:
Encode.c:
#include "stm32f10x.h" // Device header
int16_t Compar=0;
void Encode_Init()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,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_InitStructure;
TIM_InitStructure.TIM_ClockDivision=TIM_CKD_DIV2;
TIM_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_InitStructure.TIM_Period=65536-1;
TIM_InitStructure.TIM_Prescaler=1-1;
TIM_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
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_Cmd(TIM3,ENABLE);
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Rising);
}
int16_t TIM_EncodeCount()
{
int16_t tmp=TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3,0);
return tmp;
}
编码器如何根据旋转使CNT计次可以参考下图:
为了达到 测速的目的,我们还可以使用一个定时器每隔一段时间读取计次,这样就可以测速了,再配置一个定时器:
Timer.c:
#include "stm32f10x.h" // Device header
#include "Encode.h"
void Timer_Init()//TIM2
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InternalClockConfig(TIM2);//内部时钟模式
//周期1s
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=10000-1;
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV4;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级计数器配置
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_Cmd(TIM2,ENABLE);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);//配置完会立刻更新中断,要重置标志位
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//如何中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
主函数和OLED之类的就不写了,以上内容仅供参考,谢谢!