Menu
CoddyTech

Współdzielenie z volatile

Część sekcji Odmierzanie czasu bez delay() ścieżki Arduino w Coddy. Lekcja 14 z 18.

ISR powinno wykonywać jedną szybką czynność, dlatego zwykle ustawia zmienną, którą odczyta reszta szkicu. Zmienna używana przez oba elementy musi być zadeklarowana jako volatile:

volatile bool started = false;

void onPress() {
  started = true;
}

Aby zaoszczędzić czas, kompilator (program, który zamienia Twój kod C++ na instrukcje dla układu) może przechowywać kopię zmiennej w procesorze zamiast odczytywać ją z pamięci. Nie wie, że przerwanie może zmienić tę zmienną, więc szkic może bez końca używać starej kopii. volatile sprawia, że za każdym razem odczytywana jest aktualna wartość zmiennej.

Ten szkic czeka w setup() w pętli while: while (condition) { } powtarza instrukcje w nawiasach klamrowych, dopóki warunek jest prawdziwy — tutaj !started. Podobnie jak w sekcji Inputs, ! oznacza negację: pętla powtarza się, dopóki started ma wartość false. Bez volatile może czekać bez końca, nawet po naciśnięciu przycisku.

challenge icon

Wyzwanie

Łatwy

Ten szkic powinien czekać, aż przycisk zostanie naciśnięty, a następnie migać diodą LED. Teraz czeka bez końca. Napraw go:

  • w onPress() ustaw started na true
  • zadeklaruj started jako volatile

Naciśnij Run, naciśnij przycisk, a następnie Check. Spróbuj raz bez volatile, aby zobaczyć, jak płytka się zawiesza.

Spróbuj swoich sił

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

bool started = false;   // ustawiane przez przerwanie, odczytywane przez szkic

unsigned long previousMillis = 0;
int ledState = LOW;

void onPress() {
  // ustaw tutaj started na true
}

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

  // czekaj tutaj, aż przycisk zostanie naciśnięty
  while (!started) {
  }
}

void loop() {
  // migaj co 250 ms
  unsigned long now = millis();
  if (now - previousMillis >= 250) {
    previousMillis = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Odmierzanie czasu bez delay()

Poćwicz samodzielnie: Edytor online Arduino