קטגוריות: מעגלי מיקרו-בקר
מספר צפיות: 41940
הערות לכתבה: 5

שיטות לקריאה וניהול של יציאות קלט / פלט של Arduino

 

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

שיטות לקריאה וניהול של יציאות קלט / פלט של Arduino

שיטה ראשונה - השפה הסטנדרטית עבור ה- IDE של ארדואינו

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

יציאות נכתבות בדרך כלל בפונקציית האתחול המשתנה:

הגדרת ביטול ()
{
// קוד
}

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

pinMode (nomer_porta, naznachenie)

עם פקודה זו, המעגל הפנימי של בקר המיקרו מוגדר בצורה ספציפית.

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

pinMode (13, INPUT);

OUTPUT - פלט, בהתאם לפקודה שנקבעה בקוד, היציאה לוקחת ערך של אחד או אפס. הפלט הופך למעין מקור כוח מבוקר ומייצר זרם מרבי (במקרה שלנו 20 mA ו- 40 mA בשיא) לעומס המחובר אליו. כדי להקצות יציאה כפלט לארduino אתה צריך להזין:

pinMode (13, פלט);

INPUT_PULLUP - הפורט עובד כקלט, אך מה שנקרא מתחבר אליו. נגן משיכה 20 קילו.

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

pinMode (13, INPUT_PULLUP);

נגר למשוך קלט

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

  • digitalWrite (סיכה, ערך) - ממיר את סיכת הפלט לוגית 1 או 0 בהתאמה, מתח 5V מופיע או נעלם ביציאה, לדוגמה digitalWrite (13, HIGH) - מספק 5 וולט (יחידה לוגית) ל 13 סיכות, ו- digitalWrite (13, נמוך) ) - מתרגם 13 סיכות למצב של אפס לוגי (0 וולט);

  • digitalRead (pin) - קורא את הערך מהכניסה, לדוגמה digitalRead (10), קורא את האות מעשרה סיכות;

  • analogRead (pin) - קורא אות אנלוגי מיציאה אנלוגית, תקבל ערך בטווח שבין 0 ל- 1023 (בתוך ADC של 10 סיביות), דוגמה היא analogRead (3).


שיטה שנייה - ניהול יציאות באמצעות רישומי Atmega והאיץ את הקוד

שליטה כזו היא כמובן פשוטה, אך במקרה זה ישנם שני חסרונות - צריכת זיכרון גדולה יותר וביצועים ירודים בעבודה עם יציאות. אבל זוכר מה זה ארדואינו, ללא קשר ללוח האופציות (uno, micro, nano)? קודם כל זה בקר מיקרו - AVR משפחת ATMEGA, השתמש לאחרונה ב- MK atmega328.

ב- Arduino IDE, אתה יכול לתכנת את שפת ה- C AVR ילידת משפחה זו, כאילו אתה עובד עם מיקרו-בקר נפרד. אבל קודם דברים ראשונים. כדי לנהל נמלי ארדואינו בצורה זו, תחילה עליך לשקול בזהירות את האיור הבא.

יציאות מיקרו-בקר Atmega168

אולי מישהו יבחן בצורה ברורה יותר את היציאות בצורה זו (זהה באיור, אבל בעיצוב שונה):

יציאות מיקרו-בקר Atmega328

כאן תוכלו לראות את ההתכתבויות בין מסקנותיו של ארדואינו ושמות הנמלים של אטמגה. אז יש לנו 3 יציאות:

  • PORTB;

  • PORTC;

  • פורטד.

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

טבלת קונקורדנס של נמלים ארדואינו ואטמגה

ל- Atmega שלושה אוגרי 8 סיביות השולטים במצב היציאות, לדוגמה, יציאה B תמצא את מטרתם על ידי ציור אנלוגיות לכלי החיווט הסטנדרטיים שתוארו בתחילת מאמר זה:

  • PORTB - ניהול מצב פלט. אם הסיכה נמצאת במצב "פלט", 1 ו- 0 קובעים את נוכחותם של אותם אותות ביציאה. אם הסיכה נמצאת במצב "קלט", 1 מתחבר נגד נגרר (זהה ל- INPUT_PULLUP שנדון לעיל), אם 0 הוא מצב של עכבה גבוהה (אנלוגי של INPUT);

  • PINB הוא פנקס קריאה. בהתאם, הוא מכיל מידע על המצב הנוכחי של סיכות היציאה (יחידה לוגית או אפס).

  • DDRB - פנקס כיוון יציאה. בעזרתו אתה מציין למיקרו-בקר מה היציאה ככניסה או פלט, עם "1" פלט ו "0" כניסה.

במקום האות B, יכול להיות כל אחד אחר לפי שמות היציאות, לדוגמה, פקודות PORTD או PORTC פועלות באופן דומה.

אנו ממצמצים את נורית LED, מחליפים את פונקציית digitalWrite הסטנדרטית (). ראשית, נזכיר כיצד נראית הדוגמא המקורית מספריית ה- Arduino IDE.

קוד מהבהב של ארדואינו

זהו הקוד של ה"מצמוץ "הידוע, המציג את מהבהב הנורית המובנית בלוח.

ניהול סיכות

התגובות מסבירות את הקוד. ההיגיון בעבודה זו הוא כדלקמן.

