使用stm32 定时器TIM3 的重映射引脚 捕获正交编码器数据的一些积累

因为我们公司的软件和硬件是分开的,硬件人员在设计电路板的时候,为了布线方便,往往会使用一些引脚的重映射功能。

这次使用的单片机是stm32F103ZGT6,使用PB4和PB5捕获正交编码器的数据。

因为这两个引脚本身没有定时器,只有在重映射时候才能使用TIM3的ch1和ch2。

因此,我使用重映射配置,将这两个引脚配置了以下,这是一开始的代码: 

GPIO_InitTypeDef  GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimBaseStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 ,ENABLE );                //重映射相应的外设
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	TIM_TimeBaseStructInit(&TIM_TimBaseStructure);
	TIM_TimBaseStructure.TIM_Prescaler = 0x0;
	TIM_TimBaseStructure.TIM_Period = 2400;
	TIM_TimBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	TIM_TimeBaseInit(TIM3,&TIM_TimBaseStructure);
	
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
	
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_ICFilter = 0;
	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	
	TIM_ClearFlag(TIM3,TIM_FLAG_Update);
	TIM_SetCounter(TIM3,0);
	TIM_Cmd(TIM3,ENABLE);

通过读取TIM3的CNT寄存器获取当前数值。

然而无论怎样旋转编码器,都无法得到计数,计数始终为0。因此开始进行排查:

猜测1:引脚是否能够捕获到高低电平

试验:将两个引脚设置为开入,然后旋转编码器,可以正确的读到两个引脚高低电平的变换,证明是配置的问题

猜测2:是否和未开启AFIO时钟有关?

试验:开启AFIO时钟。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

还是不能捕获电平,证明不是由这个引起的。

猜测3:是否其他地方使用了TIM3,导致重映射功能没有正确开启?

试验:屏蔽其他程序,在重映射之前添加一行程序

TIM_DeInit(TIM3);

问题仍然没有解决。

猜测4:该引脚复用后是否具备捕获编码器脉冲的功能?

试验:百度上搜索,然后获取到了部分重映射和全部重映射的概念。在我的认知当中,部分重映射应该是只映射部分功能,我这里配置的是全部重映射,认为应该是可以实现捕获编码器功能的。

 

然而问题没有办法解决。只能寻求参考手册的帮助。

在AFIO寄存器这一章看到了这个概念:

使用stm32 定时器TIM3 的重映射引脚 捕获正交编码器数据的一些积累_第1张图片使用stm32 定时器TIM3 的重映射引脚 捕获正交编码器数据的一些积累_第2张图片

看到这里,我瞬间明白了,stm32中的重映射,也是针对端口的,并不是说每个端口都具备映射的全部功能。在开启这个端口重映射的时候,不能够配置成FullRemap,否则是配置失败的。

因此改成了以下样子:

GPIO_InitTypeDef  GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimBaseStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 ,ENABLE );                //重映射相应的外设
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	TIM_TimeBaseStructInit(&TIM_TimBaseStructure);
	TIM_TimBaseStructure.TIM_Prescaler = 0x0;
	TIM_TimBaseStructure.TIM_Period = 2400;
	TIM_TimBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	TIM_TimeBaseInit(TIM3,&TIM_TimBaseStructure);
	
	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
	
	TIM_ICStructInit(&TIM_ICInitStructure);
	TIM_ICInitStructure.TIM_ICFilter = 0;
	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	
	TIM_ClearFlag(TIM3,TIM_FLAG_Update);
	TIM_SetCounter(TIM3,0);
	TIM_Cmd(TIM3,ENABLE);

stm32由于由库函数的支持,导致我们在使用的过程中越来越忽略掉了底层的一些运作方式。知其然而不知其所以然,在技术道路上,所有忽略掉的小细节以后都会成倍的返还给你。

你可能感兴趣的:(stm32)