В настоящее время я использую STM32F4 с платой Nucleo-144 STM32F429ZI. Я хочу использовать этот микроконтроллер для оценки положения вращающегося энкодера через интерфейс квадратурного энкодера. Рассматривая документацию, это делается с помощью таймеров. У меня есть выходы кодировщика A/B, подключенные к PA6 и PC7 на микро, но я заметил, что подсчеты, похоже, дрейфуют.STM32F4 Число энкодеров меняется, когда оно не должно
Во время отладки я заметил, что если я отсоединяю один из выходов энкодера к микроконтроллеру, и я перемещаю двигатель, счетчики все еще увеличиваются/уменьшаются, хотя только одна из линий энкодера подключается. Поскольку я рассчитываю на края TI1 и TI2, это не должно происходить. Если я правильно читаю приведенную ниже диаграмму, так как одна из моих линий удерживается высоко, используя внутреннее подтягивание, тактовые импульсы на другом входе должны идти вверх/вниз/вверх/вниз и действительно просто циклироваться между двумя разными значениями. Однако, если я вращаю энкодер, подсчеты продолжают увеличиваться или уменьшаться в зависимости от направления.
Почему изменяется счетчик энкодера только при подключении только одного входа энкодера? У меня также есть трассировка области, чтобы доказать, что активен только один счетчик, а также код.
EDIT: Я также попытался изменить полярность от 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);
}
Похоже, это инкрементный датчик. Если вам нужно выяснить угол, лучше всего подходит абсолютный поворотный кодер? Вы все еще можете оценить позицию из исходной позиции (если она известна), но я думаю, что в какой-то момент вы будете пропускать прерывания и потерять счет – Emilien