במדריך הקודם למדנו על הבהוב נורית באמצעות מיקרו-בקר PIC ובנינו את אותו מעגל על לוח Perf. ואז השתמשנו ב- PICkit 3, ICSP ו- MPLAB IPE לצורך השלכת התוכנית על לוח Perf שלנו. כעת, במדריך זה נקדם את עצמינו לשימוש בסיכות נוספות במיקרו-בקר PIC. נשתמש בשבעה יציאות (נוריות נוריות) ובכניסה אחת. לצורך הדרכה זו נשתמש בלוח Perf הישן (שמוצג למטה) ונוסיף מקלות ברג כדי לשלוף את הפינים הנדרשים על לוח ה- LED השני. בסוף מדריך זה ניצור רצף של נוריות מהבהבות באמצעות מיקרו-בקר PIC16F877A ונלמד כיצד להשתמש בכניסות ויציאות מרובות, כמה יסודות על קריאת לולאה ופונקציה.
לוח ה- LED אינו אלא לוח מושלם נוסף, עליו נלחם את ה- LED עם נגד מגביל זרם (מוצג להלן). נוסיף גם כפתור לחיצה כדי להפעיל את נורית LED המהבהבת.
תרשים מעגל:
PIC מיקרו-בקר PIC16F877A קוד רצף מהבהב LED והסבר עבודה:
הקוד השלם ניתן למטה (בדוק בסוף), כאן נקבל אותו דרך שורה אחר שורה. קוד זה יתחיל להדליק נוריות נוריות ברצף כאשר לוחצים על כפתור הלחיצה. על מנת להבין את הרצפים אנא צפו בסרטון בסוף ההדרכה. אני ממליץ לך להשוות את הפלט שמוצג בסרטון עם הקוד שלהלן ולנסות להבין את התוכנית.
בואו נסתכל על הקוד שורה אחר שורה. השורות הראשונות נועדו להגדרת סיביות תצורה שהוסברו במדריך הקודם ולכן אני מדלג עליהן לעת עתה. הדרך הטובה ביותר להבין כל תוכנית היא להתחיל מהפונקציה הראשית ( void main () ), אז בוא נעשה את זה
TRISB0 = 1; // הורה ל- MCU שסיכת ה- PORTB 0 משמשת כקלט לכפתור. TRISD = 0x00; // הורה ל- MCU כי כל הפינים יוצאים PORTD = 0x00; // אתחל את כל הסיכות ל -0
המילה TRIS משמשת כדי להגדיר אם הסיכה משמשת כקלט / פלט והמילה PORT משמשת ליצירת סיכה גבוהה / נמוכה. הקו TRISB0 = 1 יהפוך את הסיכה ה -0 של פורט B לקלט. זה יהיה הכפתור שלנו. הקווים TRISD = 0x00; פורט = 0x00; יהפוך את כל הפינים של יציאה D לפלט ויקצה ערך ראשוני של LOW לפינים האלה.
מכיוון שאמרנו ש- B0 משמש כקלט, נחבר קצה אחד של כפתור הלחיצה לסיכה B0 וקצה אחר לקרקע. עד אז, בכל פעם שנלחץ על הכפתור, הסיכה תוחזק לקרקע כפי שמוצג בתרשים החיבור לעיל. אך כדי לגרום לזה לקרות עלינו להשתמש בנגיעה נשלפת, כך שהסיכה תחזיק גבוה כשלא לוחצים על הכפתור. נגד למשוך למעלה הוא משהו כזה.
אבל ל- PIC MCU שלנו יש נגן משיכה פנימי חלש שניתן להפעיל אותו על ידי תוכנה וכך לחסוך הרבה טרחה (כאשר יש לחבר כפתורים נוספים).
מהו נגד משיכה חלש?
ישנם שני סוגים של נגדי משיכה, האחד הוא משיכה חלשה והשני חזק כלפי מעלה. נגדי המשיכה החלשים הם בעלי ערך גבוה ובכך מאפשרים לזרם חלש לזרום ונגדי המשיכה החזקים הם בעלי ערך נמוך ובכך מאפשרים לזרם חזק לזרום. כל ה- MCU משתמשים בעיקר בנגדי משיכה חלשים. על מנת להפעיל זאת ב- PIC MCU שלנו עלינו לבדוק בדף הנתונים שלנו את OPTION_REG (רישום האופציות) כפי שמוצג בתצלום המצב למטה.
כפי שמוצג ביט 7 מתמודד עם הנגד המושך החלש. צריך להפוך אותו לאפס כדי להפעיל אותו. זה נעשה על ידי OPTION_REG <7> = 0 . זה במיוחד עוסק בסיבית 7 שמשאירה את הסיביות האחרות לערכי ברירת המחדל שלה. עם זאת אנו נכנסים לולאת ה- while שלנו, שם היא בודקת אם הכפתור נלחץ באמצעות if (RB0 == 0). אם התנאי מתקיים אנו קוראים לפונקציה שלנו עם הפרמטרים 1, 3, 7 ו -15.
סלינק (1); // FUNCTION CALL 1 עם פרמטר 1 sblink (3); // FUNCTION CALL 3 עם פרמטר 3 sblink (7); // FUNCTION CALL 7 עם פרמטר 7 sblink (15); // FUNCTION CALL 4 עם פרמטר 15
מדוע אנו משתמשים בפונקציות?
פונקציות משמשות להפחתת מספר השורות בקוד שלנו. זה מה שרובנו היינו יודעים. אך מדוע עלינו לצמצם את מספר השורות, במיוחד כשמדובר בתכנות MCU. הסיבה היא שטח מוגבל בזיכרון התוכנית שלנו. אם לא נבצע אופטימיזציה של הקוד כראוי, יתכן שנגמר מקום הזיכרון. זה יהיה שימושי כשאנחנו כותבים דפים ארוכים של קודים.
לכל פונקציה תהיה הגדרת פונקציה ( sblink (int get) במקרה שלנו) ופונקציה Call ( sblink (1) במקרה שלנו). זה אופציונלי לקבל הצהרת פונקציה, כדי להימנע ממנה מיקמתי את הגדרת הפונקציה שלי לפני שקראתי לפונקציה לפונקציה העיקרית שלי.
פרמטרים של פונקציה הם הערך שיועבר מקריאת הפונקציה להגדרת הפונקציה. במקרה שלנו הערכים השלמים (1, 3, 7, 15) הם הפרמטרים שעוברים מהקריאה לפונקציה והמשתנה "get" מכניס את ערך הפרמטרים להגדרת הפונקציה כדי לעבד אותם. לפונקציה יכול להיות יותר מפרמטר אחד.
לאחר קריאת הפונקציה, השורות הבאות בהגדרת הפונקציה יבוצעו.
עבור (int i = 0; i <= 7 && RB0 == 0; i ++) {PORTD = get << i; // הזזת LED רצף שמאלי __השהיית_מס (50); } עבור (int i = 7; i> = 0 && RB0 == 0; i--) {PORTD = get << i; // הזזת LED רצף שמאלי __השהיית_מס (50); }
עכשיו נראה ששורה זו מוזרה: PORTD = קבל << i . אסביר מה קורה כאן בפועל.
"<<" הוא מפעיל משמרת שמאלי שמעביר את כל הביטים למיקומו השמאלי. כעת, כאשר אנו קוראים לפונקציה sblink (int get) עם הפרמטר '1' כ- sblink (1), זה יקבע את הערך של 'get' כ- 1, שבבינארי הוא 0b00000001. מכאן ששורה זו תהיה כמו PORTD = 0b00000001 << i .
הערך של "i" ישתנה בין 0 ל- 7 מכיוון שהשתמשנו ב- 'for loop' עבור (int i = 0; i <= 7 && RB0 == 0; i ++). הערך של 'אני' הוא בין 0 ל -7 ישנה את התוצאה באופן הבא:
כפי שניתן לראות הדלקנו נורית אחת בכל פעם (משמאל לימין) על ידי השארת כיבוי השאר. הבא עבור 'לולאה' עבור (int i = 7; i> = 0 && RB0 == 0; i--) , יעשה את אותו הדבר, אך הפעם נורית ה- LED תידלק מימין לשמאל ברצף, כשהתחלנו מ- 7 ונרד ל- 0. השתמשנו בעיכוב של 200 ms כדי שנוכל לדמיין את נורית ה- LED מופעלת ומכבה.
כעת כאשר אנו מעבירים את ערך 3 בפונקציה sblink (int get) , כך הפונקציה sblink (3) תבוצע מה שהופך את הערך של 'get' ל- 0b00000011, ומכאן שהתוצאה ב- PORTD תהיה:
אז עכשיו הפעם שתי נוריות יופעלו בכל זמן נתון באמצעות sblink (3). באופן דומה עבור sblink (7) ו- sblink (15), שלוש וארבע נוריות נוריות יהיו דולקות ברצף. לאחר השלמת פעולה זו אנו נכין את כל נוריות הדלק לדולק באמצעות קו PORTD = 0xFF . עיין בסרטון להלן להפגנה מלאה.
מקווה שהבנתם את הקוד וכך למדתם כיצד להשתמש בפונקציות 'לולאה' ו- 'תוך כדי' כדי להשיג את התפוקות הרצויות. עכשיו אתה יכול לצבוט סביב הקוד כדי לקבל את רצף ה- LED השני שלך מהבהב. קדימה, הידר את הקוד שלך והשליך אותו על ה- MCU שלך ותהנה מהפלט. אתה יכול להשתמש בסעיף ההערות אם אתה נתקע איפשהו. צירפתי כאן גם את קבצי ההדמיה והתוכנה.
זהו זה לעת עתה במדריך הבא שלנו נלמד כיצד להשתמש בטיימרים של PIC16F877A במקום להשתמש בפונקציות עיכוב. תוכל לעיין בכל מדריכי PIC המיקרו-בקר כאן.