תוכן עניינים:

הדרכה להרכבת AVR 2: 4 שלבים
הדרכה להרכבת AVR 2: 4 שלבים

וִידֵאוֹ: הדרכה להרכבת AVR 2: 4 שלבים

וִידֵאוֹ: הדרכה להרכבת AVR 2: 4 שלבים
וִידֵאוֹ: שלב 4 הלבשת המולטימדיה על הרכב + חיבור הכבלים לרכב Multimedia sleepwear on the vehicle 2024, יולי
Anonim
הדרכה להרכבת AVR 2
הדרכה להרכבת AVR 2

הדרכה זו היא המשך של "מדריך הרכבה של AVR 1"

אם לא עברת את הדרכה 1 עליך לעצור עכשיו ולעשות זאת קודם.

במדריך זה נמשיך ללמוד את תכנות שפת ההרכבה של ה- atmega328p המשמש בארדואינו.

אתה תצטרך:

  1. לוח לחם ארדואינו או סתם ארדואינו רגיל כמו בהדרכה 1
  2. LED
  3. נגד 220 אוהם
  4. כפתור לחיצה
  5. חיבור חוטים ליצירת המעגל בלוח הלחם שלך
  6. מדריך למערכות אינסטרוקציה: www.atmel.com/images/atmel-0856-avr-instruction-s…
  7. גליון נתונים: www.atmel.com/images/Atmel-8271-8-bit-AVR-Microco…

את האוסף המלא של ההדרכות שלי תוכלו למצוא כאן:

שלב 1: בניית המעגל

בניית המעגל
בניית המעגל

ראשית עליך לבנות את המעגל אותו נלמד במדריך זה.

להלן דרך החיבור:

PB0 (סיכה דיגיטלית 8) - LED - R (220 אוהם) - 5V

PD0 (סיכה דיגיטלית 0) - כפתור לחיצה - GND

אתה יכול לבדוק כי ה- LED שלך מכוון כראוי על ידי חיבורו ל- GND במקום ל- PB0. אם לא קורה כלום, הפוך את הכיוון והאור צריך להידלק. לאחר מכן חבר אותו מחדש ל- PB0 והמשך. התמונה מראה כיצד מחובר הארדואינו של לוח הלחם שלי.

שלב 2: כתיבת קוד ההרכבה

כתיבת קוד ההרכבה
כתיבת קוד ההרכבה

כתוב את הקוד הבא בקובץ טקסט שנקרא pushbutton.asm וערך אותו עם אברה כפי שעשית במדריך 1.

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

;************************************

; נכתב על ידי: 1o_o7; תאריך: 23 באוקטובר 2014; **********************************

.nolist

.כלול "m328Pdef.inc".list.def temp = r16; להגדיר את רשם העבודה r16 כ- temp rjmp Init; השורה הראשונה בוצעה

ראשית:

ser temp; הגדר את כל הביטים בטמפ 'ל -1. יוצא DDRB, טמפ '; הגדרת מעט כ- 1 ב- I/O Data Direction; הרשמה ל- PortB, שהיא DDRB, קובעת זאת; סיכה כפלט, 0 יגדיר את הסיכה כקלט; אז כאן, כל סיכות PortB הן יציאות (מוגדרות ל- 1) ldi temp, 0b11111110; טען את המספר 'המיידי' לרשם הזמני; אם זה היה רק ld אז הטיעון השני; יצטרך להיות מיקום זיכרון במקום DDRD, זמני; mv temp ל- DDRD, התוצאה היא ש- PD0 הוא קלט; והשאר הם זמני פלט CLR; כל הסיביות בטמפ 'מוגדרות ל- 0 out PortB, temp; הגדר את כל הסיביות (כלומר סיכות) ב PortB ל- 0V ldi temp, 0b00000001; טען מספר מיידי כדי להוציא את PortD, temp; העברת טמפ 'ל- PortD. ל- PD0 יש נגד משיכה; (כלומר מוגדר ל- 5V) מכיוון שיש לו 1 בביט זה; השאר 0V מאז 0.

