如何解决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()
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。