В настоящее время я использую STM32F4 с платой STM32F429ZI Nucleo-144. Я хочу использовать этот микроконтроллер для оценки положения поворотного энкодера через интерфейс квадратурного энкодера. Глядя на документацию, это делается с помощью таймеров. У меня есть выходы энкодера A/B, подключенные к PA6 и PC7 на микроконтроллере, но я заметил, что счетчики дрейфуют.
Во время отладки я заметил, что если я отсоединяю один из выходов энкодера от микроконтроллера и перемещаю двигатель, счетчики все равно увеличиваются/уменьшаются, даже если подключена только одна из линий энкодера. Поскольку я рассчитываю как на TI1, так и на TI2, этого не должно происходить. Если я правильно читаю приведенную ниже диаграмму, поскольку одна из моих линий удерживается на высоком уровне с помощью внутреннего подтягивания, тактовые импульсы на другом входе должны идти вверх/вниз/вверх/вниз и на самом деле просто циклически переключаться между двумя разными счетчиками. Однако, если я вращаю энкодер, счетчики продолжают увеличиваться или уменьшаться в зависимости от направления.
Почему счетчик энкодера меняется, когда подключен только один вход энкодера? У меня также есть трассировка области, чтобы доказать, что активен только один счетчик, а также код.
РЕДАКТИРОВАТЬ: Я также пытался изменить полярность с ОБА КРАЯ на ВОСХОДЯЩИЙ КРАЙ, но без видимой пользы.
#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);
}