STM32G474RE TIM4 Rotary Encoder
Hi,
Greetings!
I have a Bourns Rotary encoder
https://www.bourns.com/docs/product-datasheets/pec11r.pdf
connected to PA11(ENCA)/TIM4_CH1 and PA12(ENCB)/TIM4_CH2.
Trying to use the encoder as a input control for user input.
This is what I am doing:
static void encoder_init(void)
{
LL_GPIO_InitTypeDef gpio;
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
gpio.Pin = LL_GPIO_PIN_11 | LL_GPIO_PIN_12; /* Enc A, Enc B */
gpio.Mode = LL_GPIO_MODE_ALTERNATE; /* Alternate function */
gpio.Speed = LL_GPIO_SPEED_FREQ_LOW; /* Low Speed */
gpio.Alternate = LL_GPIO_AF_10; /* AF10=TIM4 */
LL_GPIO_Init(GPIOA, &gpio);
LL_TIM_SetPrescaler(TIM4, 0);
LL_TIM_SetAutoReload(TIM4, 100);
LL_TIM_SetCounterMode(TIM4, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetClockDivision(TIM4, LL_TIM_CLOCKDIVISION_DIV4);
LL_TIM_DisableARRPreload(TIM4);
// LL_TIM_SetEncoderMode(TIM4, LL_TIM_ENCODERMODE_X4_TI12);
LL_TIM_SetEncoderMode(TIM4, LL_TIM_ENCODERMODE_DIRECTIONALCLOCK_X1_TI12);
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetFilter(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV2_N8);
LL_TIM_IC_SetPolarity(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetFilter(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV2_N8);
LL_TIM_IC_SetPolarity(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);
LL_TIM_EnableCounter(TIM4);
LL_TIM_CC_EnableChannel(TIM4, LL_TIM_CHANNEL_CH1);
LL_TIM_CC_EnableChannel(TIM4, LL_TIM_CHANNEL_CH2);
}
int main(void)
{
uint32_t enc_cur = 0, enc_prev = 0;
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
SystemClock_Config();
gpio_init();
uart_init();
encoder_init();
printf("\tSTM32G474 Encoder Test\n");
while (1) {
enc_cur = LL_TIM_GetCounter(TIM4);
if (enc_cur != enc_prev) {
printf(" ENC: %d DIR: %d\n", enc_cur, LL_TIM_GetDirection(TIM4) >> 4);
enc_prev = enc_cur;
}
}
}On RST, I get the following results:
STM32G474 Encoder Test
ENC: 1 DIR: 0
ENC: 2 DIR: 0
ENC: 3 DIR: 0
ENC: 4 DIR: 0
When I turn the encoder CW, I get:
ENC: 3 DIR: 1
ENC: 2 DIR: 1
ENC: 1 DIR: 1
ENC: 0 DIR: 1
ENC: 100 DIR: 1
ENC: 99 DIR: 1
ENC: 98 DIR: 1
ENC: 97 DIR: 1
ENC: 96 DIR: 1
When I turn the encoder CCW, I get:
ENC: 95 DIR: 1
ENC: 94 DIR: 1
ENC: 93 DIR: 1
ENC: 92 DIR: 1
ENC: 91 DIR: 1
ENC: 90 DIR: 1
ENC: 89 DIR: 1
ENC: 88 DIR: 1
ENC: 87 DIR: 1
Attached screenshot:
Despite what I do, the direction, does not seem to change.
Any thoughts, suggestions what I am doing wrong in here ?
Thanks,
Manu
