1
votes

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;
            }  
        }   
    }
2

2 Answers

1
votes

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.

1
votes

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.