1

In my ST32L c application I want to speed up the blinking LEDs. With the code below I can press the button and the LEDs will blink faster. When I release, the LEDs will blink normal.

How can I check if a button is pressed for minimal 2 seconds and after that speed up the LEDs?

int i = 0;
    while (1) {
        bool wasSwitchClosedThisPeriod = false;
        while (i++ < speed) {
            // Poll the switch to see if it is closed.
            // The Button is pressed here
            if ((*(int*)(0x40020010) & 0x0001) != 0) {
                wasSwitchClosedThisPeriod = true;
            }
        }
        // Blinking led
        *(int*) (0x40020414) ^= 0xC0; 

        i = 0;

        if (wasSwitchClosedThisPeriod) {

            speed = speed * 2;

            if (speed > 400000) {

                speed = 100000;
            }  
        }   
    }
Bence Kaulics
  • 7,066
  • 7
  • 33
  • 63
Mvz
  • 507
  • 3
  • 11
  • 29

2 Answers2

1

You need to use on-chip hardware timers in the microcontroller. The easiest way is to have a repetitive timer which increases a counter every x time units. Let the timer ISR poll the button port. If the button is found inactive, reset the counter, otherwise increase it. Example:

static volatile uint16_t button_count = 0;

void timer_isr (void)  // called once per 1ms or so
{
  // clear interrupt source here

  if((button_port & mask) == 0)
  {
    button_count = 0;
  }
  else
  {
    if(button_count < MAX)
    {
      button_count++;
    }
  }
}

...

if(button_count > 2000)
{
  change speed
}

This way you also get the signal de-bouncing of the button for free. De-bouncing is something that you must always have and your current code seems to lack it.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

Without ISR you should have something in your loop that at least guarantees, that an amount of time has been elapsed (sleep/wait/delay for some milliseconds) and counters.

renonsz
  • 571
  • 1
  • 4
  • 17