הפקודה PORTB B00100000 מציבה את PB5 במצב של יחידה לוגית, מבט, והתמונות האלה והטבלה שלהלן נמצאים ואנחנו רואים ש PB5 תואם 13 פינים של Arduina.

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

מבנה נמל D

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

מחשבון חלונות

הזן את המספר הרצוי:

מצב מחשבון מתכנת

ולחץ על HEX:

תרגום מספרים במחשבון

במקרה זה, אנו מעבירים את כל זה ל- IDE של Arduino, אך במקום הקידומת "B" זה יהיה "0x".

העברת מספרים ב- Arduino IDE

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

הזנת נתונים לכל סיכה

רשומה כזו עשויה להיראות לא מובנת, בואו ונברר זאת.

ניתוח רשומה

זוהי פעולת תוספת הגיונית, | = פירושו להוסיף משהו לתוכן היציאה.

פעולת תוספת לוגית

פירוש הדבר שעליך להוסיף מילה של 8 סיביות בפנקס כאשר יחידה מוזזת ב -5 ביטים - כתוצאה מכך, אם 11000010 יתברר כ -110,110,010. בדוגמה זו ניתן לראות שרק PB5 השתנה, שאר הקטעים בפנקס זה נותרו ללא שינוי, כמו גם מצב סיכות המיקרו-בקר נותר ללא שינוי.

אבל עם תוספת הגיונית, מתעוררת בעיה - אינך יכול להפוך את היחידה לאפס, מכיוון:

0+0=1

1+0=1

0+1=1

הכפל וההיפוך הלוגי יעזרו לנו:

כפל והפכה לוגיים

& = פירושו להכפיל את תוכן היציאה במספר ספציפי.

 

הכפלת תוכן היציאה במספר

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

הכפל את תוכן היציאה באפס המועבר ב -5 ביטים

ניתן לעשות את אותו הדבר באמצעות פעולת ההפוך (^):

קריאה מהנמלים, האנלוג של digitalRead () מבוצע באמצעות פנקס ה- PIN, בפועל זה נראה כך:

קרא מהנמלים

כאן אנו בודקים האם הביטוי בסוגריים שווה למצבם האמיתי של הנמלים, כלומר באופן דומה אם כתבנו אם (digitalRead (12) == 1).


מסקנה

מדוע ישנם קשיים כאלה בניהול נמל אם אתה יכול להשתמש בפונקציות נוחות סטנדרטיות? הכל קשור למהירות וגודל קוד. כאשר משתמשים בשיטה השנייה, הנדונה במאמר, גודל הקוד מופחת משמעותית, והמהירות עולה בכמה סדרי גודל. ה- DigitalWrite הסטנדרטי () בוצע בשנת 1800 מיקרוגרם, והוקלט ישירות ליציאה ב- 0.2 מיקרוגרם, ו- digitalRead () בשנת 1900 מיקרוגרמים, והפך גם ל- 0.2 מיקרוגרם. שיטת בקרה זו נמצאה בשטחים הפתוחים של הרשת ונמצאת לרוב בקוד. פרויקטים גמורים.

ראה גם באתר elektrohomepro.com:

  • חיבור ותכנות של ארדואינו למתחילים
  • כיצד לחבר מקודד מצטבר לארדואינו
  • בקרי מיקרו PIC למתחילים
  • שלט רחוק מיקרו-בקר: IR Remote, Arduino, ESP8266, 433 ...
  • מדידת טמפרטורה ולחות על ארדואינו - מבחר דרכים

  •  
     
    הערות:

    מספר 1 כתב: קיפובץ | [ציטוט]

     
     

    "אבל עם תוספת הגיונית, מתעוררת בעיה - אינך יכול להפוך את היחידה לאפס, מכיוון:

    0 + 0 = 1 "(c)

    פיקוח קטן: 0 + 0 = 0.

     
    הערות:

    מס '2 כתב: צ'וגו | [ציטוט]

     
     

    קיפובץ, הוא בטח רצה לומר:

    1 + 1 = 1

     
    הערות:

    מספר 3 כתב: | [ציטוט]

     
     

    קיפובץ,
    שגיאת הקלדה בנאלית אתה רואה כמה טוב שמומחים יושבים בפורטל שלנו! צריך להכין רק תוכן מתאים!

     
    הערות:

    # 4 כתב: סרג | [ציטוט]

     
     

    בחלק האחרון כתוב PORTB | = 1 << 5 ... if (digitalRead (12) == 1). אבל 5 סיכות של יציאה B, זהו 13 סיכות של ארדואינו. או שאני טועה ?!

     
    הערות:

    מס '5 כתב: p-a-h-a | [ציטוט]

     
     

    אם (PINB == B00010000) {} אינודומה אם כתבנו אם (digitalRead (12) == 1)
    אנלוגי למדי
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... וכך 8 סיכות יציאה

    כאן אתה צריך את זה:
    אם (
    ! (~ PORTB & (1 << PB4))) {} //חוזר0 או 1
    או ככה:
    אם (PORTB & (1 << PB4)) {} // מחזירה את היחידה המועברת = 16, DEC
    או ככה:
    אם (
    bit_is_set (PORTB, 4)) {}// מחזירה את היחידה המועברת = 16, DEC