2
\$\begingroup\$

I am using a STM32 Nucleo MCU and trying to pull a multi-function single-button method.

I need a way to implement this form of functionality for a single push-button:

  • Push 1: function 1
  • Push 2: function 2
  • Push 3: function 3
  • Push 4: function 4 + reset/loop back to before Push 1

I tried using a sort of counter variable like:

if(GPIO_Pin == Pin){
    Counter++;
    if(Counter == 1){
        function1();
    }else if(Counter == 2){
        function2();
    }else if(Counter == 3){
        function3();
    }else if(Counter == 4){
        function4();
        Counter = 0;
    }
}

But then the problem I faced is - I had to place these conditional statements inside a while(1) loop - so it keeps running. Here the Counter variable becomes unreliable since the while loop will increment the Counter variable too many times.

I tried using GPIO_EXTI - which are interrupt callbacks. Even when I call the functions using with External Interrupt Mode with Rising Edge trigger detection I am having the same problem with the counter variable increment multiple times.

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == Pin){
            Counter++;
            if(Counter== 1){
                func1();            
            }else if(Counter== 2){
                func2();
            }else if(Counter== 3){
                func3();
            }       
    }
} 

Is there any way around this rather than just use more buttons? Or any way to implement a multi-function single-button method different from the counter method I thought of?

\$\endgroup\$
  • 3
    \$\begingroup\$ First you will need to learn about debouncing. Likely what you want to do is to ignore the input for maybe 150 ms after each time you detect it pressed. And you may not want to run this out of an interrupt service routine, but either set a volatile flag to trigger a run at an opportune time in the main loop. Or if the main loop is simple, cease using an interrupt at all and simply poll the gpio. \$\endgroup\$ – Chris Stratton May 4 at 20:08
  • 1
    \$\begingroup\$ @Toor volatile does not have anything in common with cache. It does not guarantee cache coherency. \$\endgroup\$ – P__J__ May 4 at 20:53
  • 4
    \$\begingroup\$ @Toor you did and never read from cache. volatile just informs the compiler that the object is side effect prone \$\endgroup\$ – P__J__ May 4 at 21:02
  • 3
    \$\begingroup\$ @Toor Some people think of that as a form of caching I think you are alone in this opinion as it does not have anything common with caching. It is just simple optimization and it does not happen if the optimizations are off. \$\endgroup\$ – P__J__ May 4 at 21:26
  • 1
    \$\begingroup\$ @P__J__ Go read around. Some people call it that. Either way, this is getting into an argument about semantics and disabling optimizations is throwing the baby out with the bathwater. \$\endgroup\$ – DKNguyen May 4 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.