cancel
Showing results for 
Search instead for 
Did you mean: 

Doubt regarding multiple button press on STM32.

Killstreet30
Associate III

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);

}

}

}

11 REPLIES 11
gbm
Lead III

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.

S.Ma
Principal

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

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.

we live in an amazing time

we dont need to firmware by ourselves, lets talk

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

Do you have the code for this?

S.Ma
Principal

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.

> 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

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.