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

בקר מיקרו AVR. החלף נוריות LED באמצעות מתג לחצן. הפעלת לחצן לחיצה: 4 שלבים
בקר מיקרו AVR. החלף נוריות LED באמצעות מתג לחצן. הפעלת לחצן לחיצה: 4 שלבים

וִידֵאוֹ: בקר מיקרו AVR. החלף נוריות LED באמצעות מתג לחצן. הפעלת לחצן לחיצה: 4 שלבים

וִידֵאוֹ: בקר מיקרו AVR. החלף נוריות LED באמצעות מתג לחצן. הפעלת לחצן לחיצה: 4 שלבים
וִידֵאוֹ: LDmicro 10: Incubator Temperature Regulator (Microcontroller PLC Ladder Programming with LDmicro) 2024, יולי
Anonim
Image
Image

בחלק זה נלמד כיצד ליצור קוד C לתוכנית ATMega328PU כדי להחליף את מצב שלוש נוריות הלדים בהתאם לקלט ממתג כפתורים. כמו כן, חקרנו פתרונות לבעיה של 'Switch Bounce'. כרגיל, נרכיב את המעגל החשמלי על בסיס ה- AVR ATmega328 כדי לבדוק את עבודת קוד התוכנית.

שלב 1: כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7

כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7
כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7
כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7
כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7
כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7
כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולבת Atmel Studio 7

אם אין לך Atmel Studio, עליך להוריד ולהתקין אותו.

www.microchip.com/mplab/avr-support/atmel-studio-7

בשורות הראשונות יש לנו כמה הגדרות מהדר.

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

#ifndef F_CPU

#define F_CPU 16000000UL // אומר תדר קריסטל בקר (16 MHz AVR ATMega328P) #endif

#include // כותרת כדי לאפשר בקרת זרימת נתונים על סיכות. מגדיר סיכות, יציאות וכו '.

הקובץ הראשון הכולל הוא חלק מ- avr-libc והוא ישמש כמעט בכל פרויקט AVR שאתה עובד עליו. io.h יקבע את המעבד שבו אתה משתמש (וזו הסיבה שאתה מציין את החלק בעת הידור) ובתורו יכלול את כותרת הגדרת IO המתאימה לשבב בו אנו משתמשים. הוא פשוט מגדיר את הקבועים של כל הפינים, היציאות, הרישומים המיוחדים וכו '.

#include // header כדי לאפשר פונקציית עיכוב בתוכנית

הספרייה util/delay.h מכילה כמה שגרות לעיכובים קצרים. הפונקציה שבה נשתמש היא _delay_ms ().

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

מתג כפתור #define 1 1 // מחובר ליציאה B סיכה 1

#define LED1 0 // Led1 מחובר לפין B פין 0 #Define LED2 1 // Led2 מחובר ליציאה C פין 1 #הגדר LED3 2 // Led3 מחובר ליציאה D פין 2

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

#הגדר DEBOUNCE_TIME 25 // זמן לחכות תוך כפתור "ביטול הקפצה"

#הגדר LOCK_INPUT_TIME 300 // זמן לחכות לאחר לחיצה על כפתור

בטל init_ports_mcu ()

