בפוסט מס' 2 בסדרה דיברתי על הגדרות שעון שאפשר לבחור עבור ה-ATtiny85 (ומיקרו-בקרים אחרים ממשפחת AVR) באמצעות צריבת פיוזים. מבחר האפשרויות היה כה גדול, עד שבחרתי לדלג שם על חלק מהפרמטרים ולהתרכז אך ורק במקור השעון ובתדר שנבחר עבורו. כעת נתקלתי, לראשונה, במצב בו גם הפרמטרים הנוספים חשובים. אז כהשלמה קטנה לפוסט על הגדרות השעון, בואו נדבר על השהיה באתחול.
הפריט שמסומן בכחול, בתמונה למעלה, הוא הצירוף הבלתי-קריא INTRCOSC_8MHZ_6CK_14CK_64MS. את החלק הראשון אנחנו כבר מכירים: הוא אומר "מתנד RC [נגדים וקבלים] פנימי, בתדר 8 מגהרץ". אבל מה זה 6CK_14CK_64MS?
במסגרת הכנות לפרויקט ניסיוני כלשהו בניתי את המעגל שבתמונה הבאה. זהו מודול של מטריצת לדים 8×8 עם ג'וק בקר תצוגה מדגם MAX7219 (קיט חמוד מאד להלחמה – את שלי השגתי באיביי), שהטייני מריץ עליו נקודות מימין לשמאל. מאחורי המטריצה יש מראה, כדי שתוכלו לראות את הטייני שמסתתר מאחורי המודול.
זה עבד יפה כשזה עבד, אבל חיבור למקור חשמל לא הבטיח תמיד פעולה. לעתים קרובות, שום דבר לא הופיע על המודול או שרק הטור השמאלי פעל, והדרך היחידה לתקן זאת היתה לחבר ולנתק שוב ושוב, לפעמים אפילו ארבע פעמים, עד שזה הסתדר מעצמו. מה קרה שם?
קוד התוכנה מכיל שני חלקים עיקריים. החלק הראשון שולח ל-MAX7219 רצף חיוני של נתוני אתחול שמכין אותו לעבודה, ואילו החלק השני מריץ את הנקודות בלולאה אינסופית. לכן, ובזכות הניסיון שלי עם רכיבים אחרים בעבר, החשוד המיידי היה זמן האתחול של ה-MAX7219 עצמו: אולי, עד שהוא "מתחמם" ומוכן לקלוט מידע, הטייני כבר רץ במלוא הקיטור ושלח לו מזמן נתוני אתחול שהלכו לאיבוד?
הדרך הטבעית לבדוק זאת היא, כמובן, להוסיף השהיה קצרה בתחילת הקוד, לפני שליחת הנתונים. אך לפני שהספקתי לעשות זאת נזכרתי בפרמטרים המסתוריים של שעון הטייני ובמה שהם מגדירים – השהיית אתחול.
החלק הראשון, 6CK במקרה שלנו, אומר כמה מחזורי שעון (בקיצור, CK) יעברו מרגע שהטייני מתחיל לקבל חשמל ועד לרגע שהוא מתחיל לעבוד, ומסתבר שכאשר הוא מתחיל לעבוד, הדבר הראשון שהוא עושה זה להפעיל אות RESET פנימי שהמשך שלו מוגדר על ידי החלק השני, 14CK_64MS. זאת אומרת, מרגע החיבור לחשמל עוברים 6 מחזורי שעון, ואז יש אות RESET שאורכו 14 מחזורי שעון + 64 אלפיות השניה, ורק אז התוכנה מתחילה לרוץ.
שיהיה ברור, אף אחד לא הכניס את ההשהיה הזו לשם כדי להתמודד עם ג'וקים איטיים. הסיבה האמתית לקיומה היא כדי שיהיה למתח של המערכת ולשעון החיצוני, אם יש כזה, זמן להתייצב. אם המיקרו-בקר הוא חלק ממערכת מורכבת מבחינה חשמלית, והמתח רועד קצת בהתחלה ו/או השעון החיצוני מפרפר קצת, זה יכול לדפוק את פעולת הטייני, אז אנחנו יכולים לתת לו זמן המתנה. הטייני שעל המטריצה הוגדר, בפרויקטים קודמים, ל-4CK_16CK_0MS, וכנראה שעשרים מחזורי השעון שלו, בתדר של 8MHz, בתוספת הזמן מתחילת הריצה של הקוד ועד לשליחת הנתונים, היו גבוליים מבחינת ה-MAX7219.
אז כדי לנסות את התיאוריה, שיניתי את הפיוזים כפי שמוצג בתמונה העליונה – ואכן, מאותו רגע הכל עבד פיקס עם כל חיבור מחדש לחשמל.
כדי לוודא שאין אי-הבנות, כלומר שאני לא מקשקש, כתבתי קוד בדיקה ללוח ארדואינו. קוד זה תיעד את הזמן עם הפונקציה millis, מיד לאחר מכן הדליק פין שמשמש כאספקת חשמל לטייני ולמודול, ואז חיכה לאות הראשון שיגיע מפין פלט של הטייני (שמחובר גם למודול). ברגע שהגיע אות, הארדואינו מדד כמה זמן עבר והציג את התוצאה במוניטור הטורי. כל זה נעשה באופן מאולתר ביותר ומאד לא מדויק, אך מספר בדיקות הראו תוצאה עקבית צפויה ומשמחת: 64 אלפיות השניה.
מוסר ההשכל הוא, קודם כל, לתת לכל הרכיבים במערכת זמן להתאפס על עצמם לפני שהמיקרו-בקר מתחיל לתזז אותם. הדרך הנכונה לעשות זאת היא באמצעות הקוד, לא עם הפיוזים של השעון – מה שהראיתי פה הוא כאמור רק הדגמה לימודית. בנוסף, צריך לזכור שלפעמים יש יתרון גם להשהיה קצרה לעומת פעולה מיידית. המיקרו-בקר הוא לא מודל תיאורטי אלא מכשיר חשמלי, שחי בעולם של אי וודאות ושל קפיצות מתחים ותדרים…
כייף לקרוא, תמשיך להעשיר אותנו בניסיון שלך…