STM32L432 EXTI strange behaviour
Hi,
I have three buttons - START, STOP and CH_SELECT which are serviced using EXTI interrupts. I have also a rotary encoder (A and B pins). Every button line is serviced on a separate IRQ line. Debouncing of the switch and rotary encoder pins is handled in HAL_GPIO_EXTI Callback function.
The code is actually working but sometimes, actually very often, code snippet of wrong button is executed. When I pressing for example button START sometimes I get “STOP button pressed” or “CH_SELECT_button pressed” randomly. Rotary encoder works very well. Am I missing something, every help is really appreciated.
Microcontrooller is STM32L431 with 80MHz master clock. I am using STM32CubeIDE 1.16.1
Those are my EXTI handlers (in stm32l4xx_it.c file):
void EXTI4_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(STOP_BUTTON_Pin);
}
void EXTI9_5_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(START_BUTTON_Pin);
}
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(A_Pin);
HAL_GPIO_EXTI_IRQHandler(B_Pin);
HAL_GPIO_EXTI_IRQHandler(CH_SELECT_Pin);
}
This is my callback function (in main.c file):
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
uint32_t currentTime = HAL_GetTick();
if ((currentTime - lastDebounceTime) < DEBOUNCE_DELAY_ENCODER) {
return;
}
lastDebounceTime = currentTime;
if (GPIO_Pin == A_Pin) {
if (HAL_GPIO_ReadPin(B_GPIO_Port, B_Pin) == GPIO_PIN_SET) {
encoderValue+=20;
if(encoderValue>2666) encoderValue=0;
} else {
encoderValue-=20;
if(encoderValue<0) encoderValue=2666;
}
}
if (GPIO_Pin == B_Pin) {
if (HAL_GPIO_ReadPin(A_GPIO_Port, A_Pin) == GPIO_PIN_SET) {
encoderValue-=20;
if(encoderValue<0) encoderValue=2666;
} else {
encoderValue+=20;
if(encoderValue>2666) encoderValue=0;
}
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, encoderValue);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, encoderValue);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, encoderValue);
}
//START button
if (GPIO_Pin == START_BUTTON_Pin) {
if ((currentTime - last_start_button_tick) > DEBOUNCE_DELAY_BUTTON) {
last_start_button_tick = currentTime;
treatment_time=0;
start_treatment=1;
TIM1->CR1 |= TIM_CR1_CEN; //start timer1
//printf("start button pressed\n\r");
flag=1;
}
}
//STOP button
if (GPIO_Pin == STOP_BUTTON_Pin) {
if ((currentTime - last_stop_button_tick) > DEBOUNCE_DELAY_BUTTON) {
last_stop_button_tick = currentTime;
start_treatment=0;
//printf("stop button pressed\n\r");
flag=2;
}
}
//CH_SELECT button
if (GPIO_Pin == CH_SELECT_Pin) {
if ((currentTime - last_ch_select_tick) > DEBOUNCE_DELAY_BUTTON) {
last_ch_select_tick = currentTime;
//printf("CH_SELECT button pressed\n\r");
flag=3;
}
}
}
I am printing debug messages in the main loop:
while(1) {
if(flag==1) { printf("START button pressed\n\r"); flag=0;}
if(flag==2) { printf("STOP button pressed\n\r"); flag=0;}
if(flag==3) { printf("CH_SELECT button pressed\n\r"); flag=0;}
//…
//…
}
AND my debounce values are:
const uint32_t DEBOUNCE_DELAY_ENCODER = 50;
const uint32_t DEBOUNCE_DELAY_BUTTON = 50;
Thank you very much, I really appreciated any advice...