{

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

בכפתור, נשתמש ברשמי ה- PORT וה- PIN לכתיבה וקריאה. עם מכשירי AVR, אנו קוראים סיכה באמצעות רישום ה- PINx שלו ואנו כותבים לסיכה באמצעות רשם ה- PORTx שלו. עלינו לכתוב לרשם הכפתורים בכדי לאפשר את המשימות.

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

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

DDRB = 0xFFu; // הגדר את כל הסיכות של ה- PORTB כפלט.

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

DDRB & = ~ (1 <

לאחר מכן, סיכות PORTB מוגדרות גבוהות (+5 וולט) כדי להפעיל אותו. סיכות הפלט גבוהות בהתחלה, ומאחר שה- LED שלנו מחובר לחוט פעיל-גבוה, הוא יופעל אלא אם נכבה אותו במפורש.

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

PORTB = 0xFF; // הגדר את כל הסיכות של ה- PORTB כגבוהות. לד נדלק, // גם הנגד הפנימי כלפי מעלה של ה- PORTB הסיכה הראשונה מופעל. DDRC = 0xFFu; // הגדר את כל הסיכות של ה- PORTC כפלט. PORTC = 0x00u; // הגדר את כל סיכות ה- PORTC נמוכות מה שמכבה אותו. DDRD = 0xFFu; // הגדר את כל הסיכות של ה- PORTD כפלט. PORTD = 0x00u; // הגדר את כל סיכות ה- PORTD נמוך מה שמכבה אותו. }

char_state ללא חתימה ()

{

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

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

/ * נלחץ על הכפתור כאשר ה- BUTTON1 bit ברור */

אם (! (PINB & (1 <

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

_ delay_ms (DEBOUNCE_TIME);

אם (! (PINB & (1 <

int main (void)

{

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

תו לא חתום n_led = 1; // בתחילה מספר LED דולק כעת

קריאה של הפונקציה לאתחול סיכות קלט/פלט בשימוש:

init_ports_mcu ();

לולאה אינסופית בה פועלת התוכנית שלנו:

בעוד (1)

{

כאשר button_state מחזיר אחד המציין כי הכפתור נלחץ והופסק, ואז להחליף את המצב הנוכחי של נוריות בתורו לפי הפרמטר n_led.

אם (button_state ()) // אם לוחצים על הלחצן, החלף את מצב הנורית והתעכב במשך 300ms (#define LOCK_INPUT_TIME)

{switch (n_led) {מקרה 1: PORTB ^= (1 << LED1); PORTC ^= (1 << LED2); לשבור;

הצהרות אלה משתמשות באופרטורים של C bitwise. הפעם הוא משתמש במפעיל OR הבלעדי. כאשר אתה מסמן את ה- PORT עם ערך הסיביות של הסיביה שברצונך להחליף, אותו ביט משתנה מבלי להשפיע על הביטים האחרים.

מקרה 2:

PORTC ^= (1 << LED2); PORTD ^= (1 << LED3); לשבור; מקרה 3: PORTD ^= (1 << LED3); PORTB ^= (1 << LED1); n_led = 0; // איפוס שבירת מספר LED; } n_led ++; // LED הבא הוא הפעלת _עיכוב_מס (LOCK_INPUT_TIME); }} החזר (0); }

אז עכשיו, כאשר אתה מפעיל את התוכנית הזו, אתה אמור להיות מסוגל ללחוץ על כפתור הלחיצה כדי שמדליקים של נוריות LED. בשל העיכוב שלנו שהוגדר על ידי LOCK_INPUT_TIME, תוכל ללחוץ לחיצה ארוכה על הלחצן שיגרום לכיבוי והדלקה של הנוריות בקצב עקבי (קצת יותר מכל 275ms).

התכנות הושלם.

השלב הבא הוא בניית הפרויקט ותכנות קובץ hex לתוך המיקרו -בקר באמצעות התוכנית avrdude.

אתה יכול להוריד את הקובץ main.c עם התוכנית בקוד c:

שלב 2: העברת קובץ ה- HEX של התוכנית לזיכרון הבזק של שבב

העברת קובץ HEX של התוכנית לזיכרון הבזק של שבב
העברת קובץ HEX של התוכנית לזיכרון הבזק של שבב
העברת קובץ HEX של התוכנית לזיכרון הבזק של שבב
העברת קובץ HEX של התוכנית לזיכרון הבזק של שבב

הורד והתקן את AVRDUDE. הגרסה האחרונה הזמינה היא 6.3: הורד את קובץ ה- zip

ראשית, העתק את קובץ ה- hex של התוכנית לספריית AVRDUDE. במקרה שלי זה ButtonAVR.hex

לאחר מכן, הקלד בחלון שורת DOS את הפקודה: avrdude –c [שם המתכנת] –p m328p –u –U flash: w: [שם קובץ ה- hex שלך].

במקרה שלי זהו: avrdude –c ISPProgv1 –p m328p –u –U פלאש: w: ButtonAVR.hex

פקודה זו כותבת קובץ hex לזיכרון המיקרו -בקר.

צפה בסרטון עם תיאור מפורט של צריבת זיכרון ההבזק של המיקרו -בקר:

צריבת זיכרון פלאש של מיקרו -בקר …

בסדר! כעת, המיקרו -בקר פועל בהתאם להוראות התוכנית שלנו. בוא נבדוק את זה!

שלב 3: ניפוי מתג חומרה

ניסוח מתג חומרה
ניסוח מתג חומרה

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

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

שלב 4: מעגל חשמלי

מעגל חשמלי
מעגל חשמלי
מעגל חשמלי
מעגל חשמלי
מעגל חשמלי
מעגל חשמלי

חבר רכיבים בהתאם לתרשים סכמטי.

מוּמלָץ: