當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Arduino volatile用法及代碼示例

[變量範圍和限定符]

說明

volatile 是一個被稱為變量qualifier 的關鍵字,它通常用在變量的數據類型之前,以修改編譯器和後續程序對變量的處理方式。

聲明變量volatile 是編譯器的指令。編譯器是將您的 C/C++ 代碼翻譯成機器代碼的軟件,機器代碼是 Arduino 中 Atmega 芯片的真實指令。

具體來說,它指示編譯器從 RAM 而不是從存儲寄存器加載變量,存儲寄存器是存儲和操作程序變量的臨時內存位置。在某些情況下,存儲在寄存器中的變量的值可能不準確。

隻要變量的值可以通過超出其出現的代碼部分的控製範圍(例如並發執行的線程)來更改,則應聲明變量volatile。在 Arduino 中,唯一可能發生這種情況的地方是與中斷相關的代碼段,稱為中斷服務程序。

int 或長揮發物

如果 volatile 變量大於一個字節(例如 16 位 int 或 32 位長),則微控製器無法一步讀取它,因為它是 8 位微控製器。這意味著當您的主代碼部分(例如您的循環)讀取變量的前 8 位時,中斷可能已經更改了後 8 位。這將為變量生成隨機值。

補救:

在讀取變量時,需要禁用中斷,因此它們在讀取時不會弄亂這些位。做這件事有很多種方法:

  1. LANGUAGE 無中斷

  2. 使用ATOMIC_BLOCK 宏。原子操作是單個 MCU 操作 - 可能的最小單元。

示例代碼

volatile 修飾符確保對 state 變量的更改在 loop() 中立即可見。如果沒有volatile 修飾符,state 變量可能會在進入函數時加載到寄存器中,並且在函數結束之前不會再更新。

// Flashes the LED for 1 s if the input has changed
// in the previous second.

volatile byte changed = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE);
}

void loop() {
  if (changed == 1) {
    // toggle() has been called from interrupts!

    // Reset changed to 0
    changed = 0;

    // Blink LED for 200 ms
    digitalWrite(LED_BUILTIN, HIGH);
    delay(200);
    digitalWrite(LED_BUILTIN, LOW);
  }
}

void toggle() {
  changed = 1;
}

要訪問大小大於微控製器 8 位數據總線的變量,請使用 ATOMIC_BLOCK 宏。宏確保在原子操作中讀取變量,即在讀取時不能更改其內容。

#include <util/atomic.h> // this library includes the ATOMIC_BLOCK macro.
volatile int input_from_interrupt;

// Somewhere in the code, e.g. inside loop()
  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    // code with interrupts blocked (consecutive atomic operations will not get interrupted)
    int result = input_from_interrupt;
  }

相關用法


注:本文由純淨天空篩選整理自arduino.cc大神的英文原創作品 volatile。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。