facebook pixel מדריך: פירוט שפת תכנות - פסיקות - ()attachInterrupt - www.4project.co.il
Main logo www.4project.co.il
כל הרכיבים לפרוייקט שלכם
עגלת קניות

העגלה ריקה

לקוחות נכבדים, אלה שעות הפעילות של המחסן במהלך יום העצמאות:
ביום הזכרון/ערב עצמאות (יום שני 13/05) - המחסן סגור
יום עצמאות (יום שלישי 14/05) - המחסן סגור
נחזור לפעילות רגילה ביום רביעי 15/05
יום עצמאות שמח (עד כמה שאפשר).

פירוט שפת תכנות - פסיקות - ()attachInterrupt


2022-06-14 09:50:30
פונקציית ()attachInterrupt מצמידה פונקציה לטיפול בפסיקה (interrupt) חיצונית.

שימוש בפסיקות

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

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

הסבר על ISR

ISR היא פונקציית טיפול בפסיקות (Interrupt Service Routine). פונקציית ISR היא פונקציה מיוחדת ויש עליה מגבלות שלפונקציות רגילות אין. ל-ISR אין פרמטרים והיא גם לא מחזירה ערכים.

כעקרון,פונקציית ISR צריכה להיות קצרה ומהירה עד כמה שאפשר. אם התוכנית שלכם משתמשת בכמה פסיקות, רק פונקציית ISR אחת יכולה להתבצע בכל רגע נתון, פונקציות ISR אחרות יתבצעו בסדר שתלוי בהגדרת העדיפויות בין הפסיקות אחרי שזאת תסתיים .
פונקציית ()millis מסתמכת על הפסיקות, כך שהערך שלה לא יתקדם בתוך ISR. מכיוון שפונקציה ()delay דורשת שהפיסקות יעבדו, היא לא תוכל לעבוד אם נקראת מתוך ISR. פונקציה ()micros תעבוד בהתחלה, אבל התוצאות יהיו לא יציבות אחרי כ-1-2 מילישניות. פונקציה ()delayMicroseconds לא משתמשת במשאבים חיצוניים, כך שהיא כן תעבוד.

בדרך כלל משתמשים במשתנים גלובליים כדי להעביר מידע מ-ISR לתוכנית הראשית. כדי שערכי המשתנים יהיו מעודכנים בצורה נכונה בתוכנית הראשית, צריך להגדיר אותם כ-volatile.

פסיקות וקווים דיגיטליים

הפרמטר הראשון של פונקציית ()attachInterrupt הוא מספר הפסיקה. מומלץ להשתמש בפונקציית המרה digitalPinToInterrupt(pin) כדי לתרגם את מספר הקו שמחובר לחיישן למספר הפסיקה. לדוגמה, אם אתם משתמשים בקו מספר 3, העבירו digitalPinToInterrupt(3) כפרמטר ראשון לפונקציית ()attachInterrupt. מספרי הקווים ומספרי הפסיקות שונה לכל סוג של כרטיס, שימוש במספר פסיקה ישירות יכול להיראות כדרך הפשוטה ביותר, אבל זה יכול לגרום לבעיות תאימות אם התוכנה שלכם צריכה לרוץ על סוגי כרטיסים שונים.

אלה הקווים מהם אפשר לקבל פסיקה בכרטיסים השונים:
  • UNO, Nano, Mini ואחרים המבוססים על בקר 328 - קווים 2, 3
  • Mega, Mega2560, MegaADK - קווים 2, 3, 18, 19, 20, 21
  • Micro, Leonardo ואחרים המבוססים על בקר 32u4 - קווים 0, 1, 2, 3, 7
  • Zero - כל הקווים הדיגיטליים חוץ מקו 4
  • MKR1000 Rev.1 - קווים 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
  • Due - כל הקווים הדיגיטליים
  • 101 - כל הקווים הדיגיטליים, רק הקווים 2, 5, 7, 8, 10, 11, 12, 13 יעבדו במצב CHANGE


תחביר

קוד: בחר הכל
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); (recommended)
attachInterrupt(interrupt, ISR, mode); (not recommended)
attachInterrupt(pin, ISR, mode); (not recommended Arduino Due, Zero, MKR1000, 101 only)

פרמטרים:
interrupt - מספר ישיר של פסיקה, מסוג int (לא מומלץ להשתמש בגישה זו)
pin - מספר הקו של הכרטיס
ISR - שם הפונקציה שתקרא לביצוע הפסיקה. הפונקציה לא מקבלת פרמטרים ולא מחזירה ערכים.
mode - מגדיר מתי הפסיקה צריכה להיות מופעלת. ישנם מספר קבועים שאפשר להעביר כפרמטר:
  • LOW - הפסיקה תופעל כשהקו יהיה ב-"0" לוגי
  • CHANGE - הפסיקה תופעל כשהקו ישנה את מצבו
  • RISING - הפסיקה תופעל כשהקו משתנה מ-"0" ל-"1" לוגי
  • FALLING - הפסיקה תופעל כשהקו משתנה מ-"1" ל-"0" לוגי
  • HIGH (לכרטיסים Arduino Due, Zero, MKR1000 בלבד) - הפסיקה תופעל כשהקו יהיה ב-"1" לוגי

פונקציה זו לא מחזירה ערכים.


דוגמה

קוד: בחר הכל
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}


שימו לב:
בתוך הפונקציה שמוצמדת לפסיקה: ()delay לא יעבוד, ערכים שחוזרים מ-()millis לא יתעדכנו. נתונים שמגיעים בתקשורת טורית יכולים ללכת לאיבוד בזמן שמתבצע ISR. כל המשתנים שמשנים אותם מתוך ה-ISR ונקראים מחוצה לה צריכים להיות מוגדרים כ-volatile.


ראו גם:

()detachInterrupt

פירוט שפת תכנות לסביבת Arduino


עמוד זה הוא תרגום של ()attachInterrupt לפי רישיון Creative Commons Attribution-ShareAlike 3.0.