为什么在函数内修改全局变量的值不会改变

问题描述 投票:0回答:1

我正在用 C 语言对 Raspberry Pi Pico 进行编程。我有这个 MWE:

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "hardware/uart.h"

#define UART_ID uart0
#define BAUD_RATE 2000000
#define UART_TX_PIN 0
#define UART_RX_PIN 1

uint8_t blink_LED;

void handle_uart_commands() {
    // Function to be called when data is received in the UART.
    while (uart_is_readable(UART_ID)) {
        uint8_t ch = uart_getc(UART_ID);

        switch (ch) {
            case 'b':
                printf("%d", blink_LED); // This sends "0", ok!
                blink_LED = 7;
                printf("%d", blink_LED); // This sends "7", ok!
            break;
        }
    }
}

void init_uart(void) {
    uart_init(UART_ID, BAUD_RATE);
    gpio_set_function(UART_TX_PIN, UART_FUNCSEL_NUM(UART_ID, UART_TX_PIN));
    gpio_set_function(UART_RX_PIN, UART_FUNCSEL_NUM(UART_ID, UART_RX_PIN));

    // Set up a RX interrupt:
    int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ; // Select correct interrupt for the UART we are using.
    irq_set_exclusive_handler(UART_IRQ, handle_uart_commands);
    irq_set_enabled(UART_IRQ, true);
    uart_set_irq_enables(UART_ID, true, false);
}

void init_stuff(void) {
    stdio_init_all();
    init_uart();
    hard_assert(cyw43_arch_init() == PICO_OK);
    blink_LED = 3;
}

int main() {
    init_stuff();

    while (true) {
        if (blink_LED) {
            cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
            sleep_ms(333);
            cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
            sleep_ms(333);
            blink_LED -= 1;
            printf("b"); // Indicate that the LED blinked once.
        }
    }
}

它应该做什么:

  1. 通电后 LED 闪烁 3 次。
  2. 通过 UART 串行通信接收到
    b
    后,LED 应闪烁 7 次。

它的作用:

  1. 开机时 LED 闪烁 3 次。好的!
  2. 收到
    b
    后,LED不再闪烁一次。不好。

我添加了两行

printf
只是为了查看
blink_LED
的值,并且它发送了正确的值,这意味着它正在接收并正确处理
b
。但是,LED 不闪烁。此外,
printf("b")
行在上电后仅执行3次,这意味着它永远不会回到
if (blink_LED)
。我不明白为什么。
blink_LED=7
的值是否仅在
handle_uart_commands
内有效,之后又返回到之前的值?

c global-variables
1个回答
0
投票

我通过将

blink_LED
声明为
volatile
解决了这个问题,即

volatile uint8_t blink_LED;

对于我的应用程序来说,这已经足够并且完美地工作了。但是,在最一般的情况下,仍然可能存在竞争条件,请参阅问题中的评论。

© www.soinside.com 2019 - 2024. All rights reserved.