TIM—编码器模式注意事项
TIM编码器模式实现如下功能

代码:
TIM4的通道1 PB6连接PA1,通道2 PB7连接PA2
用IO口模拟向上计数的输入波形
#include "debug.h" typedef struct { uint8_t Dir; uint16_t Count; } EncodTypeDef; #define TIM_IS_TIM_COUNTING_DOWN() (((TIM1->CTLR1)&TIM_DIR) == (TIM_DIR)) EncodTypeDef encoder; int main(void) { u16 count=0; GPIO_InitTypeDef GPIO_InitStructure={0}; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure={0}; TIM_ICInitTypeDef TIM_ICInitStructure={0}; NVIC_InitTypeDef NVIC_InitStructure={0}; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); SystemCoreClockUpdate(); Delay_Init(); USART_Printf_Init(115200); printf("SystemClk:%d\r\n",SystemCoreClock); //使能相应时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA, GPIO_Pin_1); GPIO_ResetBits(GPIOA, GPIO_Pin_2); //定时器初始化配置 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //计数器自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler = 0; //预分频器值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复计数器值 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化结构体 TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //使用编码器模式3 TIM_ICStructInit(&TIM_ICInitStructure); //输入捕获配置 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1|TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //输入捕获极性设置,可用于配置编码器正反相 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入捕获预分频器设置 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //输入捕获通道选择,编码器模式需选用此配置 TIM_ICInitStructure.TIM_ICFilter = 0; //输入捕获滤波器设置 TIM_ICInit(TIM4, &TIM_ICInitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //使能中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //设置子优先级为2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始化 TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除TIM更新标志位 TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //使能开启TIM中断 TIM_SetCounter(TIM4,0); TIM_Cmd(TIM4, ENABLE); while(1) { count++; if(count==1) { GPIO_SetBits(GPIOA, GPIO_Pin_1); } if(count==2) { GPIO_SetBits(GPIOA, GPIO_Pin_2); } if(count==3) { GPIO_ResetBits(GPIOA, GPIO_Pin_1); } if(count==4) { GPIO_ResetBits(GPIOA, GPIO_Pin_2); count=0; } encoder.Dir=TIM_IS_TIM_COUNTING_DOWN(); encoder.Count=TIM_GetCounter(TIM4); printf("Dir=%d,count=%d\r\n",encoder.Dir,encoder.Count); Delay_Ms(10); } } void TIM4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void TIM4_IRQHandler(void) { if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //是否产生更新(溢出)中断 { TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清空TIM中断标志位 } }
注意事项:
1.TIM的预分频值设为0,设为1时CNT会除以2。
2.滤波系数TIM_ICFilter,当信号变化速度非常快时,需要设置为0,否则会丢信号,变化速度不是很快时,可以设置高一些,防止干扰,可以参考RM手册中的描述,具体值以测试为准。
浙公网安备 33010602011771号