【前言】
【Mini-F5375-OB】的定时器,有编码器模式,可以通过设置,直接读取旋转的方向与旋转的步数。【IO的选取】
从数据手册中看到,TIM1/8、TIM2/5、TIM3/4均有编码器模式。我这里先取TIM1的CH1/CH2为编码器接口。从引脚图上看出,CH1为PA8,CH2为PA9。
【定时器初始化】
首先要开启GPIOA的时钟,复用为GPIO-AF-1。
其次初始化IO为中输入模式。
开始TIM1的时钟,然后设为编码器模式,下降沿触发。
void TIM1_8_Configure(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_ICInitTypeDef TIM_ICInitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; /* TIM1 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_1); /* TIM1_CH1 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); /* TIM1_CH2 */ GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStruct); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInitStruct.TIM_Period = UINT16_MAX; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct); TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI12, TIM_ICPolarity_Falling, TIM_ICPolarity_Falling); TIM_ICStructInit(&TIM_ICInitStruct); TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; TIM_ICInitStruct.TIM_ICFilter = 6; TIM_ICInit(TIM1, &TIM_ICInitStruct); TIM_SetCounter(TIM1, 0); TIM_Cmd(TIM1, ENABLE); }
【状态获取】
创建 一个任务,周期获取编码器的状态,如果有变化则打印出状态与步长:
void led2_task(void *pvParameters) { static uint16_t OldCount1 = 0, OldCount8 = 0; static uint16_t NewCount1 = 0, NewCount8 = 0; printf("\r\nTest %s", __FUNCTION__); TIM1_8_Configure(); printf("\r\nConnect encoders."); while(1) { NewCount1 = TIM_GetCounter(TIM1); if (NewCount1 != OldCount1) { OldCount1 = NewCount1; printf("\r\nDIR1 : %d, CNT1 : %d", TIM_GetCountDirection(TIM1), NewCount1); } vTaskDelay(20); } }
【实验效果】
【小结】
根据编码器的状态结合方向,就可以实现比如设置状态等功能了。