Чтение выходного сигнала квадратурного энкодера с помощью NUCLEO-F072RB

Я использую плату NUCLEO-F072RB в сочетании с X2C для считывания выходного сигнала энкодера двигателя постоянного тока для измерения его скорости. Согласно техническому описанию, с помощью таймеров TIM2 и TIM3 можно выполнить это чтение. Для этого я следовал этому и эти источники для написания следующего кода:

/** - configure A6 for encoder input (T1) */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_Init (GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_InitStruct.GPIO_Pin, GPIO_AF_1);

/** - configure A7 for encoder input (T2) */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_Init (GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA, GPIO_InitStruct.GPIO_Pin, GPIO_AF_1);

/**********************************************/
/* Encoder input setup */

/* TIM3 clock enabled */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* TIM3 DeInit */
TIM_DeInit(TIM3);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure); 

/* Configure the timer TIM3 for encoder input */
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12,  TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_SetAutoreload (TIM3, 0xffff);

/* TIM3 counter enable */
TIM_Cmd(TIM3, ENABLE);

Здесь я использую альтернативную функцию 1 для обоих входов, что согласно даташиту соответствует TIM3. Насколько я понимаю, при такой настройке каждый раз, когда на T1 (в данном случае GPIO A6) появляется нарастающий фронт, счетчик TIM3 увеличивается на 1, а когда на T2 (A7) есть нарастающий фронт, счетчик уменьшается одним.

В целях отладки я установил значение переменной, которую могу отслеживать. Если счетчик равен 1 или больше, устанавливается значение INT16_MAX, в противном случае устанавливается 0.

if (TIM_GetCounter(TIM3) > 0x0) {
    Inports.Encoder_Input = INT16_MAX;
} else {
    Inports.Encoder_Input = 0;
}

Прежде чем использовать настоящий энкодер, я попытался использовать переключатель для ручной генерации нарастающих фронтов и выход ШИМ от другого GPIO для подачи на входы (GPIO A6 и A7). Таким образом, я ожидаю, что счетчик TIM3 начнет считать вверх/вниз, но ничего не происходит. Я заметил, что когда я подключаю сигнал к A6 или A7, он ухудшается, что может объяснить, почему не обнаруживаются нарастающие фронты. Измерив мультиметром постоянного тока сопротивление на этих входах, я получил примерно 40 Ом, что очень мало для входного порта.

Как я могу правильно настроить таймер и GPIO, чтобы иметь возможность считывать сигнал кодировщика и запускать счетчик TIM3?


person Nicolás Arias    schedule 12.09.2017    source источник