Menu
CoddyTech

Chia sẻ dữ liệu với volatile

Thuộc phần Định thời không dùng delay trong hành trình Arduino của Coddy. Bài học 14 trên 18.

ISR nên thực hiện một việc nhanh chóng, vì vậy nó thường đặt một biến để phần còn lại của sketch đọc. Biến được cả hai bên sử dụng phải được khai báo là volatile:

volatile bool started = false;

void onPress() {
  started = true;
}

Để tiết kiệm thời gian, trình biên dịch (chương trình chuyển C++ thành các lệnh của chip) có thể giữ một bản sao của biến bên trong bộ xử lý thay vì đọc bộ nhớ. Nó không biết ngắt có thể thay đổi biến, vì vậy sketch có thể dùng bản sao cũ mãi mãi. volatile khiến chương trình đọc lại giá trị mới nhất của biến mỗi lần.

Sketch này chờ trong setup() bằng một vòng lặp while: while (condition) { } lặp lại phần nằm trong dấu ngoặc nhọn chừng nào điều kiện còn đúng, ở đây là !started. Như trong phần Đầu vào, ! có nghĩa là phủ định: vòng lặp tiếp tục khi started là false. Không có volatile, chương trình có thể chờ mãi mãi, ngay cả sau khi nhấn nút.

challenge icon

Thử thách

Dễ

Bản sketch này cần chờ đến khi nút được nhấn, sau đó nhấp nháy đèn LED. Hiện tại, nó chờ mãi. Hãy sửa lại:

  • trong onPress(), đặt started thành true
  • khai báo started là volatile

Nhấn Chạy, nhấn nút, rồi nhấn Kiểm tra. Hãy thử một lần không dùng volatile để thấy bo mạch bị treo.

Tự làm thử

const int ledPin = 13;
const int buttonPin = 2;

bool started = false;   // Ngắt đặt giá trị, sketch đọc giá trị

unsigned long previousMillis = 0;
int ledState = LOW;

void onPress() {
  // Đặt started thành true tại đây
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);

  // Chờ tại đây cho đến khi nút được nhấn
  while (!started) {
  }
}

void loop() {
  // Nhấp nháy mỗi 250 ms
  unsigned long now = millis();
  if (now - previousMillis >= 250) {
    previousMillis = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Định thời không dùng delay

Tự luyện tập: Playground Arduino