STM32F407定时器编码器接口模式
16位定时器扩展32位
//TIM5初始化为编码器接口模式,读取光栅尺数值
void TIM5_Config(u32 arr,u32 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTF时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //光栅尺
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //开漏输出
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP; //上拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PD
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //复用为TIM5
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); //复用为TIM5
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 0xFFFF 65535
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure); //初始化TIM5
//编码器模式1 – 根据TI1FP1的电平,计数器在TI2FP2的边沿向上/下计数。
TIM_EncoderInterfaceConfig(TIM5,TIM_EncoderMode_TI1,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //编码器接口模式配置
TIM_ICStructInit(&TIM_ICInitStructure); //默认值赋值
TIM_ICInitStructure.TIM_ICFilter =0x2; //滤波 0x0~0xF
TIM_ICInit(TIM5, &TIM_ICInitStructure); //初始化
TIM_ClearFlag(TIM5, TIM_FLAG_Update);//清除标志位
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE); //更新中断
TIM_SetCounter(TIM5,0); //计数器清零
TIM_Cmd(TIM5, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn; //添加中断函数
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
volatile int16_t N=0;
void TIM5_IRQHandler(void) //溢出中断
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //中断标志位
{
if((TIM5->CR1 & TIM_CR1_DIR) == TIM_CR1_DIR)//向下计数 DIR=1
{
N--;
}
else if((TIM5->CR1 & TIM_CR1_DIR) == 0)//向上计数 DIR=0
{
N++;
}
}
TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清除中断标志位
}
int main(void)
{
u32 data;
TIM5_Config(0XFFFF,0); //定时器初始化 16位自动加载
while(1)
{
data=N * 65536 + TIM5->CNT; //读取编码器值
data=GetENCODECounter(data); //编码器值反方向处理
delay_ms(200);
}
}
//编码器反方向转换
//输出0xX0000000 正方向X=0 反方向X=1
u32 GetENCODECounter(u32 count) //编码器反方向数值转换
{
if(count>0X80000000) //负方向
{
count=0XFFFFFFFF-count; //
count=count | 0X80000000 ;
}
return count;
}