最近任务中使用到了旋钮,前面文章做了一个I/O口,今天记录一下使用STM32 timer编码器模式的方法
-
旋钮的左右2脚接到带有timer的脚上,配置为编码器模式, 这里使用了PC0和PC1
//PB6 ch1 A,PB7 ch2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//使能TIM1时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); GPIO_StructInit(&GPIO_InitStructure);//将GPIO_InitStruct中的参数按缺省值输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//PA6 PA7浮空输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_2); GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_2); TIM_DeInit(TIM1); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 359*4; //设定计数器重装值 TIMx_ARR = 359*4 TIM_TimeBaseStructure.TIM_Prescaler = 0; //TIM3时钟预分频值 TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1 ;//设置时钟分割 T_dts = T_ck_int TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_EncoderInterfaceConfig(TIM1, TIM_EncoderMode_TI1, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge);//使用编码器模式3,上升下降都计数 TIM_ICStructInit(&TIM_ICInitStructure);//将结构体中的内容缺省输入 TIM_ICInitStructure.TIM_ICFilter = 6; //选择输入比较滤波器 TIM_ICInit(TIM1, &TIM_ICInitStructure);//将TIM_ICInitStructure中的指定参数初始化TIM3 //Reset counter TIM1->CNT = 0;// TIM_Cmd(TIM1, ENABLE); //启动TIM1定时器
-
编码器检测
需要用一个定时器记录时间来判断旋转快慢,定义为1ms记录一次,tim3_cnt4 为计数值。#define CMP_VALUE (500) #define FAST_RANK_2 (200) #define FAST_RANK_1 (30) uint8_t g_enc_fast_flag; uint16_t Encoder_Process(void) { static uint8_t flag = false; uint16_t enc_value; if(TIM1->CNT == CMP_VALUE)//未旋转 { flag = false;//清标志 g_enc_fast_flag = 0; return 0; } if(TIM1->CNT > CMP_VALUE)// 向右 { enc_value = BIT2;// 自己定义一个标志是代表向右的方向 TIM1->CNT = CMP_VALUE; }else if(TIM1->CNT < CMP_VALUE){// 向左 enc_value = BIT0;;// 自己定义一个标志是代表向左的方向 TIM1->CNT = CMP_VALUE; } if(!flag)// 表示这次检测到了向左或向右 { flag = true; tim3_cnt4 = 0; // timer清0开始计时 return enc_value;// 返回旋转值 } if(tim3_cnt4 < FAST_RANK_2)// 如果在限定时间内,认为是快旋 { g_enc_fast_flag = 2;// 快旋标志 if(tim3_cnt4 <= FAST_RANK_1) // 如果时间更短, 表示旋转极快 { g_enc_fast_flag = 1;// 极快标志 } tim3_cnt4 = 0;// timer清0再次开始计时 }else{ g_enc_fast_flag = 0; // 正常旋转速度 } return enc_value; // 返回旋转值 }
最后就是处理旋钮值了