# Help with a simple debounce program on STM32

I'm trying to write a simple debounce program on an STM32F4. Code as follows:

Initialization:

  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

//Configure PB7 as output and PC13 as input pull-down
GPIOB->MODER |= GPIO_MODER_MODER7_0;
GPIOC->PUPDR |= GPIO_PUPDR_PUPDR13_1;

//Configure Timer 2 for 20ms delay
TIM2->PSC = 95;
TIM2->ARR = 19999;
TIM2->CR1 |= TIM_CR1_URS;
TIM2->DIER |= TIM_DIER_UIE;
TIM2->EGR |= TIM_EGR_UG;

NVIC_EnableIRQ(TIM2_IRQn);


Main:

 while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
if (GPIOC->IDR & GPIO_IDR_ID13)
TIM2->CR1 |= TIM_CR1_CEN;            //Enable Timer 2
}


IRQ Handler:

void TIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_SR_UIF;                   // Reset Update Interrupt Flag on Timer 2 Status Register
if (GPIOC->IDR & GPIO_IDR_ID13)
{
GPIOB->ODR ^= GPIO_ODR_OD7;            // Toggle PB7
TIM2->CR1 &= ~TIM_CR1_CEN;             // Disable Timer 2
}
}


I'm using a delay of 20ms on Timer 2 and toggling the LED on PB7. The LED does toggle, but it doesn't behave like a debounced switch and flickers as the LED turns on. Where am I going wrong?

• What do you expect the code to do then? Based on the code, as long as you press the button, it will keep turning on the timer, and the timer will keep toggling the LED. – Justme May 2 at 17:27
• @Justme I’d like it to behave like a normal debounced switch, toggle whenever pressed. I’ve read Ganssle’s algorithm for debouncing but I’m just confused as to how to go about it. – Joshua John May 2 at 18:49
• I think you should forget debouncing and timers for a while and concentrate on the program logic how to toggle the LED only when a button push is first detected, not toggle a LED while the button is being held pushed down. – Justme May 2 at 18:50
• @Justme I know how to toggle the LED when the button push is first detected, it’s just a matter of removing all the timer stuff and replacing TIM2->CR1 |= TIM_CR1_CEN with GPIOB->ODR ^= GPIO_ODR_OD7. That’s worked for me. I want to learn how to debounce the switch so that I won’t see any ripple on the output. – Joshua John May 2 at 19:02
• You need an extra variable for your code to 'remember' if it's already toggled the LED for the current button-press so that it doesn't just continuously toggle. If you use a bool, then only toggle the LED in the ISR if it's false, and then immediately set it to true. Only set it back to false when you see that the button has been released. – brhans May 2 at 19:35

Make 2 global variables called tick and previousTick, or whatever you want, and inside the timer ISR increment the tick variable by 1. then check if the difference between this tick and previoustick is larger than a value of your choice then consider the button debounced, otherwise if the difference of this tick and previousTick is not large enough then that means your button has bounced. At the end of ISR set previousTick = tick.

Psuedo code:

   //GLOBALS
uint32_t tick = 0 ;
uint32_t previousTick = 0 ;

timerInterrupt()
{
tick++;
if( (tick - previousTick) > 5 )