באמצעות הפרעות על ארדואינו

מד דופק לב (יולי 2019).

$config[ads_text] not found
Anonim

באמצעות הפרעות על ארדואינו


ייעל את קוד Arduino שלך עם Interrupts - הדרך הפשוטה להגיב לאירועים בזמן אמת!

רמה מומלצת

ביניים

אנחנו מפסיקים את השידור הזה …

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

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

לחצן מפריע

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

 const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin // variables will change: int buttonState = 0; // variable for reading the pushbutton status void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed. // if it is, the buttonState is HIGH: if (buttonState == HIGH) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } } 

הורד קוד

מה שאתה רואה כאן זה שום דבר מזעזע או מדהים - כל התוכנית עושה, שוב ושוב, פועל באמצעות `לולאה ()`, וקורא את הערך של 'buttonPin`. נניח לרגע שרצית לעשות משהו אחר בלולאה () - משהו חוץ מקריאת סיכה. זה המקום שבו נכנסים Interrupts. במקום רק צופה זה סיכה כל הזמן, אנחנו יכולים לחוות את העבודה של ניטור כי סיכה כדי פסיקה, ללא תשלום `לולאה ()` לעשות כל מה שאנחנו צריכים לעשות את זה בינתיים! הקוד החדש ייראה כך:

 const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin // variables will change: volatile int buttonState = 0; // variable for reading the pushbutton status void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); // Attach an interrupt to the ISR vector attachInterrupt(0, pin_ISR, CHANGE); } void loop() { // Nothing here! } void pin_ISR() { buttonState = digitalRead(buttonPin); digitalWrite(ledPin, buttonState); } 

הורד קוד

לולאות ומצבי פסיקה

תראה כמה שינויים כאן. הראשון, וברור ביותר של אלה, היא כי `לולאה ()` אינו מכיל שום הוראות! אנחנו יכולים להתחמק מזה, כי כל העבודה שנעשתה בעבר על ידי הצהרה 'אם / אחר' מטופלת כעת על ידי פונקציה חדשה, 'pin_ISR () `. סוג זה של פונקציה נקרא _שגרת שירות רציפה _ - תפקידו לרוץ במהירות ולטפל בפסיקה ולתת למעבד לחזור לתוכנית הראשית (כלומר, התוכן של לולאה). יש כמה דברים חשובים לשקול בעת כתיבת שגרת שירות פסיקה, אשר אתה יכול לראות לידי ביטוי בקוד לעיל:

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

אתה בטח תוהה - איך אנחנו יודעים מתי קטע מקבל? מה מעורר אותו? הפונקציה השלישית בשגרה 'setup' היא מה שקובע את המערכת כולה. פונקציה זו, 'attachInterrupt () `, לוקחת שלושה ארגומנטים:

1. וקטור הפסיקה, אשר קובע מה סיכה יכול ליצור פסיקה. זה לא מספר הסיכה עצמה - זה בעצם התייחסות למקום שבו הזיכרון מעבד Arduino צריך להסתכל כדי לראות אם מתרחשת הפסקה. שטח נתון בווקטור זה מתאים לסיכה חיצונית מסוימת, ולא כל הפינים יכולים ליצור הפסקה! על Arduino Uno, סיכות 2 ו 3 מסוגלים לייצר interrupts, והם תואמים וקטורים פסיקה 0 ו 1, בהתאמה. לקבלת רשימה של מה סיכות זמינים כמו סיכות פסיקה, לבדוק את התיעוד Arduino על `attachInterrupt ()`.

2. שם פונקציה של שגרת שירות פסיקה - זה קובע את הקוד כי יופעל כאשר התנאי נפגשת.

3. מצב פסיקה, אשר קובע מה פעולה סיכה מפעילה פסיקה. Arduino Uno תומך ארבעה מצבי פסיקה:

* `RISING`, אשר מפעיל קטע על קצה עולה של סיכת הפסיקה,

* `נפילה`, אשר פועלת על נופל,

* "שינוי", אשר עונה על כל שינוי בערכו של פין פסיקה,

* 'LOW', אשר מפעילה בכל עת את הסיכה הוא נמוך דיגיטלי.

רק כדי לסכם - ההגדרה שלנו של `attachInterrupt ()` הוא הגדרת לנו לפקח וקטור פסיקה 0 / PIN 2, להגיב interrupts באמצעות `pin_ISR ()`, וכן להתקשר `pin_ISR ()` בכל פעם שאנו רואים כל שינוי של מצב על סיכה 2.

תנודתי - לא לנער!

עוד דבר אחד מהיר להצביע - ISR שלנו משתמש המשתנה `buttonState` לאחסן מצב סיכה. בדוק את ההגדרה של 'כפתור' - במקום סוג `int`, הגדרנו אותו כסוג` נדיף int`. מה העסקה כאן? `נדיפים` היא מילת מפתח C שחלה על משתנים. משמעות הדבר היא שהערך של משתנה זה אינו לגמרי בשליטת התוכנית. זה משקף כי הערך של 'כפתור' יכול להשתנות, ולשנות על משהו כי התוכנית עצמה לא יכול לחזות - במקרה זה, קלט המשתמש.

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

(חוץ מזה: גיזום משתנים שאינם בשימוש מהקוד הוא תכונה, לא באג, של מהדרים, אנשים יניחו לפעמים משתנים שאינם בשימוש בקוד המקור, אשר לוקח זיכרון.זה לא כזה עניין גדול אם היית כותב תוכנית C מחשב, עם ג 'יגה בייט של זיכרון RAM.בארדינו, עם זאת, RAM הוא מוגבל, ואתה לא רוצה לבזבז! אפילו תוכניות C במחשבים יעשה את זה גם, עם טונות של זיכרון מערכת זמין. אנשים סיבה לנקות campgrounds - זה נוהג טוב לא להשאיר אשפה מאחור!)

מסיימים

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

יש לך פרויקטים מגניבים עם interrupts? השאירו תגובה למטה כדי להודיע ​​לנו!