רָאשִׁי:

בטמפ ', PinD; PinD מחזיק את מצב PortD, העתק זאת לטמפ '; אם הכפתור מחובר ל- PD0 זה יהיה; 0 כאשר הכפתור נלחץ, 1 אחרת מאז; PD0 יש נגד למעלה הוא בדרך כלל ב 5V החוצה PortB, temp; שולח את ה 0 ו -1 הנקרא למעלה לפורט ב; זה אומר שאנחנו רוצים את ה- LED מחובר ל- PB0,; כאשר PD0 הוא נמוך, הוא מגדיר את PB0 ל- LOW והופך; על ה- LED (מכיוון שהצד השני של ה- LED הוא; מחובר ל- 5V וזה יגדיר PB0 ל- 0V כך; הזרם יזרום) rjmp Main; לולאות חזרה לתחילת Main

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

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

שלב 3: ניתוח שורה אחר שורה של הקוד

אני אדלג על השורות שהם הערות בלבד כיוון שמטרתן מובנת מאליה.

.nolist

.כלול רשימת "m328Pdef.inc"

שלוש שורות אלה כוללות את הקובץ המכיל את הגדרות ה- Register ו- Bit עבור ה- ATmega328P אותו אנו מתכנתים. הפקודה.nolist אומרת למאסף לא לכלול קובץ זה בקובץ pushbutton.lst שהוא מייצר בעת הרכבתו. זה מכבה את אפשרות הרישום. לאחר הכללת הקובץ אנו מפעילים את אפשרות הרישום מחדש באמצעות הפקודה.list. הסיבה שאנו עושים זאת היא מכיוון שקובץ m328Pdef.inc ארוך למדי ואיננו באמת צריכים לראות אותו בקובץ הרשימה. המאסף שלנו, אברה, אינו יוצר קובץ רשימה באופן אוטומטי ואם נרצה אחד מהם היינו מרכיבים באמצעות הפקודה הבאה:

לחצן avra -l pushbutton.lst pushbutton.asm

אם תעשה זאת הוא יפיק קובץ בשם pushbutton.lst ואם תבדוק קובץ זה תגלה שהוא מציג את קוד התוכנית שלך יחד עם מידע נוסף. אם תסתכל על המידע הנוסף תראה שהשורות מתחילות ב- C: ואחריהן הכתובת היחסית ב- hex של המקום בו מוצב הקוד בזיכרון. בעיקרו של דבר הוא מתחיל ב- 000000 עם הפקודה הראשונה ועולה משם עם כל פקודה עוקבת. העמודה השנייה אחרי המקום היחסי בזיכרון היא קוד ה- hex של הפקודה ואחריה קוד ה- hex של הארגומנט של הפקודה. נדון בקבצי רשימה עוד בהדרכות עתידיות.

.def temp = r16; ציין את רשם העבודה r16 כטמפ '

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

תרגיל 1: נסה להעתיק מספר בינארי ישירות ליציאה או לרשם מיוחד כמו DDRB ולראות מה קורה כשאתה מנסה להרכיב את הקוד.

מרשם מכיל בתים (8 סיביות) של מידע. בעיקרו של דבר זהו בדרך כלל אוסף SR-Latches שכל אחד מהם הוא "קצת" ומכיל 1 או 0. אנו עשויים לדון בכך (ואפילו לבנות אחד!) בהמשך הסדרה. יתכן שאתה תוהה מהו "רישום עובד" ומדוע בחרנו ב- r16. נדון בכך במדריך עתידי כאשר נצלול אל ביצה הפנימית של השבב. לעת עתה אני רוצה שתבין כיצד לעשות דברים כמו לכתוב קוד ותכנת חומרה פיזית. לאחר מכן תהיה לך מסגרת התייחסות מאותה חוויה אשר תהפוך את הזיכרון והרישום של מאפייני הבקרה לקלים יותר להבנה. אני מבין שרוב ספרי הלימוד והדיונים מבצעים זאת הפוך, אך גיליתי שלמשחק משחק וידאו לזמן מה קודם כדי לקבל נקודת מבט עולמית לפני קריאת מדריך ההוראות הרבה יותר קל מאשר לקרוא את המדריך קודם.

