Menu
CoddyTech

שיתוף באמצעות volatile

חלק מהיחידה תזמון ללא Delay במסלול ה-Arduino של Coddy. שיעור 14 מתוך 18.

ISR אמור לבצע פעולה מהירה אחת, ולכן בדרך כלל הוא מגדיר משתנה ששאר הסקץ' קורא. משתנה ששניהם משתמשים בו חייב להיות מוכרז בתור volatile:

volatile bool started = false;

void onPress() {
  started = true;
}

כדי לחסוך זמן, המהדר (התוכנית שהופכת את ה-C++ שלך להוראות של השבב) עשוי לשמור עותק של משתנה בתוך המעבד במקום לקרוא מהזיכרון. הוא לא יודע שפסיקה יכולה לשנות את המשתנה, ולכן הסקץ' עלול להשתמש בעותק הישן לנצח. volatile גורם לו לקרוא את המשתנה מחדש בכל פעם.

הסקץ' הזה ממתין בתוך setup() באמצעות לולאת while: while (condition) { } חוזרת על מה שבתוך הסוגריים המסולסלים כל עוד התנאי אמת, ובמקרה הזה !started. כמו ביחידת הקלטים, ! פירושו לא: הלולאה חוזרת כל עוד started הוא false. בלי volatile, היא עלולה להמתין לנצח, אפילו אחרי הלחיצה.

challenge icon

אתגר

קל

הסקץ' הזה אמור להמתין עד ללחיצה על הכפתור, ואז להבהב את ה-LED. כרגע הוא ממתין לנצח. תקן אותו:

  • ב-onPress(), הגדר את started ל-true
  • הכרז על started כ-volatile

לחץ על Run, לחץ על הכפתור, ואז על Check. נסה פעם אחת בלי volatile כדי לראות את הלוח נתקע.

נסו בעצמכם

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

bool started = false;   // נקבע על ידי הפסיקה, נקרא על ידי הסקץ׳

unsigned long previousMillis = 0;
int ledState = LOW;

void onPress() {
  // הגדר כאן את started ל־true
}

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

  // המתן כאן עד ללחיצה על הכפתור
  while (!started) {
  }
}

void loop() {
  // הבהב כל 250 ms
  unsigned long now = millis();
  if (now - previousMillis >= 250) {
    previousMillis = now;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תזמון ללא Delay

תרגלו בעצמכם: Arduino אונליין