בפוסט האחרון בסדרה התבלבלתי בכותרת, ונתתי לו את המספר 2 אף על פי שהקודם היה 0. כדי לתקן את השיבוש וגם כדי לעשות קצת סדר בעניינים, הנה פוסט מס' 1 – בו אציג בצורה מסודרת סביבת פיתוח חלופית למיקרו-בקרים ממשפחת STM8, ואת תהליך העבודה המפורט ליצירת פרויקט Blink. אם אתם רוצים להתנסות עם המיקרו-בקרים האלה, זה בהחלט המקום להתחיל!
סביבת הפיתוח
בהשוואה למיקרו-בקרים של Atmel ואפילו לאלה של Microchip, קשה מאד למצוא חומר למתחילים על STM8. במקום אחד שמצאתי, הכותב השתמש בסביבת פיתוח של IAR. אלו הם מוצרים מסחריים שעולים בהתאם, אך מסתבר שאפשר להוריד גרסת התנסות עם מגבלת זמן או גודל קוד לבחירתכם (חשוב מאד, בזמן ההתקנה, לשים לב לסוג הרישיון שבוחרים!) מכיוון שגם סביבת הפיתוח הקודמת איתה עבדתי שמה מגבלה זהה על גודל הקוד, חשבתי לנסות את זו של IAR ולבדוק אם ההתקנה והשימוש בה נוחים יותר.
לא תיעדתי את תהליך ההתקנה של סביבת הפיתוח, אך הוא שגרתי למדי ולא כזה מורכב. הורידו את הקובץ מהקישור למעלה (מתאים רק ל-Windows) והפעילו. בשלב מסוים תתבקשו לבחור בסוג הרישיון הרצוי ולהירשם באתר של IAR. אז יישלח אליכם במייל קוד הרישום, אותו תזינו בחזרה בתוכנת ההתקנה, וסביבת הפיתוח תעלה בלי בעיה. אגב, במהלך ההתקנה יותקנו במחשב, בין השאר, גם הדרייברים לצורב ST Link שבו נשתמש בהמשך.
החומרה
לצורך פרויקט ה-Blink אשתמש בלוח פיתוח מינימלי עם המיקרו-בקר STM8S103F3P6 – לוח שאפשר להשיג מהמזרח הרחוק בפחות מדולר וחצי (חפשו לפי הקוד הזה + המילה "minimum"). הצורב הוא תואם סיני של ST Link V2, ובנוסף נצטרך headers להלחמה ללוח, ארבעה חוטים לחיבור בין הצורב ללוח, מטריצה, נורית LED ונגד מתאים (בסביבות 200-400 אוהם).
לפי המפרט הטכני, מיקרו-בקרים ממשפחה זו צריכים קבל חיצוני של כ-1uF בין פין Vcap לבין האדמה. אני חושב שהלוחות כוללים קבל כזה מובנה – בכל אופן הם עובדים כמו שהם…
בתמונה למטה מופיע כל העסק מחובר. הרגל החיובית של נורית ה-LED מחוברת לפין D3, והשלילית דרך הנגד ל-GND. החיבורים מהצורב ללוח הם GND, 3.3V, SWIM ו-RST (או NRST) – יש כיתובים ברורים על המודולים.
הכנות לקוד
סביבת הפיתוח כבר רצה, אז נבחר בתפריט Project->Create New Project:
ונקבל את החלון הזה, שמבקש מאיתנו לבחור את שפת התכנות. לצורך העניין, נבחר ב-C:
ייפתח חלון שמירה סטנדרטי, בו נתבקש לבחור תיקיה ושם עבור הפרויקט (שיקבל את הסיומת ewp). כשנעשה זאת, ייפתח כמעט מיד הקובץ הראשי של התוכנית שלנו – main.c:
כעת, יש עוד כמה הגדרות שצריך לקבוע עבור הקומפיילר והצורב. בפאנל Workspace משמאל, מתחת לכותרת Files, סמנו קודם כל – זה חשוב! – את Blink-Debug (הפריט העליון). לאחר מכן, בחרו בתפריט Project->Options:
בחלון שנפתח, נבחר את דגם המיקרו-בקר המדויק. לשם כך נסמן את General Options משמאל, ואז בלשונית Target נלחץ על הלחצן שליד Device ונבחר בתפריט שמופיע STM8S->STM8S103F3P (כן, השם המלא שעל הג'וק כולל 6 נוסף בקצה, שלא מופיע כאן):
הגדרה חשובה נוספת באותו חלון נבצע בלחיצה על Debugger משמאל. בלשונית Setup, מתחת לכותרת Driver, נבחר במקום Simulator את הפריט ST Link:
ונלחץ על OK כדי לסגור את חלון האפשרויות הזה. אנחנו חוזרים לקוד שב-main.c.
כזכור, כל שמות הרגיסטרים והקבועים האחרים שישמשו אותנו (ואת הקומפיילר) נמצאים בקובץ header מסוים. עבור סביבת הפיתוח הזו, כל הקבצים האלה נמצאים בתיקיה stm/inc במקום בו התקנתם את סביבת הפיתוח. אתרו את הקובץ עם השם שמתאים לדגם הג'וק:
העתיקו את השם שלו (כולל הסיומת) לתוך פקודת include בתחילת הקוד:
ננסה קימפול לבדיקה. נבחר בתפריט Project->Compile:
וסביבת הפיתוח תבקש מאיתנו לבחור תיקיה ושם לקובץ "סביבת העבודה" ("Workspace Files"). לאחר מכן, יופיע למטה פאנל messages ובשאיפה הוא ייראה ככה:
הודעות הקומפיילר בסיום קימפול תקין
אין שגיאות – אפשר לעבור לקוד עצמו.
קוד Blink
למיטב ידיעתי, אף אחד לא כתב ספריות תואמות-ארדואינו ל-STM8S, ואם להאמין לבלוג שהזכרתי אי-שם למעלה, גם הספריות שכן קיימות כדי לעשות למתכנתים חיים קלים קצת יותר אינן אמינות. לכן, נכתוב את הבלינק שלנו בעזרת פניה ישירה לרגיסטרים.
בניגוד ל-AVR ול-PIC, מיקרו-בקרים ממשפחת STM8S מסוגלים לשנות את מקור השעון שלהם תוך כדי ריצה. זו יכולת עם המון פוטנציאל ובוודאי אחקור אותה בעתיד, אך בינתיים פשוט נסתמך על שעון ברירת המחדל שמופעל בכל אתחול: מתנד פנימי של 16MHz, מחולק ב-Prescaler של 8.
אנחנו עובדים עם פין D3, ומהשם שלו ברור שהוא שייך לפורט D, ומיוצג על ידי הביט הרביעי מימין בכל הרגיסטרים של הפורט הזה (מספור הביטים מתחיל מאפס, כך ש-D0 ייוצג על ידי הביט הראשון מימין וכו'). הרגיסטרים הדרושים לתפעול נורית ה-LED הם:
PD_DDR – רגיסטר כיוון הנתונים (Data Direction Register) של פורט D. ביט 0 פירושו שהפין התואם מוגדר כקלט, ו-1 פירושו פלט. לכן, בצורת ניסוח אחת,
PD_DDR = 8;
PD_CR1 – רגיסטר בקרה 1 של פורט D. מה שהוא עושה קצת מתקדם מדי לענייננו, ולכן נאמר רק שעבור המקרה הספציפי הזה, הביט שלנו צריך להיות 1. יש רגיסטר בקרה שני בשם PD_CR2, אבל כרגע הוא חסר משמעות עבורנו.
PD_CR1 = 8;
נכתוב את הפקודות האלה בתחילת הפונקציה main, ולאחר מכן ניכנס ללולאה אינסופית של הדלקה וכיבוי, שיבוצעו באמצעות כתיבה של 1 ו-0 לביט הרביעי מימין ברגיסטר PD_ODR (ראשי תיבות של Output Data Register). אפשר לבצע כתיבות של 0 ושל 1 בנפרד, או לבצע אותן לסירוגין באמצעות חזרה על פעולת XOR (שסימנה בשפת C הוא "^"):
PD_ODR ^= 8;
נשאר לנו רק ליצור השהיה כלשהי, כדי שנוכל לראות את ההבהוב בעיניים. זה עניין של הערכה, או ניסוי וטעיה – נדלג עליהם ונגיע למשהו כזה:
unsigned int i; // ... for (i = 0; i < 40000; i++);
למזלנו, הקומפיילר לא מבצע אופטימיזציה דורסנית מדי ולא מעלים את כל הלולאה הזו שכביכול לא עושה שום דבר חשוב. על הדרך, אפשר גם למחוק את פקודת return 0 שהופיעה כברירת בסוף main – ממילא לא נגיע אליה לעולם והקומפיילר לא יתלונן. הנה הקוד הסופי:
#include <iostm8s103f3.h> int main( void ) { unsigned int i; PD_DDR = 8; PD_CR1 = 8; while (1) { PD_ODR ^= 8; for (i = 0; i < 40000; i++); } }
וכמובן, תמיד כדאי להריץ עוד compile רק כדי לוודא שלא נפלה איזו טעות.
צריבה
נחבר את הצורב ליציאת USB במחשב, נקווה שהמחשב מזהה אותו בלי בעיה, ונבחר בתפריט Project->Download and Debug (או על האייקון המתאים בשורת האייקונים – ראו בצילום המסך):
כעבור שניות ספורות האורות על הצורב יתחילו להבהב, אבל הקוד עדיין לא רץ במצב רגיל – במקום זאת, סביבת הפיתוח תיכנס למצב דיבוג:
זה מצב שימושי וחשוב להפליא, אלא שכרגע אנחנו בסך הכל רוצים לראות לד מהבהב – אז נלחץ על F5, או נבחר בתפריט Debug->Go, או נלחץ על אייקון שלושת החיצים הקטנים. כולם עושים אותו דבר – מעבירים את התוכנית למצב ריצה רגיל.
זהו, יש לנו Blink פועל (בקצב די מהיר). בעזרת האייקונים השונים או תפריט Debug אפשר "להקפיא" את התוכנית באמצע כדי לחזור למצב דיבוג, או להפסיק את הדיבוג לגמרי (המיקרו-בקר ימשיך לפעול עצמאית כמובן).
עד עכשיו, הלוח קיבל את אספקת החשמל מהצורב. אין שום מניעה לנתק את הצורב ולחבר במקום זאת כבל USB (בלוח שלנו, חיבור זה משמש לאספקת חשמל בלבד ולא לתקשורת נתונים) או לספק מתח יציב ומתאים לפין 5V או 3.3V.
לא היה כל כך נורא, נכון? 🙂