stmSTM32L476 按键控制led闪烁

下面的代码:
按一下按键,led一直保持闪烁。
怎样才能改成,按一下按键,led保持闪烁,然后再按一下,led停止闪烁。以此类推
我试过在while(1)里面加上一个另外一个while(GPIOC->IDR & (1 << BUTTON_PIN)); 去检测按键是否按下,但是没有按上述要求工作
谢谢

while(1){
        GPIOA->ODR |= 1 << LED_PIN;   //led亮
        delayMs(50); // Call the delay function
        GPIOA->ODR &= ~(1 << LED_PIN);  //led 灭
        delayMs(50); // Call the delay function
        while(GPIOC->IDR & (1 << BUTTON_PIN)); 
        GPIOA->ODR &= ~(1 << LED_PIN);   //led灭
    }

下面是按一下键可以让led循环闪烁

#include "stm32L476xx.h"

#define LED_PIN 5 
#define BUTTON_PIN 13

void delayMs(int n);

void toggleLed();

int main(void) {
    //enable clock for GPIOA and GPIOC
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; 
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;    

    // Configure LED2 pin as output
    GPIOA->MODER &= ~(3UL << (2 * LED_PIN)); 
    GPIOA->MODER |=  (1UL << (2 * LED_PIN)); 

    // Configure button pin as input
    GPIOC->MODER &= ~(3UL << (2 * BUTTON_PIN)); 

    // Configure button with no pull-up or pull-down
    GPIOC->PUPDR &= ~(3UL << (2 * BUTTON_PIN));
    
        
    while(GPIOC->IDR & (1 << BUTTON_PIN)); //wait for button press
    while(1){
        GPIOA->ODR |= 1 << LED_PIN;
        delayMs(50); // Call the delay function
        GPIOA->ODR &= ~(1 << LED_PIN);
        delayMs(50); // Call the delay function
    }
}

        


/* 16 MHz SYSCLK */
void delayMs(int n) {
    int i;
    for (; n > 0; n--)
        for (i = 0; i < 3195; i++);
}

为了让LED在按一次按键后闪烁,再按一次按键后停止闪烁,您可以在代码中添加一个变量来跟踪LED的状态。每次按下按键时,您可以在代码中使用这个变量来切换LED的状态。在while循环中加入if语句来检测按键是否按下,如果按键按下,切换LED的状态,如果LED当前是灭的,就让它亮,如果LED当前是亮的,就让它灭。

int led_state = 0;
while(1){
    if(!(GPIOC->IDR & (1 << BUTTON_PIN))){
        led_state = !led_state;
        while(!(GPIOC->IDR & (1 << BUTTON_PIN)));
    }
    if(led_state){
        GPIOA->ODR |= 1 << LED_PIN;   //led亮
        delayMs(50); // Call the delay function
        GPIOA->ODR &= ~(1 << LED_PIN);  //led 灭
        delayMs(50); // Call the delay function
    }
}


这样就可以实现按键控制LED闪烁。
另外,如果您想要在按键按下时立即停止闪烁,可以在if语句中将LED状态立即设置为灭,而不是等待下一个while循环迭代。

int led_state = 0;
while(1){
    if(!(GPIOC->IDR & (1 << BUTTON_PIN))){
        led_state = !led_state;
        if(led_state){
            GPIOA->ODR |= 1 << LED_PIN;   //led亮
        }else{
            GPIOA->ODR &= ~(1 << LED_PIN);  //led 灭
        }
        while(!(GPIOC->IDR & (1 << BUTTON_PIN)));
    }
    if(led_state){
        delayMs(50); // Call the delay function
        GPIOA->ODR ^= 1 << LED_PIN;   //led状态取反
        delayMs(50); // Call the delay function
    }
}


这样就可以实现按键控制LED闪烁。
如果您还有其他问题,请随时告诉我。
望采纳。

应该是判断方式错误;你应该给个flag额外参数,默认值0,按下点亮,赋值flag为1,再按下判断flag值,假如是1,就执行熄灭指令;假如是0,就点亮,再次赋值为1

用 printf 打印一下:GPIOC -> IDR &(1<< BUTTON _ PIN) 看看

STM32L476 按键控制 LED 闪烁示例程序大致如下:

初始化:配置相应的 IO 口为输入或输出,配置 LED 引脚为输出。

循环执行:读取按键状态,如果按键按下,LED 亮,否则 LED 灭。

延时:用于控制 LED 闪烁频率。

代码如下

#include "stm32l4xx_hal.h"

int main(void)
{
    // 初始化:配置相应的 IO 口为输入或输出,配置 LED 引脚为输出。
    // 按键状态变量
    uint8_t button_state;
    // LED 状态变量
    uint8_t led_state = 0;

    while (1)
    {
        // 读取按键状态
        button_state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
        // 如果按键按下
        if (button_state == GPIO_PIN_RESET)
        {
            // LED 亮
            led_state = 1;
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
        }
        else
        {
            // LED 灭
            led_state = 0;
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
        }
        // 延时
        HAL_Delay(1000);
    }
}

请注意,上述代码仅是一个示例。实际应用中还需要进行各种配置和初始化,这些工作可以使用各种库函数来完成。

int blink_flg = 0;//LED闪烁标志初始化

while(1){
    if (GPIOC->IDR & (1 << BUTTON_PIN))//按键检测
    {
            delayMs(20); //按键去抖动
            if (GPIOC->IDR & (1 << BUTTON_PIN))//按键确认
            {
                    if (blink_flg == 0)
                     {
                              blink_flg  = 1;//LED闪烁标志置位
                     }
                     else
                     {
                               blink_flg  = 0;//LED闪烁标志清零
                      } 
            }
    }
    if (blink_flg == 1)//检查LED闪烁标志
    {
        //LED闪烁
        GPIOA->ODR |= 1 << LED_PIN;
        delayMs(50); // Call the delay function
        GPIOA->ODR &= ~(1 << LED_PIN);
        delayMs(50); // Call the delay function
     }
     else
     {
         //led灭
         GPIOA->ODR &= ~(1 << LED_PIN);
     } 
}