我对C和Raspberry Pi相对较新,并且正在尝试简单的程序。我想要的是当按下按钮时它会一次打印一次,直到再次按下该按钮时才再次打印一次,即使按住该按钮(有点像闩锁)。我以为也许添加第二个while循环可以解决此问题,但是有时它仍然无法检测到按钮按下。
#include <bcm2835.h>
#include <stdio.h>
#define PIN RPI_GPIO_P1_11
int main()
{
if(!bcm2835_init())
return 1;
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
while(1)
{
if(bcm2835_gpio_lev(PIN))
{
printf("The button has been pressed\n");
}
while(bcm2835_gpio_lev(PIN)){}
}
bcm2835_close();
return 0;
}
最佳答案
对于像这样的简单程序,可以使用已完成的繁忙循环。但是,我建议您养成这种习惯,因为除玩具项目外,这通常是 Not Acceptable 。
防弹跳按钮的方式与编写代码的方式一样多。在某些情况下,可以采用硬件来完成此操作,但这并非没有缺点。无论如何,由于这是一个编程站点,因此假设您无法(或不想)更改硬件。
一种快速而肮脏的修改是定期检查主循环中的按钮,并且只有在按钮已更改时才采取措施。由于您是C和嵌入式编程的新手,因此我将避免使用计时器和中断,但是您知道一旦了解它们,就可以使代码更易于理解和维护。
#include <bcm2835.h>
#include <stdio.h>
#define PIN RPI_GPIO_P1_11
// A decent value for the number of checks varies with how "clean" your button is, how
// responsive you need the system to be, and how often you call the helper function. That
// last one depends on how fast your CPU is and how much other stuff is going on in your
// loop. Don't pick a value above UINT_MAX (in limits.h)
#define BUTTON_DEBOUNCE_CHECKS 100
int ButtonPress()
{
static unsigned int buttonState = 0;
static char buttonPressEnabled = 1;
if(bcm2835_gpio_lev(PIN))
{
if(buttonState < BUTTON_DEBOUNCE_CHECKS)
{
buttonState++;
}
else if(buttonPressEnabled)
{
buttonPressEnabled = 0;
return 1;
}
}
else if(buttonState > 0 )
{
buttonState--;
// alternatively you can set buttonState to 0 here, but I prefer this way
}
else
{
buttonPressEnabled = 1;
}
return 0;
}
int main()
{
if(!bcm2835_init())
return 1;
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_INPT);
while(1)
{
if(ButtonPress())
{
printf("The button has been pressed\n");
}
// the rest of your main loop code
}
bcm2835_close();
return 0;
}
关于C编程一个按钮以在按下时执行一次任务(闩锁),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16306901/