STM8 板的按钮切换问题

问题描述

我是微控制器的初学者。我正在使用定制的 STM8 板并使用板载按钮计算按下的次数。我无法使其正常工作,这是我的代码,如果可以,请提供帮助 - 交换机已连接到 PA1。相关代码段-

void setup()
{
  GPIO_DeInit(GPIOA);
  GPIO_DeInit(GPIOB);
  GPIO_DeInit(GPIOC);
  GPIO_DeInit(GPIOD);

  GPIO_Init(GPIOA,GPIO_PIN_1,GPIO_MODE_IN_PU_IT); // **PA1 SWITCH**
}

void scan()
{

  if (GPIO_ReadInputPin(GPIOA,GPIO_PIN_1) == 0)
  {
    do 
    {
    }
    while(GPIO_ReadInputPin(GPIOA,GPIO_PIN_1) == 0);
    
    key_count++;
  }    
}    

解决方法

这里有很多猜测,但由于您似乎在轮询按钮而不是使用中断,因此您的初始化不正确:

GPIO_Init( GPIOA,GPIO_PIN_1,GPIO_MODE_IN_PU_NO_IT ) ; 
//                                            ^^^

感谢@Sorenp 在评论中发现这一点

即使使用正确的输入模式,scan() 函数也会阻塞(当按住按钮时,您的程序将停止执行任何有用的操作),并且不提供开关去抖动(开关很少干净地改变状态)。因此,我建议使用去抖动时间进行非阻塞轮询:

#define DEBOUNCE_MILLIS 20

void scan()
{
    // Button states
    typedef enum
    {
        BTN_DN = 0,BTN_UP = 1
    } tBtnState  ;

    static tBtnState  previous_button_state = (tBtnState)GPIO_ReadInputPin(GPIOA,GPIO_PIN_1) ;
    static unsigned long timestamp = 0 ;

    tBtnState  current_button_state = (tBtnState)GPIO_ReadInputPin(GPIOA,GPIO_PIN_1) ; 

    // If button down...
    if( current_button_state == BTN_DN )
    { 
        // ... and was previously up (transition event)...
        if( previous_button_state == BTN_UP )
        {
            timestamp = millis() ;
            previous_button_state = BTN_DN ;

            key_count++ ;
        }
    }
    // If button has been released for at least the debounce period...
    else if( millis() - timestamp > DEBOUNCE_MILLIS )
    {
        previous_button_state = BTN_UP ;
    }
}    

然后,您可以在执行代码需要执行的任何其他操作时“频繁地”调用 scan()

void main()
{
    // Initialise
    setup() ;

    // executive loop
    for(;;)
    {
        // Count button presses
        scan() ;

        // Do other stuff
    }
}

scan() 处理它自己的时间,所以不需要以特定的速率调用 - 足够快以捕捉任何按钮按下,所以你在循环中做的任何其他事情都必须同样是非阻塞的,这样循环进行迭代,到达 scan() 的时间不会超过 100 毫秒。

既然你把它标记为 [arduino],我假设 Arduino millis() 函数可用,但不清楚这是否真的是 Arduino 代码。根据需要替换您自己的计时函数或标准库 clock()