rjmp Init; השורה הראשונה בוצעה

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

ראשית:

ser temp; הגדר את כל הסיביות בטמפ 'ל -1.

לאחר התווית Init אנו מבצעים פקודה "set register". זה מגדיר את כל 8 הסיביות ברשם "טמפ '(שאתה זוכר הוא r16) ל- 1. אז הטמפ 'מכילה כעת 0b11111111.

יוצא DDRB, טמפ '; הגדרת מעט כ- 1 ברשם I/O Data Direction

; עבור PortB, שהוא DDRB, מגדיר את הסיכה כפלט; 0 יגדיר את הסיכה כקלט; אז כאן, כל סיכות ה- PortB הן יציאות (מוגדרות ל -1)

הרשם DDRB (Register Direction Data for PortB) מספר אילו סיכות ב- PortB (כלומר PB0 עד PB7) מיועדות כקלט ואילו מסומנות כפלט. מכיוון שהסיכה PB0 מחוברת למנורת הלד שלנו והשאר לא מחוברים לשום דבר נקבע את כל הביטים ל -1 כלומר כולם יציאות.

ldi temp, 0b11111110; טען את המספר 'המיידי' לרשם הזמני

; אם זה היה רק ld אז הטיעון השני היה; חייב להיות מיקום זיכרון

שורה זו טוענת את המספר הבינארי 0b11111110 לרשם הזמני.

יוצא DDRD, זמני; mv temp ל- DDRD, התוצאה היא ש- PD0 הוא קלט ו-

; השאר הם תפוקות

כעת הגדרנו את רישום כיוון הנתונים עבור PortD מהטמפ ', מכיוון שהטמפ' עדיין מכיל 0b11111110 אנו רואים ש- PD0 יוגדר כסיכת קלט (מכיוון שיש 0 בנקודה הימנית ביותר) והשאר מיועדים כתפוקות מכיוון שיש 1 במקומות האלה.

טמפ 'clr; כל הביטים בטמפ 'מוגדרים ל- 0

יוצא PortB, טמפ '; הגדר את כל הסיביות (כלומר סיכות) ב- PortB ל- 0V

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

תרגיל 2: השתמש במולטימטר כדי לבדוק אם כל הסיכות ב- PortB הן בעצם אפס. האם קורה משהו מוזר עם PB1? יש לך מושג למה זה יכול להיות? (בדומה לתרגיל 4 להלן ולאחר מכן בצע את הקוד …) תרגיל 3: הסר את שתי השורות למעלה מהקוד שלך. האם התוכנית עדיין פועלת כהלכה? למה?

ldi temp, 0b00000001; טען מספר מיידי לטמפ '

