简体   繁体   中英

How do I turn on LED while pressing and releasing the push button once and then turn it off by pressing and releasing it again?

I am trying to turn on LED by pressing and releasing the button once and turn it off by pressing and releasing it again and so on. I wrote a bunch of code together but I'm not sure if it sounds right. I mean I don't know if it's my breadboard or loose connection but not sure if it works as expected. I know that the wiring is correct as simply turning it on while pressing the button and turning it off by releasing the button works. Any help is much appreciated. Thank you.

Here is the code:

//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;
  }

You have several problems.

The first one might be linked to debouncing. When you press the button, the electrical signal is actually oscillating between two values and at the end, what your code will consider as "button is pressed a second time" might just be the bouncing of the switch.

Also, when your code detects a button press, it doesn't wait for the button to be released, it is only turning the LED on and immediatly checking whether the button has been released. It will not work in all cases (anyway your code is doing nothing new in if(~(GPIOB->IDR &(GPIO_IDR_1))) ...).

Then it will probably not work anyway because the way you coded it, you will lost many "press" events. Use interrupts instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM