Skip to main content
Killstreet30
Associate III
January 17, 2023
Question

Doubt regarding multiple button press on STM32.

  • January 17, 2023
  • 7 replies
  • 3781 views

Hello,

I had a doubt regarding multiple button presses. Im trying to code a program so that every time I press a button the brightness of the LED decreases and once it reaches the minimum (5th button press), it increases back again after every button press. I have tried to code the same but am not getting the desired result. Please help. P.S I'm using timers and interrupts for the same.

Thank you.

Here is the code:

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_USART2_UART_Init();

 MX_TIM2_Init();

 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

 while (1)

 {

 }

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

int i;

if(GPIO_Pin==GPIO_PIN_13){

for(i=1;i<6;i++){

__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1, 1000/i);}

for(i=6;i>0;i=i-1){

__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1, 1000/i);

}

}

}

    This topic has been closed for replies.

    7 replies

    gbm
    Lead III
    January 17, 2023

    It's usually a very bad idea to use EXTI foe checking the button state. Search the forum for few discussions on this topic, use timer interrupt, not EXTI, for detecting button press. Note that multiple EXTI interrupts will fire on every button press (typically 2..3). You will not see it on a Nucleo board because of the extra circuitry present. Normally, no extra components are used with a button cause there is no need for them if your software is correctly written.

    Your code simply sets the PWM duty to 1000 on every EXTI interrupt button press - it doesn't change the duty at all.

    My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
    S.Ma
    Principal
    January 17, 2023

    ChatGPT produces in 3 minutes:

    #include "stm32f4xx.h"
     
     
     
    #define LED_PIN 9 // Assumes the LED is connected to pin 9
     
    #define BUTTON_PIN 0 // Assumes the button is connected to pin 0
     
     
     
    // Variables to keep track of the LED brightness and button state
     
    uint8_t brightness = 100;
     
    uint8_t button_state = 0;
     
     
     
    // Function to initialize the TIMER for PWM mode
     
    void init_timer() {
     
     // Enable clock for TIM4
     
     RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
     
     
     
     // Set prescaler and period for TIM4
     
     TIM4->PSC = 47; // 48 MHz / 48 = 1 MHz
     
     TIM4->ARR = 100; // PWM frequency = 1 MHz / 100 = 10 KHz
     
     
     
     // Set PWM mode for channel 1
     
     TIM4->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
     
     
     
     // Enable output for channel 1
     
     TIM4->CCER |= TIM_CCER_CC1E;
     
     
     
     // Enable TIM4
     
     TIM4->CR1 |= TIM_CR1_CEN;
     
    }
     
     
     
    // Function to initialize the button
     
    void init_button() {
     
     // Enable clock for GPIOA
     
     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
     
     
     
     // Set button pin as input
     
     GPIOA->MODER &= ~(3 << (BUTTON_PIN * 2));
     
     
     
     // Enable pull-up resistor for button pin
     
     GPIOA->PUPDR |= (1 << (BUTTON_PIN * 2));
     
    }
     
     
     
    // Function to debounce the button
     
    uint8_t debounce_button() {
     
     static uint8_t button_count = 0;
     
     if (GPIOA->IDR & (1 << BUTTON_PIN)) {
     
     // Button is not pressed
     
     button_count = 0;
     
     return 0;
     
     } else {
     
     // Button is pressed
     
     button_count++;
     
     if (button_count == 50) {
     
     button_count = 0;
     
     return 1;
     
     } else {
     
     return 0;
     
     }
     
     }
     
    }
     
     
     
    int main() {
     
     // Initialize TIM4 and the button
     
     init_timer();
     
     init_button();
     
     
     
     // Set initial duty cycle for TIM4
     
     TIM4->CCR1 = brightness;
     
     
     
     while (1) {
     
     if (debounce_button()) {
     
     // Decrease LED brightness and set duty cycle for TIM4
     
     if (brightness > 5) {
     
     brightness -= 5;
     
     TIM4->CCR1 = brightness;
     
     }
     
     // Increase LED brightness and set duty cycle for TIM4
     
     else {
     
     brightness += 5;
     
     TIM4->CCR1 = brightness;
     
     }
     
     }
     
     }
     
    }
     

    S.Ma
    Principal
    January 17, 2023

    DIY :

    Can you make a code example for STM32F4 so that every time I press a button the brightness of the LED decreases and once it reaches the minimum (5th button press), it increases back again after every button press. Assume that the LED dimming is done by TIMER in PWM mode, and that the core frequency is 48 MHz. Make sure the code includes a button debounce functionality.

    Javier1
    Principal
    January 17, 2023

    we live in an amazing time

    hit me up in https://www.linkedin.com/in/javiermuñoz/
    waclawek.jan
    Super User
    January 17, 2023

    Now putting aside both the fact that it's incomplete (e.g. there's no LED pin initialization in GPIO) and incorrect (the "output" loop would rapidly alternate between 5 and 10; also, amazingly, ARR is not corrected for -1 as PSC is), most striking for me is, that it's register-based.

    JW

    S.Ma
    Principal
    January 17, 2023

    I didn't include chatGPT code comments (DYI). Have you tried asking to use LL or HAL? With the x570 upgrade, the trend is promising.

    waclawek.jan
    Super User
    January 17, 2023

    > I didn't include chatGPT code comments (DYI).

    Do they explain the choice of register-based approach, or the fact that it's incorrect?

    > Have you tried asking to use LL or HAL?

    I am not really interested. I was just amused, that after decades of ST promoting "libraries" of various sorts (honestly, there may be more SPL-based code out there than Cube/HAL or Cube/LL based) it chose register-based code by default. What was the training base here? There's not that much register-based STM32 code out there.

    JW

    gbm
    Lead III
    January 17, 2023

    So we will proably not starve to death that soon. The AI-produced code is not only incorrect (it does not debounce anything), it's not even proper ANSI C.

    My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
    Javier1
    Principal
    January 18, 2023

    the AI apocalypse gets postponed again

    hit me up in https://www.linkedin.com/in/javiermuñoz/