我目前正在使用 STM32F4 和 STM32F429ZI Nucleo-144 板。我希望使用此微控制器通过正交编码器接口评估旋转编码器的位置。查看文档,这是通过计时器完成的。我将 A/B 编码器输出连接到 micro 上的 PA6 和 PC7,但我注意到计数似乎在漂移。
在调试过程中,我注意到如果我断开一个编码器输出到微控制器并移动电机,即使只连接了一条编码器线,计数仍然会递增/递减。因为我指望 TI1 和 TI2 边缘,所以这不应该发生。如果我正确阅读下图,因为我的一条线使用内部上拉保持高电平,另一个输入上的时钟脉冲应该上升/下降/上升/下降,实际上只是在两个不同的计数之间循环。但是,如果我旋转编码器,计数会根据方向不断增加或减少。
为什么只连接一个编码器输入时编码器计数会发生变化?我还附上了范围跟踪,以证明只有一个计数处于活动状态,以及代码。
编辑:我也尝试将极性从 BOTH EDGE 更改为 RISING EDGE,但没有明显的好处。
#include "stm32f4xx_hal.h"
#include "encoder_test.h"
GPIO_InitTypeDef GPIO_InitStruct;
TIM_HandleTypeDef Timer_InitStruct;
TIM_Encoder_InitTypeDef Encoder_InitStruct;
void EncoderTest_Init()
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA6 ------> TIM3_CH1
PC7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Timer_InitStruct.Instance = TIM3;
Timer_InitStruct.Init.Period = 0xFFFF;
Timer_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP;
Timer_InitStruct.Init.Prescaler = 1;
Timer_InitStruct.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
Encoder_InitStruct.EncoderMode = TIM_ENCODERMODE_TI12;
Encoder_InitStruct.IC1Filter = 0x00;
Encoder_InitStruct.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
Encoder_InitStruct.IC1Prescaler = TIM_ICPSC_DIV1;
Encoder_InitStruct.IC1Selection = TIM_ICSELECTION_DIRECTTI;
Encoder_InitStruct.IC2Filter = 0x00;
Encoder_InitStruct.IC2Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
Encoder_InitStruct.IC2Prescaler = TIM_ICPSC_DIV1;
Encoder_InitStruct.IC2Selection = TIM_ICSELECTION_DIRECTTI;
if (HAL_TIM_Encoder_Init(&Timer_InitStruct, &Encoder_InitStruct) != HAL_OK)
{
while (1);
}
if (HAL_TIM_Encoder_Start_IT(&Timer_InitStruct, TIM_CHANNEL_1) != HAL_OK)
{
while (1);
}
}
void TIM3_IRQHandler()
{
HAL_TIM_IRQHandler(&Timer_InitStruct);
}