כפי שציינתי בפוסט הקודם בסדרה, פרויקט ה-Blink הראשון ל-PIC12F675 מפוצל לשני פוסטים מכיוון שמעורבים בעניין הרבה תמונות והסברים, ואני לא רוצה לדלג על שום שלב. בפוסט ראשון זה אציג את צד הקוד – כל מה שקורה בסביבת הפיתוח MPLAB X עד לרגע שבו נהיה מוכנים להעלות את הקוד המקומפל למיקרו-בקר. בפוסט הבא נדבר על צד החומרה ונראה כיצד הפרויקט עובד בפועל.
נפעיל את סביבת הפיתוח, שהאייקון שלה מוצג בגדול בצילום המסך למעלה, ונקבל בסופו של דבר את הדבר הבא. שימו לב, ניתן ללחוץ כמעט על כל התמונות כאן כדי להציג גרסה מוגדלת.
כדי ליצור פרויקט חדש, נלחץ על התפריט File->New Project (או על מקשי קיצור הדרך Ctrl+Shift+N):
ייפתח חלון חדש, בו נצטרך לעבור על ולהגדיר את כל הפרמטרים של הפרויקט החדש. נתחיל בקטגוריה שלו, שהיא Microchip Embedded (משמאל), ובסוג הפרויקט שהוא Standalone. לאחר מכן, נלחץ על Next:
עכשיו נבחר את המיקרו-בקר שעבורו נכתב הפרויקט. בעזרת תיבת Family נוכל לצמצם קצת את האפשרויות – במקרה זה, נבחר Mid-Range 8-bit MCUs – ובתיבה שמתחתיה נאתר ונבחר את PIC12F675. לסיום השלב הזה, כמו קודם, נלחץ על Next:
כעת אנחנו מתבקשים לבחור Header לדיבוג. לומר את האמת, אני עוד לא יודע מה זה אומר, אז אני פשוט לוחץ על Next…
השלב הבא – בחירת הצורב. הצורב לא חייב להיות מחובר כרגע למחשב – עלינו רק לבחור את הדגם שיש לנו וללחוץ על Next. אם מדובר בדגם שסביבת הפיתוח לא מכירה, תהליך הצריבה יצטרך להיות עקיף (איתור וצריבה ידניים של קובץ ה-HEX).
שימו לב לשלב הבא, הוא חשוב מאד: כאן אנחנו בוחרים עם איזה קומפיילר לעבוד. כל הקומפיילרים המתאימים שהותקנו מופיעים בחלון זה. אנחנו נבחר, כאמור, ב-XC8 ונלחץ Next:
השלב הבא – בחירת שם ותיקיה לפרויקט. ברמה של פרויקט Blink זה לא ממש משנה מה תבחרו כאן, העיקר שתעבדו מסודר.
וסוף כל סוף, בשעה טובה, אנחנו מוחזרים לסביבת הפיתוח עצמה, כשמשמאל מופיע עץ הפרויקט החדש והטרי שלנו:
אבל, אם תשימו לב, אין בו שום קובץ קוד מקור (source). גם את זה נצטרך ליצור לבד. לחצן עכבר ימני על שם הפרויקט ("Blink"), ונבחר בפריט התפריט New->C Main File:
יצירת קובץ C ראשי
גם לקובץ הזה נצטרך לבחור ידנית שם. אני בחרתי blink, עם B קטנה להבדיל משם הפרויקט Blink…
והנה, עוד לפני שהספקנו להגיד "הצילו, אני רוצה לחזור לארדואינו!", נפתחת לנו לשונית חדשה עם שלד קוד מוכן. מעולה!
בואו נבדוק אם זה מתקמפל כמו שצריך. בלי לגעת בשום דבר אחר, נבחר בתפריט Run->Build Main Project:
בתחתית החלון תיפתח לשונית Output, יופיעו בה כל מיני דברים, ואם אין שום תקלה זה ייראה בסופו של התהליך בערך ככה:
סבבה? סבבה. רק מה, הקוד הזה בכלל לא מתאים לנו. זהו קוד גנרי מדי, ואם ננסה לכתוב בו שמות של רגיסטרים של ה-PIC12F675, למשל, לא יהיה לו מושג על מה אנחנו מדברים. אפשר לפתור את הבעיה באמצעות הכללה (include#) של המוני ספריות שונות ומשונות, או באמצעות הכללה אחת ויחידה של xc.h. למה? ככה. למען הבהירות, נשנה גם את הקוד של פונקציית main למשהו קומפקטי והגיוני יותר:
אנחנו מתקרבים לסוף, בחיי. השלב הבא הוא להגדיר את הפיוזים של המיקרו-בקר, כל אותן הגדרות גלובליות של מקור שעון, טיימר Watchdog וכדומה. בניגוד ל-ATtiny85, הגדרת הפיוזים מתבצעת כאן דרך הקוד עצמו, אבל למזלנו אנחנו לא צריכים לזכור את כל השמות וההגדרות בעל-פה – יש חלון מיוחד שמטפל בזה. נלחץ בתפריט על Window->PIC Memory Views->Configuration Bits:
בתחתית סביבת הפיתוח תיפתח לשונית חדשה בשם Configuration Bits, בה ניתן לבחור בעזרת העכבר את הגדרות הפיוזים הרצויות לנו. כאן בחרתי במתנד הפנימי (שמהירותו, אגב, 4MHz), ואת פין GP3 הגדרתי כ-MCLR (המקביל ל-Reset ב-ATtiny85). אלה לא בהכרח ההגדרות האופטימליות עבור פרויקט הבהוב בלד, אבל זה יספיק. כל שאר הפיוזים הוגדרו כ-OFF, ולסיום נלחץ על הלחצן Generate Code to Output למטה:
מה שיקרה כעת הוא שתיפתח עוד לשונית פלט, ובה נראה קוד C שנבנה אוטומטית עבור ההגדרות שבחרנו, כולל הערות אינפורמטיביות באמת:
השורות הקריטיות בפלט הזה הן השורות שמתחילות ב-pragma#. לפני שנים רבות, כשנתקלתי לראשונה במילת המפתח הזאת ולא היה לי מושג מה היא עושה, היא נשמעה לי מסתורית, מרתקת ורבת-עוצמה. בפועל, זה משהו הרבה פחות אקזוטי: זה אומר, בערך, ככה: "שמע, אני מופיע בקוד שלך אבל אני לא באמת שייך לשפת C, קפצתי רק כדי להגיד משהו לקומפיילר הספציפי או לסביבת הפיתוח שאתה עובד איתם, זה לא יעבוד לך בשום מקום אחר" – ואכן, זה בדיוק מה שהפקודות האלה עושות: הן אומרות לסביבת הפיתוח שכאשר היא צורבת את הקוד ה"רגיל" למיקרו-בקר, היא צריכה גם להגדיר את הפיוזים כפי שצוין.
אז נעתיק את שורות הפראגמה האלה ונדביק אותן בקוד:
ומה עוד? כלום, אפשר להתחיל לתכנת. הנה הקוד שכתבתי עבור הלד המהבהב – הסברים לאחר התמונה:
השורה שמסומנת בחץ (1) היא ציון של קצב השעון ("תדר הגביש"), שאנחנו צריכים ליצור ידנית עם השם הספציפי XTAL_FREQ_ אם אנחנו רוצים להשתמש בפקודת ההשהיה (ליתר דיוק, מאקרו ההשהיה) שנראה בהמשך.
חץ (2) מצביע על אתחול הרגיסטרים החיוני כדי שהעסק יפעל. צריך להגדיר במפורש לא רק איזה פין הוא פלט או קלט דיגיטלי, אלא גם איזה פין הוא לא קלט אנלוגי, ולכבות את האלמנטים האנלוגיים שעלולים להפריע לנו. קיראו בתשומת לב את ההערות שהוספתי ליד כל הגדרת רגיסטר, וקבלו את זה בינתיים כתורה מסיני – או, עדיף, הסתכלו במפרט הטכני של המיקרו-בקר כדי לראות מה כל רגיסטר עושה.
החלק שמסומן בחץ (3) הוא קוד ההבהוב. את קביעת הערכים לפין ביצעתי בשני אופנים שונים רק כדי להראות שזה אפשרי – באותה מידה הייתי יכול לכתוב את שתי השורות עם GPIObits.GP2 או עם GPIO (כמשתנה בעל 8 ביטים). ההשהיה היא, כמובן, של 1000 אלפיות שניה אחרי כל פעולה. מעניין לציין שסביבת הפיתוח מסמנת את פקודות המאקרו האלה כשגיאה, אך הן מתקמפלות בלי בעיה. זו תקלה מוכרת ונצטרך לחיות איתה, או לעשות שמיניות באוויר כדי לעקוף אותה.
כדאי לקמפל שוב כדי לוודא שהקוד תקין, כי השלב הבא – שיופיע בפוסט הבא – הוא הצריבה למיקרו-בקר עצמו!