C++ 如何在按下并释放按钮一次时打开LED,然后再次按下并释放按钮将其关闭?

C++ 如何在按下并释放按钮一次时打开LED,然后再次按下并释放按钮将其关闭?,c++,stm32,bare-metal,stm32f3,C++,Stm32,Bare Metal,Stm32f3,我试图通过按下并松开按钮一次来打开LED,然后再按下并松开按钮来关闭LED,以此类推。我一起写了一堆代码,但我不确定它听起来是否正确。我的意思是,我不知道这是我的试验板还是连接松动,但不确定它是否能按预期工作。我知道接线是正确的,只要在按下按钮的同时打开它,然后松开按钮将其关闭即可。非常感谢您的帮助。多谢各位 代码如下: //Reset and clock control - Advanced high-performance bus - Enabling GPIO Port C pin 6 a

我试图通过按下并松开按钮一次来打开LED,然后再按下并松开按钮来关闭LED,以此类推。我一起写了一堆代码,但我不确定它听起来是否正确。我的意思是,我不知道这是我的试验板还是连接松动,但不确定它是否能按预期工作。我知道接线是正确的,只要在按下按钮的同时打开它,然后松开按钮将其关闭即可。非常感谢您的帮助。多谢各位

代码如下:

//Reset and clock control - Advanced high-performance bus - Enabling GPIO Port C pin 6 and Port B pin 1
RCC -> AHBENR |= RCC_AHBENR_GPIOCEN;
RCC -> AHBENR |= RCC_AHBENR_GPIOBEN;

//Setup Control Registers for the LED output
//Mode register as Output
GPIOC -> MODER |= GPIO_MODER_MODER6_0;
GPIOC -> MODER &= ~(GPIO_MODER_MODER6_1);
//OtypeR - Push pull
GPIOC -> OTYPER &= ~(GPIO_OTYPER_OT_6);
//OspeedR - High
GPIOC -> OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6;
//PUPDR
GPIOC -> PUPDR &= ~(GPIO_PUPDR_PUPDR6);

//Setup control registers for the push button input
//Mode register as input
GPIOB -> MODER &= ~(GPIO_MODER_MODER1);
//Pull up pull down register
GPIOB -> PUPDR &= ~(GPIO_PUPDR_PUPDR1); // Connected to ground externally (no need for internal pupdr
int counter = 0;

  while (1)  {
  //If the button is pressed (IDR - input data register)
  if((GPIOB -> IDR & (GPIO_IDR_1)) && counter == 0) //If button is pressed
  {
      GPIOC -> BSRR |= GPIO_BSRR_BS_6; //Turn ON the LED
      if(~(GPIOB->IDR &(GPIO_IDR_1))) // If the button is released
      {
          GPIOC -> BSRR |= GPIO_BSRR_BS_6; //LED stays ON
      }
  }
  counter = 1;

  if((GPIOB -> IDR & (GPIO_IDR_1)) && counter == 1) //If button is pressed
  {
      GPIOC -> BRR |= GPIO_BRR_BR_6; //Turn OFF the LED
      if(~(GPIOB -> IDR &(GPIO_IDR_1))) // If the button is released
      {
          GPIOC -> BRR |= GPIO_BRR_BR_6; //LED stays OFF
      }
  }
  counter = 0;
  }

你有几个问题

第一个可能与去抖动有关。当你按下按钮时,电信号实际上在两个值之间振荡,在最后,你的代码将被认为是“第二次按下按钮”可能只是开关的跳动。 此外,当您的代码检测到按钮按下时,它不会等待按钮释放,它只是打开LED并立即检查按钮是否已释放。它不会在所有情况下都起作用(无论如何,您的代码在
if(~(GPIOB->IDR&(GPIO\u IDR\u 1))
中没有任何新功能)


那么它可能无论如何都不会工作,因为按照您编写它的方式,您将丢失许多“新闻”事件。使用中断代替。

您应该在内部if条件内设置计数器。为什么不根据
if(B中断){if(计数器)…else…counter=!counter}
if(C中断){/*same logic*/}
来做出决定,这样您只有在中断准备就绪时才做出响应,即使基本上在每个内部复制了打开/关闭逻辑。您是否考虑过启用中断处理程序——如果stm32上有中断处理程序?我还没有在stm32上启动中断。如果没有中断,这段代码不会仍然工作吗?当然,无论您如何触发条件,相同的逻辑都会工作。你可以直接从pin中读取,而不用中断。“开关去抖动”是关键词,请搜索它。按钮上的中断是一个巨大的问题。如果您使用中断,您可以使用它们和计时器来定期对按钮进行采样……在学习过程中或在某些应用程序中,哪个轮询也可以非常好地工作,成功的几率更大。如果你不能通过轮询解决问题,那么你也会因为中断而失败,再加上发现中断的风险。你是指去抖动问题吗?我同意这很棘手,但还有其他问题吗?(在管理带有中断的按钮时)去抖动就足够了。。。