יוצא PortD, טמפ '; העברת טמפ 'ל- PortD. PD0 הוא ב 5V (יש נגד pullup); מכיוון שיש לו 1 בביט כל השאר 0V. תרגיל 4: הסר את שתי השורות שלעיל מהקוד שלך. האם התוכנית עדיין פועלת כהלכה? למה? (זה שונה מתרגיל 3 לעיל. עיין בתרשים הצמד. מהי הגדרת ברירת המחדל של DDRD עבור PD0? (ראה עמוד 90 בגיליון הנתונים

ראשית אנו "מעמיסים" את המספר 0b00000001 לטמפ '. החלק ה"מיידי "קיים מכיוון שאנו מעמיסים מספר ישר לטמפ 'במקום מצביע למיקום זיכרון המכיל את המספר הטעינה. במקרה זה פשוט היינו משתמשים ב- "ld" ולא ב- "ldi". לאחר מכן אנו שולחים את המספר הזה ל- PortD שמגדיר את PD0 ל- 5V והשאר ל- 0V.

כעת הגדרנו את הפינים ככניסה או פלט והגדרנו את מצביהם הראשוניים כ- 0V או 5V (LOW או HIGH) וכך אנו נכנסים כעת ל"לולאה "של התוכנית שלנו.

עיקרי: בטמפ ', PinD; PinD מחזיק את מצב PortD, העתק זאת לטמפ '

; אם הכפתור מחובר ל- PD0 אז זה יהיה; 0 כאשר הכפתור נלחץ, 1 אחרת מאז; PD0 יש נגד משיכה הוא בדרך כלל על 5V

הרשם PinD מכיל את המצב הנוכחי של סיכות ה- PortD. לדוגמה, אם חיברת חוט 5V ל- PD3, אז במחזור השעון הבא (שקורה 16 מיליון פעמים בשנייה מאז שהמיקרו -בקר מחובר לאות שעון 16MHz) הסיבית PinD3 (מהמצב הנוכחי של PD3) יהפוך ל -1 במקום ל 0. אז בשורה זו אנו מעתיקים את המצב הנוכחי של הסיכות לטמפ '.

יוצא PortB, טמפ '; שולח את ה 0 ו -1 הנקרא למעלה לפורט ב

; זה אומר שאנחנו רוצים את ה- LED מחובר ל- PB0, אז; כאשר PD0 הוא נמוך, הוא יגדיר את PB0 ל- LOW ותהפוך; על ה- LED (הצד השני של ה- LED מחובר; ל- 5V וזה יגדיר את PB0 ל- 0V כך שהזרם זורם)

כעת אנו שולחים את מצב הפינים ב- PinD לפלט PortB. למעשה, המשמעות היא ש- PD0 ישלח 1 ל- PortD0 אלא אם כן נלחץ על הכפתור. במקרה זה מכיוון שהכפתור מחובר לאדמה, הסיכה תהיה ב 0V והיא תשלח 0 ל- PortB0. עכשיו, אם אתה מסתכל על תרשים המעגלים, 0V ב- PB0 פירושו שהנורית זוהרת מכיוון שהצד השני שלה הוא ב -5V. אם אנחנו לא לוחצים על הכפתור, כך שיישלח 1 ל- PB0, זה אומר שיש לנו 5V ב- PB0 וגם 5V בצד השני של הלד ולכן אין הבדל פוטנציאלי ושום זרם לא יזרום ולכן ה- LED לא יזהר (במקרה זה מדובר ב- LED שהוא דיודה ולכן הזרם זורם רק בכיוון אחד ללא קשר אך לא משנה).

rjmp ראשי; לולאות בחזרה להתחלה

הקפיצה היחסית הזו מחליפה אותנו בחזרה לתווית הראשית שלנו: ואנו בודקים שוב את PinD וכן הלאה. בודקים כל 16 מיליונית שנייה אם הכפתור נלחץ והגדרת PB0 בהתאם.

תרגיל 5: שנה את הקוד שלך כך שה- LED שלך יתחבר ל- PB3 במקום ל- PB0 ותראה שהוא עובד. תרגיל 6: חבר את ה- LED שלך ל- GND במקום 5V ושנה את הקוד בהתאם.

שלב 4: מסקנה

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

רשם ser קובע את כל סיביות הרגיסטר ל- 1

רשם clr קובע את כל סיביות הרגיסטר ל- 0

במרשם, i/o register מעתיק את המספר מרשום i/o לרשם עבודה

במדריך הבא נבחן את מבנה ה- ATmega328p ואת הרשמים, הפעולות והמשאבים השונים הכלולים בו.

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

מוּמלָץ: