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

אוטובוס I2C עבור ATtiny ו- ATmega: 8 שלבים
אוטובוס I2C עבור ATtiny ו- ATmega: 8 שלבים

וִידֵאוֹ: אוטובוס I2C עבור ATtiny ו- ATmega: 8 שלבים

וִידֵאוֹ: אוטובוס I2C עבור ATtiny ו- ATmega: 8 שלבים
וִידֵאוֹ: LDmicro 14: ЖК-дисплей I2C и часы реального времени DS3231 (программирование лестничной схемы ПЛК микроконтроллера с помощью LDmicro) 2024, יולי
Anonim
אוטובוס I2C עבור ATtiny ו- ATmega
אוטובוס I2C עבור ATtiny ו- ATmega

אני אוהב את בקרי ה- AVR של Atmel! מאז בניית מערכת פיתוח הגטאות המתוארת במדריך זה, לא היה לי סוף כיף להתנסות ב- AVR ATtiny2313 וב- ATmega168 בפרט. אפילו הרחיקתי לכת בכתיבת מדריך לשימוש במתגים כתשומות, והרחבתי את התפיסה של מערכת פיתוח הגטאות ל- CPLDs. במהלך פרויקט שנערך לאחרונה, הייתי צריך מספר מתגים לקביעת ערכי בקרה. ל- AVR לא היו מספיק סיכות קלט/פלט, אז הייתי צריך לחשוב על משהו. יכולתי לנסות מערכת קלט מורכבת עם מקלדת ותצוגה, אבל ל- ATtiny2313 היו נגמרים המשאבים. למרבה המזל, Atmel סיפקה דרך לעקוף בעיה זו על ידי הכללת ממשק שיכול לקשר לשבבים נוספים (כגון זיכרון או יציאות קלט/פלט) עם ממשק פשוט דו חוטי. זה נכון, על ידי שימוש בשני סיכות קלט/פלט במכשיר AVR נוכל לגשת לסיכות קלט נוספות נוספות ולמשאבים אחרים. ממשק דו חוטי זה מכונה רשמית האוטובוס המעגל הבין-משולב, או רק האוטובוס I2C והומצא על ידי NXP כשהוא עדיין היה פיליפס למחצה. אם אתה קורא את המדריך הזה, כנראה ששמעת על האוטובוס I2C ואולי אפילו השתמשת בו ב- PIC או במיקרו -בקר אחר. בעוד שהם מושגים פשוטים מאוד ונתמכים על ידי משאבי חומרה במכשירי ה- AVR, עדיין יש צורך במנהלי התוכנה לשימוש באוטובוס I2C. Atmel מספק הערות יישומים (עיין במשאבים מאוחר יותר במדריך זה), אך אלה אינם שלמים ואינם מראים דוגמאות מעבר לתקשורת עם מכשיר AVR אחר. אין מטרתו של הוראה זו ללמד אף אחד כיצד ליצור מנהלי התקנים I2C עבור AVRs. במקום זאת, אספק גרסאות מורחבות של מנהלי ההתקן של Atmel למכשירי ATtiny2313 ו- ATmega168, אסביר את הדרישות והמגבלות החלות בעת שימוש באלה, ואראה לכם דוגמאות עבודה למכשירי I2C. לאחר שתעבוד באמצעות הוראה זו תוכל להשתמש באוטובוס I2C בהצלחה בפרויקטים של AVR. ברור שאתה יכול להתעלם מהנהגים של זעירים או מגה אם אתה מעוניין רק באחד מהם. למי שמעוניין ללמוד עוד על האוטובוס I2C, אביא קישורים לחומרים המתאימים.

שלב 1: מה זה בכלל הדברים האלה של I2C?

מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?
מה זה בכלל הדברים האלה של I2C?

האוטובוס I2C הוא חיבור פשוט דו-חוטי שיכול לקשר מספר מכשירים יחד ולאפשר להם להחליף נתונים. בצורתו הפשוטה ביותר יש מכשיר אב אחד המתקשר למספר התקני עבדים. כל המכשירים מחוברים במקביל לשני החוטים של אוטובוס I2C. שני החוטים ידועים בשם SCL ו- SDA. SCL הוא קו השעון ונשלט על ידי התקן הראשי. SDA הוא קו הנתונים הדו-כיווני. כדי להעביר נתונים, המאסטר שולח כתובת עבדים בשילוב עם דגל קריאה/כתיבה של ביט אחד. אם תרצה כתיבה, המאסטר ימשיך לשלוח נתונים אל העבד המופנה. אם תתבקש קריאה, העבד יגיב עם נתונים. כדי לתאם עסקאות, קווי ה- SCL וה- SDA מתבצעים על ידי המאסטר והעבד לאותת על מספר תנאים. אלה כוללים START, STOP, ACK (אישור) ו- NAK (ללא אישור). פרטי התנאים הללו מטופלים על ידי הנהגים. החנונים האמיתיים מביניכם יכולים ללמוד את כל הפרטים בקישורים המופיעים בסוף מדריך זה. דרישות החשמל די פשוטות. המאסטר והעבדים חייבים להשתמש באותה רמה עבור Vcc, השטח חייב להיות מחובר, ואת הקווים SCL ו- SDA יש למשוך למעלה ל- Vcc. ערך נגדי המשיכה נקבע במדויק על ידי חישוב המבוסס על הקיבול הכולל באוטובוס, אך למעשה יכול להיות בערך כל ערך בין 1.8K ל -10K. אני מתחיל עם 5.1K ומשתמש בערכים נמוכים יותר עד שזה עובד. בדרך כלל זו לא בעיה אלא אם יש לך הרבה מכשירים או אורך חוט ארוך בין מכשירים. קצב הנתונים הנומינלי באוטובוס I2C הוא 100Kbits/sec. תעריפים של 400Kbits/second, 1Mbits/second ומעבר אפשריים גם כן, אך אינם נתמכים על ידי הנהגים במדריך זה. כל מכשירי I2C יעבדו במהירות של 100Kbits לשנייה. ATtiny2313 ו- ATmega168 מיישמים כל אחד את האוטובוס I2C באופן שונה. ATtiny2313 משתמש בחומרת ממשק סידורי אוניברסלי (USI) - שיכול לשמש גם לאוטובוס SPI. ל- ATmega168 יש חומרה ייעודית לאוטובוס I2C המכונה ממשק דו חוטי (TWI). לאחר כתיבת מנהלי ההתקנים, ההבדלים הללו לרוב שקופים למשתמש. הבדל משמעותי אחד הוא בתוכנה: מנהל ההתקן ATmega168 I2C מונע הפרעה בעוד של ATtiny2313 לא. המשמעות היא שתוכנית ATmega168 לא צריכה לחכות עד שתבוצע העברת נתונים של I2C, אלא רק להמתין לפני תחילת העברה נוספת, או עד שיגיעו נתונים מפעולת קריאה. הדוגמאות והדיון להלן אמורים להבהיר את כתובות ה- I2C באורך 7 סיביות, כך שאפשר להגיע לאוטובוס עד 127 מכשירים אם לכל אחת יש כתובת ייחודית. כפי שמוצג באיור, כתובת זו של 7 סיביות מועברת שמאלה לביט אחד והסיבית הפחות משמעותית משמשת לסימון קריאה או כתיבה של המכשיר בכתובת. לפיכך כתובת העבד השלמה היא בת 8 ביט. הכתובת בפועל נקבעת באופן חלקי פנימי למכשיר ואינה ניתנת לשינוי (4 סיביות משמעותיות ביותר), ונקבעת באופן חלקי על ידי סיביות שעשויות להיות מחוברות לסיכות התקן (3 סיביות פחות משמעותיות) שניתן לקשור אותן גבוה או נמוך כדי להגדיר אותן כתובת ספציפית. נשמע מבלבל, אך דוגמא תבהיר זאת. גליון הנתונים PCA8574A מראה כי ארבעת הביטים המשמעותיים ביותר של כתובת I2C יהיו תמיד 0111. שלושת הביטים הבאים נקבעים על פי ההגדרות בסיכות AD0, AD1 ו- AD2. ניתן לקשור סיכות אלה לקרקע או לאספקת המתח החיובי (5 וולט) כדי לייצג 0 או 1 בהתאמה. אז טווח הכתובות האפשריות הוא 38 עד 3F הקסדצימלי, כפי שמוצג באיור השני מתוך דף הנתונים PCA8574. אז על ידי שינוי הגדרות סיביות הכתובת, עד 8 PCA8574A יכולים להיות באוטובוס I2C בו זמנית. כל אחד יגיב לכתובת העבד הספציפית שלו בלבד. אם יש צורך בעוד יציאות קלט/פלט, ניתן להשתמש ב- PCA8574. ההבדל היחיד בין ה- PCA8574 לבין ה- PCA8574A הוא שטווח כתובות העבדים I2C של ה- PCA8574 הוא 20 עד 27. הקסדצימלי. קביעת הכתובת של התקן נתון עלולה להיות מבלבלת מכיוון שחלק מדפי הנתונים רואים את ביט הקריאה/כתיבה כחלק מה- כתובת. קרא בעיון את דף הנתונים וזכור כי כתובת העבד תהיה באורך של 7 סיביות. יש להתייחס לביט הקריאה/כתיבה בנפרד. שוב, דוגמא תעזור. גיליון הנתונים עבור EEPROM 24C16 שאנו מתנסים בו אומר שארבעת הביטים הראשונים (המשמעותיים ביותר) של כתובת העבד הם 1010. ניתן לקבוע את שלוש הסיביות הבאות על ידי A0, A1 ו- A2; אך שים לב שגיליון הנתונים מכסה גם 24C01 עד 24C08 שהם קטנים יותר ב- EEPROM. האיור מגליון הנתונים מראה שההגדרות של סיביות כתובת אלה מתעלמות ככל שהגודל עולה ומתעלמות לחלוטין מה- 24C16. כלומר, שלושת הביטים האחרונים לא חשובים וה- 24C16 באמת משתמש בכל כתובות העבדים I2C 50 עד 57 הקסדצימלי. טווח כתובות העבדים יתייחס למעשה למקטעים שונים בתוך 24C16. 256 הבייטים הראשונים נמצאים בכתובת 50h, 256 הבאים ב -51h, וכן הלאה עד 256 האחרונים ב -57h - בסך הכל 2K בתים. מכיוון שהכתובת של ה- PCF8570 RAM שאנו גם מתנסים איתה נמצאת בטווח זה, לא ניתן להשתמש ב- 24C16 וב- PCF8570 יחד.

שלב 2: הזמינו כמה התקני I2C

עכשיו שאתה יודע קצת על אוטובוס I2C ורוצה להשתמש בו, מדוע שלא תזמין כמה מכשירי I2C להתנסות בהם כעת כדי שהם יוכלו להיות בדרך אליך בזמן שתכין את התוכנה? מכשירים מתאימים כוללים I/ O Expander Expander (המועדף עלי), Ram סטטי ו- EEPROM. יש עוד הרבה, אבל אלה התחלה מצוינת. מעבדי ה- AVR בהם נשתמש הם ה- ATtiny2313 וה- Atmega168 (המשמשים בארדואינו). אם אתה חדש בתחום, עיין במדריך הנהדר הזה כדי ללמוד עליהם ולבנות את מערכת פיתוח הגטו שלך. סכמטי ה- ATmega168 במדריך הנוכחי מראה כיצד ליישם את מערכת פיתוח הגטו עבור מעבד זה. כבל היציאה המקבילה זהה לזה של ה- ATtiny2313. (לא ניסיתי את גרסת ה- USB של מערכת הפיתוח של הגטו, כך שאני לא בטוח כיצד ניתן לגשת אליו לאוטובוס I2C. כנ ל לגבי הארדואינו.) להלן מספרי חלקים של Digikey. מרחיב הנמל: IC I2C I/O EXPANDER 568-4236-5-NDRam: IC SRAM 256X8 W/I2C 568-1071-5-NDEEPROM: IC EEPROM SERIAL 16K CAT24C16LI-G-ND

שלב 3: מנהלי התקנים I2C

להלן תיאורי פונקציות הנהג לאוטובוס I2C. אלה פותחו באמצעות פתקי Atmel Apps למתחילים. לא יכולתי לעשות את זה בלעדיהם כבסיס לבנות עליו. הפיתוח נעשה באמצעות WinAVR ובמהדר gcc C. הגבלות קצב השעון מתוארות להלן עבור כל מעבד. מכיוון שאיני מסוגל לבדוק את כל שילובי הטעמים / קצב השעון האפשריים, אני פשוט אדבוק במה שאני באמת יכול לבדוק ואנסה לציין את המגבלות והמגבלות. להלן פונקציות הנהג וכיצד להשתמש בהן. אנא עיין בדוגמאות לפרטים נוספים ולראות את הפונקציות הנמצאות בשימוש בתוכניות שלמות. עבור ATtiny2313: דרישת שעון: מנהלי ההתקנים מיועדים לקצב שעון של 1MHz (שיעור ברירת המחדל) עבור ATtiny2313. אם אתה רוצה לרוץ בקצב אחר, יהיה עליך להתאים קבועים במנהלי ההתקן. שלח לי דוא"ל אם אתה צריך עזרה לעשות את זה. תוכל גם לקבל כמה רמזים מהערות אפליקציות Atmel בקישורים שבשלב Resources. USI_TWI_Master_Initialise () פונקציה זו מאתחלת את חומרת USI לפעולת מצב I2C. קראו לזה פעם אחת בתחילת התוכנית שלכם. היא מחזירה חלל ואין ארגומנטים. USI_TWI_Get_State_Info () פונקציה זו מחזירה פרטי שגיאה I2C והיא משמשת אם אירעה שגיאה במהלך עסקת I2C. מכיוון שפונקציה זו מחזירה רק קוד שגיאה, אני משתמש בפונקציה TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) כדי להבהב נורית שגיאה. קודי השגיאה מוגדרים ב- USI_TWI_Master.h. כך קוראים לזה: TWI_Act_On_Failure_In_Last_Transmission (USI_TWI_Get_State_Info ()) USI_TWI_Start_Read_Write () פונקציה זו משמשת לקריאה וכתיבה של בתים בודדים למכשירי I2C. הוא משמש גם לכתיבת בתים מרובים. ישנם שישה שלבים לשימוש בפונקציה זו.1) הכריז על מאגר הודעות בתוכנית שלך בכדי להחזיק את כתובת העבד ואת בית הנתונים שיש לשלוח או לקבל. uns char char messageBuf (MESSAGEBUF_SIZE); 2) שים את כתובת ה- Slave כבייט הראשון במאגר. העבר אותו קצת שמאלה ו- OR בקטע קריאה/כתיבה. שים לב שקצת קריאה/כתיבה תהיה 1 לקריאה ו- 0 לכתיבה. דוגמה זו מיועדת לקריאה. messageBuf (0) = (TWI_targetSlaveAddress << TWI_ADR_BITS) | (TRUE << TWI_READ_BIT); 3) בעת ביצוע כתיבה, הכנס את הבייט שייכתב למיקום הבא במאגר. 4) התקשר לפונקציה USI_TWI_Start_Read_Write עם מאגר ההודעות וגודל ההודעה כ- arguments.temp = USI_TWI_Start_Read_Write (messageBuf, 2); 5) The ניתן לבדוק את הערך המוחזר (טמפ 'במקרה זה) כדי לראות אם אירעה שגיאה. אם כן, הוא מטופל כפי שנדון לעיל. ראה דוגמאות בתוכניות.6) אם הייתה בקשת קריאה, קריאת הבייט תהיה במיקום השני במאגר. אם יש לכתוב מספר בתים (כגון להתקן זיכרון), ניתן להשתמש באותה שגרה. הגדרת המאגר והתקשרות לשגרה מעט שונות. הבייט השני במאגר יהיה כתובת הזיכרון ההתחלתית שאליה יש לכתוב. הנתונים שייכתבו יהיו בבייטים הבאים. גודל ההודעה יהיה הגודל כולל כל הנתונים התקפים. אז אם יש לכתוב 6 בתים, גודל ההודעה יהיה 8 (כתובת עבדים + כתובת זיכרון + 6 בתים של נתונים). USI_TWI_Start_Random_Read () פונקציה זו משמשת לקריאת בתים מרובים ממכשיר I2C, בדרך כלל זה משמעותי רק עבור זיכרון כלשהו. השימוש בשגרה זו דומה מאוד לשגרה הקודמת, למעט שני יוצאים מן הכלל. ההגדרה של סיבי הקריאה/כתיבה אינה משנה. קריאה לשגרה זו תמיד תגרום לפעולת קריאה. ההודעה גודל צריכה להיות 2 פלוס מספר הבייטים לקריאה. אם לא אירעו שגיאות, הנתונים יהיו במאגר החל מהמיקום השני. עבור ATmega168: דרישת השעון: מנהלי ההתקן מיועדים לקצב שעון של 4MHz עבור ATmega168. הקוד לדוגמה מראה כיצד להגדיר את קצב השעון הזה. אם אתה רוצה לרוץ בקצב אחר, יהיה עליך להתאים קבועים במנהלי ההתקן. שלח לי דוא"ל אם אתה צריך לעשות זאת. TWI_Master_Initialise () פונקציה זו מאתחלת את חומרת ה- TWI לפעולת מצב I2C. קראו לזה פעם אחת בתחילת התוכנית שלכם. הוא מחזיר בטל ואין טענות. הקפד לאפשר הפרעות על ידי התקשרות swi () לאחר האתחול. TWI_Get_State_Info () פונקציה זו מחזירה פרטי שגיאה I2C והיא משמשת אם אירעה שגיאה במהלך עסקת I2C. מכיוון שפונקציה זו מחזירה רק קוד שגיאה, אני משתמש בפונקציה TWI_Act_On_Failure_In_Last_Transmission (TWIerrorMsg) כדי להבהב נורית שגיאה. קודי השגיאה מוגדרים ב- TWI_Master.h, אך משתנים לאיתור על נורית שגיאה. עיין בקוד לדוגמא לפרטים. הנה איך לקרוא לזה: TWI_Act_On_Failure_In_Last_Transmission (TWI_Get_State_Info ()) שים לב שבדיקת השגיאות מתבצעת על ידי וודא שעסקת I2C הושלמה (הפונקציה המתוארת להלן) ולאחר מכן בודקת מעט במילת הסטטוס העולמית. TWI_Start_Read_Write () TWI_StartR) שתי פונקציות פועלות זהה לפונקציות המתאימות שתוארו לעיל אך עם מספר חריגים. הן אינן מחזירות ערכי שגיאה. קריאת הנתונים אינה מועברת למאגר. פעולה זו תתבצע בעזרת הפונקציה המתוארת להלן. בעת קריאה ל- TWI_Start_Random_Read, ההודעה Size צריכה להיות מספר בתים הנתונים המבוקשים פלוס אחד, לא שניים. מנהל ההתקן I2C של ה- ATmega168 מונע הפרעה. כלומר, עסקאות I2C מתחילות ולאחר מכן מתבצעות באופן עצמאי בזמן שהשגרה העיקרית ממשיכה לפעול. כאשר השגרה העיקרית רוצה נתונים מעסקת I2C שהיא התחילה, עליה לבדוק אם הנתונים זמינים. המצב זהה בבדיקת שגיאות. השגרה העיקרית חייבת להיות בטוחה שעסקת I2C הושלמה לפני בדיקת טעויות. שתי הפונקציות הבאות משמשות למטרות אלה. TWI_Transceiver_Busy () התקשר לפונקציה זו כדי לבדוק אם עסקת I2C הושלמה לפני בדיקת שגיאות. התוכניות לדוגמא מראות כיצד להשתמש בזה. TWI_Read_Data_From_Buffer () התקשר לפונקציה זו כדי להעביר נתונים ממאגר הקבלה של מנהל התקן I2C למאגר ההודעות. פונקציה זו תוודא שעסקת I2C הושלמה לפני העברת הנתונים. בעוד ערך מוחזר על ידי פונקציה זו, אני מוצא שבדיקת ביט השגיאה ישירות היא אמינה יותר. הנה איך לקרוא לזה. גודל ההודעה צריך להיות אחד גדול ממספר נתוני הנתונים הרצויים. הנתונים יהיו ב- messageBuf החל מ- location.temp = TWI_Read_Data_From_Buffer (messageBuf, messageSize);

שלב 4: בואו לבנות

בוא נבנה!
בוא נבנה!
בוא נבנה!
בוא נבנה!
בוא נבנה!
בוא נבנה!
בוא נבנה!
בוא נבנה!

התחל בהורדת הקובץ I2C Schematics.zip. ייתכן שתרצה ליצור תיקיית I2C באזור העבודה שלך בכדי להכיל את הסכימות וקבצי התוכנית לדוגמה. שחרר את הסכימות לספרייה זו. תמצא תיקייה בשם I2C Schematics. פתח את הקובץ בשם זעיר I2C.pdf. סכמטי זה מציג את מערכת פיתוח הגטו ATtiny2313 ואת מרחיב יציאות הקלט/פלט PCA8574A (יש את הקופסה הגדולה המקווקת סביבו). מעגל הרחבת הנמל בנוי על לוח לחם. תסתכל על התמונות כדי לראות איך המעגלים האלה נראים. הם באמת די פשוטים. חלק ה- ATtiny2313 של הסכימה הוא רק מערכת הפיתוח של הגטו עם שלושה בלינקרים (LED1, 2 ו- 3, בתוספת R4, 5 ו- 6) ולחצן (S1) המחובר אליו, ועוד אחד פירוט נוסף. פרט זה הוא תוספת של מגשרים (JP4, 5 ו- 6) אותם ניתן להסיר כדי לאפשר חיבור של קווי ה- SCL וה- SDA של אוטובוס I2C. המגשרים חייבים להיות במקומם לתכנות, ולאחר מכן מוסרים כך שניתן לחבר SCL ו- SDA. התמונות מציגות את המגשרים במקום והוסרו. מיקום מגשרים אלה תלוי בך, אתה רק צריך לשים אותם במערכת הפיתוח של הגטו אם אתה רוצה להשתמש באוטובוס I2C. יש לנתק את האוטובוס I2C ולשים את המגשרים לתכנות. שים לב שאתה רק צריך להיות מודאג לגבי JP4 ו- JP6 עבור אוטובוס I2C. הכנס JP5 אם אתה חושב שאי פעם תרצה להשתמש באוטובוס SPI. הלוח על PCA8574A I/O Expander Port הוא פשוט מאוד. ספק חיבורי Vcc (+5 וולט) ו- Gnd (קרקע) וחבר את AD0, 1 ו- 2 לאדמה (הופך את כתובת העבד I2C 38 hex). לאחר מכן חבר 4 בלינקרים ו -4 מתגי DIP. (אם אין לך מתגי DIP אתה יכול פשוט להשתמש בחוטים. לקשור לאדמה או להשאיר צפים לאות או לכבות בהתאמה.) לבסוף, חבר את נגדי המשיכה (R11 ו- 12) מ- SDA ו- SCL ל- Vcc. אלה מוצגים כ -3.3K, אך כל ערך מ -1.8K עד 5.1K אמור לעבוד (אולי עד 10K אבל לא ניסיתי זאת). לאחר שתכנת את ה- ATtiny2313 תוכל להסיר את המגשרים ולחבר SDA ו- SCL לבדיקה. כעת ל- ATmega168. הקמט היחיד כאן הוא שאולי לא בנית מערכת פיתוח גטו למעבד זה. אם זה המצב, הסכימה שאני מספקת (MEGA I2C.pdf) תראה לך כיצד. זוהי רק תמורה של גרסת ATtiny2313. אם אתה מתכנן מראש תוכל לוודא שכבל התכנות שלך יתאים לשתי המערכות. ההבדל העיקרי הוא תוספת C2 ו- C3. עיין בתמונות למיקום אלה, הם צריכים להיות קרובים מאוד לשבב; אחד מהם נמצא למעשה מתחת לשבב. אלה עוזרים לשמור על רעש מחוץ לממיר האנלוגי לדיגיטלי בפרט. אינך צריך להכניס את המגשרים אלא אם אתה מתכוון להשתמש באוטובוס SPI מכיוון שהם אינם נחוצים לאוטובוס I2C בשבב זה. שים לב כי לוח הלחם PCA8754A לא ישתנה. פשוט תחבר SDA ו- SCL ותסתלק! קל, הא?

שלב 5: בואו לקודד ולבדוק

בואו לקודד ולבדוק!
בואו לקודד ולבדוק!
בואו לקודד ולבדוק!
בואו לקודד ולבדוק!
בואו לקודד ולבדוק!
בואו לקודד ולבדוק!

הגיע הזמן לבנות את מנהלי ההתקן ואת התוכניות לדוגמא. נתחיל עם ה- ATtiny2313 ולוח הלחם PCA8574A שבנינו זה עתה. הורד את הקובץ I2C.zip לספריית העבודה שלך ב- I2C ופתח אותו. תהיה לך תיקייה חדשה בשם I2C. בו תוכלו למצוא את USI I2C (עבור ATtiny2313) ו- TWI I2C (עבור ATmega168). ב- USI I2C תמצא את תיקיית I_O Port. תיקיה זו מכילה את הקוד לתוכנית הדוגמא הראשונה שלנו ואת מנהלי ההתקן של USI I2C. בעזרת WinAVR, הידור וטען את הקוד לתוך ה- ATtiny2313. קח נשימה עמוקה והפעל את הכוח. הנה למה לצפות: בעת הדלקה, LED 1 ביציאת PD6 של ה- ATtiny2313 מהבהב פעמיים. שום דבר אחר לא יקרה עד שתלחץ על הכפתור (S1). בכל לחיצה על הלחצן, המתגים נקראים והגדרתם תוצג על נוריות ה- LED המחוברות ל- PCA8574A. שנה את ערך המתגים, לחץ על הכפתור, ונורות הלדים צריכות להשתנות. המשך לעשות זאת עד שתתגבר על הריגוש לראות את זה עובד. אם (חלילה!) הדברים אינם פועלים כמצופה, בדוק היטב את החיווט שלך. שגיאות I2C יסומנו על ידי מצמוצים ב- LED3 (PD4) וכנראה שזה אומר שאתה צריך לבדוק ש- SDA ו- SCL מחוברים לפינים הנכונים ומועלים כלפי מעלה כראוי.אם הדברים עדיין לא עובדים, קרא את שאר החלק הזה כדי ללמוד על איתור באגים. עכשיו חזור ובוא נסתכל על הקוד. פתח את הקובץ USI_I2C_Port.c. זהו הקוד לתוכנית לדוגמא. (USI_TWI_Master.c ו- USI_TWI_Master.h מכילים את מנהלי ההתקן - אתה יכול להתעלם מהם אלא אם אתה סקרן.) השתמש בדוגמה להנחיית יישומי I2C משלך. לרוב, התוכנית מראה לך כיצד לאתחל ולהשתמש במנהלי ההתקן I2C, כולל הגדרה מעלה את כתובת העבד ושאר מאגר ההודעות, ומוציא את הנתונים ממנה. תוכלו גם לראות כיצד אני מוריד את הכפתור ומגדיר את לולאת ה- while. יש כמה פרטים על התוכנית שראוי להזכיר. שים לב שהנתונים מהמתגים הופכים לפני שהם נכתבים לנוריות במרחיב הנמל. שים לב גם שיש לכתוב את יציאות הקלט ב- Expander Port כ- High כדי לגרום להן לפעול כראוי. פרטים אלה מתוארים בגיליון הנתונים PCA8574A. תמיד קרא בעיון את דפי הנתונים! מעניין יותר את השימוש באיתור מותנה. סמוך לתחילת קובץ התוכנית נמצאת המשפט // #define DEBUG ומפוזרים לאורך הקוד #ifdef DEBUG הצהרות. כל עוד DEBUG לא מוגדר (שני האלכסונים הופכים את השורה להערה ומונעים ממנה להיות מוגדר), הקוד בתוך הצהרות #ifdef ל- #endif לא יורכב. אך אם הדברים אינם פועלים כפי שאתה מצפה, הרכיב מחדש וטעון מחדש את הקוד כאשר #define DEBUG לא התייחס. תקבל הרבה יותר מהבהבים על נוריות הלדים שתוכל לפענח כדי לעקוב אחר ביצוע התוכנית שלך ולסייע לך למצוא בדיוק היכן הדברים משתבשים. למעשה, אני ממליץ לך לנסות זאת רק כדי לראות מה קורה. מה שתראה הוא ש- LED 2 (ב- PD5) יהבהב עם התקדמות הביצוע בתוכנית. הערך הנקרא מהמתגים יהבהב בנורית 1 (PD6) לפני שהוא יוצג על נוריות הרחבת הנמל. אתה אמור להיות מסוגל לעקוב אחר התוכנית כפי שהיא פועלת באמצעות נוריות אלה. נעבוד עם ATmega168 הבא; דלג על סעיף זה אם אתה מתעניין רק ב- ATtiny2313. עדיין איתי? טוֹב. עבור לתיקיה TWI_I2C, שנה את ספריית העבודה שלך ל- IO_Port, ואסוף וטען את TWI_I2C_Port.c לתוך ATmega168. נתק את קווי SDA ו- SCL מה- ATtiny2313 וחבר אותם ל- ATmega168. תחבר חשמל וקרקע, והפעל. הפעולה צריכה להיות זהה! שחק עד שהריגוש יירגע, ואז בואו נסתכל על הקוד. פתח את TWI_I2C_Port.c. הקוד כמעט זהה למעט טיפול בשגיאות והתאמה לנהגים מונעי הפרעות. להלן ההבדלים: שים לב שצריך להגדיר את השעון ל- 4MHz כדי שאוטובוס I2C יפעל כראוי. ה- sei (); הצהרה מפעילה הפרעות לאחר אתחול מנהלי ההתקן של I2C. כדי לבדוק אם יש שגיאות, נבדק ביט סטטוס ספציפי. במהלך קריאה, יש לקרוא לפונקציה TWI_Read_Data_From_Buffer כדי להעביר את הנתונים הנקראים למאגר ההודעות. במהלך כתיבה, בעוד (TWI_Transceiver_Busy ()) יש להשתמש כדי לוודא שההעברה הושלמה לפני בדיקת שגיאות. שתי הפונקציות האחרונות מתוארות לעיל בתיאור מנהלי ההתקן. מלבד זאת, הקוד די דומה לזה של ה- ATtiny2313. DEBUG עובד אותו דבר גם אם אתה רוצה להתנסות בזה.

שלב 6: שימוש בזיכרון I2C

שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C
שימוש בזיכרון I2C

כעת, לאחר שלמדנו להשתמש באוטובוס I2C לקריאה וכתיבה של מרחיב יציאות קלט/פלט, בואו נעבור לשימוש בזיכרונות I2C, הן RAM והן EEPROM. ההבדל העיקרי הוא שניתן לקרוא או לכתוב מספר בתים מתוך זיכרונות באמצעות פקודה אחת I2C. כדי להתכונן לניסויים אלה, עלינו לשנות מעט חומרה ולבנות כמה מעגלים חדשים על לוח הלחם. שמור על מעגל הרחבת הנמל מכיוון שנשתמש בו כדי להציג כמה ערכי זיכרון. הסר את מתגי ה- DIP מה- PCA8574A והנח blinkenlights על אותם סיכות. אם אין לך מספיק בלינקלייטים, העבר את אלה ב- P4 ל- P7 ל- P0 ל- P3. (הערכים שיוצגו קטנים מספיק.) עכשיו תסתכל על סכמטי I2C Ram.pdf וחיבור ה- PCF8570 ללוח הלחם. תסתכל גם על התמונה. הקפד לקשור את סיכה 7 ל- Vcc. הפעל חוטים עבור SDA ו- SCL מה- PCA8574A. אין צורך בנגדי משיכה נוספים. אם אתה מעוניין גם ב- EEPROM, בנה את המעגל הזה גם באמצעות I2C EEPROM.pdf עבור 24C16, אך הזהר כי הדוגמה משתמשת ב- ATmega168. המעגל הזה ממש פשוט. כפי שנדון לעיל, יש להתעלם מבסיסי הכתובת. פשוט תחבר את החשמל לאדמה. אל תחבר SDA ו- SCL עדיין כיוון שלא סיימנו להתנסות ב- Ram. נתחיל את ניסויי הזיכרון שלנו עם ה- ATtiny2313 המחובר למרחיב הנמל PCA8574A ול- PCF8570 Ram. התוכנית תכתוב מספרים ל- Ram, ולאחר מכן תקרא אותם בחזרה ותציג אותם במרחיב הנמל. שנה את ספריית העבודה שלך ל- RAM תחת USI I2C. השתמש בקובץ make כדי לאסוף ולהוריד את USI_I2C_RAM.c. שים לב שקבצי מנהלי ההתקן I2C זהים לאלה בהם השתמשנו קודם לכן. תחבר את החשמל ואתה אמור לראות מצמוץ אחד על נורית 1 (PD6). הנתונים ייכתבו ל- 4 בתים הראשונים של הזיכרון. לחץ על הכפתור ושני בתים יקראו לאחור ויוצגו. אתה אמור לראות נורת LED אחת במרחיב הנמל (P0), הפסקה של שתי שניות, ואז שתי נוריות נוריות (P0 ו- P1). עוד הפסקה של שתי שניות והנורות צריכות להיכבות. לחץ שוב על הכפתור כדי להתחיל את הרצף מחדש. איתור באגים דומה לשיטה שתוארה לעיל. בואו נסתכל על הקוד. פתח את USI_I2C_RAM.c. זה אמור להיראות די דומה לקוד הקודם. ההבדלים העיקריים הם פרטי זיכרון הקריאה והכתיבה. תסתכל על הדרך שבה מאגר ההודעות נטען לפני השיחה שבאמת עושה את הכתיבה. הבייט הראשון הוא כתובת העבדים עם סיבי הקריאה/הכתיבה שנקבעו כראוי. אבל הבייט הבא הוא כתובת הזיכרון שבה מתחילים לכתוב נתונים. לאחר מכן מגיעים בתים הנתונים האמיתיים אשר ייטענו ברצף לזיכרון החל מהכתובת שציינו. אנו מציינים את גודל ההודעה כ- 6. אז אנו מתחילים לכתוב בכתובת 00 וכותבים את הערכים 01, 03, 02 ו- 06 למיקומי הזיכרון 00 עד 03. כדי לקרוא את הנתונים בחזרה מהזיכרון עלינו להשתמש בפונקציה USI_TWI_Start_Random_Read. מאגר ההודעות מקבל את כתובת העבד בבייט הראשון ואת כתובת ההתחלה בבייט השני. לאחר מכן התקשר לפונקציה עם גודל ההודעה המוגדר למספר בתים לקריאה פלוס 2. שים לב שהסיביות קריאה/כתיבה אינן חשובות מכיוון שקריאה תתבצע ללא קשר. הנתונים המוחזרים יתחילו במיקום השני במאגר ההודעות. לאחר קריאת הנתונים, הם הופכים להצגה ב- Expander Port ונכתבים אליו בתור אחד בכל פעם עם הפסקה בין הערכים. לבסוף, נוריות הרחבת הנמל כבויות. הכתיבות למרחיב הנמלים זהות למה שנעשה בדוגמאות הקודמות. בשביל הכיף, אתה יכול לבטל את התגובה של #define DEBUG כאמור לעיל ולראות הרבה נורות מהבהבות. נשטף מהתרגשות לאחר ניסוי מוצלח נוסף, נעבור ל- ATmega168 ו- EEPROM. שנה את ספריית העבודה שלך ל- EEPROM תחת TWI I2C. השתמש בקובץ make כדי לאסוף ולהוריד TWI_I2C_EEPROM.c. שים לב שקבצי מנהלי ההתקן I2C זהים לאלה שבהם השתמשנו קודם לכן עבור ה- PCA8574A. כדי לבדוק את התוכנית, נתק את ה- ATtiny2313 וחבר את ה- ATmega168. השאר את אוטובוס I2C מחובר לרם והפעל אותו. התוצאות שונות מכיוון שאנו כותבים וקוראים נתונים נוספים. נורית 1 על PD7 אמורה להבהב בעת האתחול. לחץ על הכפתור והנתונים ייקראו בחזרה מהזיכרון ויוצגו. נוריות ה- PCA8574 צריכות להבהב ברצף הבא: P1, P0 & P2, (כבוי כולן), P0 & P1, P1 & P2. לבסוף נוריות ה- Port כולן צריכות להיכבות. לחץ שוב על הכפתור כדי לחזור על זה. אה, אבל רגע, אתה אומר. האם התוכנית הזו לא מתאימה ל- EEPROM? מכיוון שאנו ניגשים להתקן זיכרון באותה כתובת I2C, אותה תוכנית פועלת הן עבור ה- Ram והן עבור ה- EEPROM. כבה והעבר את SDA ו- SCL מה- Ram ל- EEPROM והפעל את התוכנית שוב. זה אמור לעבוד בדיוק אותו דבר. שים לב כי לא ניתן לחבר את ה- EEPROM וה- Ram לאוטובוס I2C בו זמנית מכיוון שהם חולקים את אותה כתובת. (החכמים מביניכם עשויים לשקול לשנות את סיביות הכתובת הניתנות לתכנות ברם, אך זה עדיין לא יעבוד. 24C16 משתמש בכל בלוק הכתובות שניתן לתכנת עבור הרם.) בסדר, בואו נסתכל על התוכנית האחרונה הזו.. פתח את TWI_I2C_EEPROM.c. הדבר הראשון שיש לשים לב אליו הוא שציינתי כיצד לטפל ב- EEPROM המלא 24C16. ניתן לגשת אליה בנתחי 256 בתים ב -8 כתובות עבד I2C שונות. ראה כיצד MEMORY_ADDR מוגדר ככתובת ההתחלה ב- 50 הקסדצימלי; זו הסיבה שהראם עבד. אם אתה רוצה לגשת לבלוקים אחרים של 24C16, השתמש בכתובות האחרות כפי שציינתי. תסתכל איך התכוננתי לכתוב לזיכרון. תחילה הכניסו את כתובת העבד עם ערכת הסיביות קריאה/כתיבה למאגר, ולאחר מכן את כתובת ההתחלה של 00, ולאחר מכן 16 בתים של נתונים. הפונקציה TWI_Start_Read_Write נקראת בכדי לכתוב את הנתונים (כמו קודם) כאשר גודל ההודעה מוגדר ל- 18. כאשר לוחצים על הכפתור, אנו משתמשים ב- TWI_Start_Random_Read וב- TWI_Read_Data_From_Buffer כדי לקרוא את הנתונים בחזרה. כל בת שלישית מוצגת על נוריות ה- Expander Port. לבסוף, הנוריות כבויות להמתנה ללחיצה על הכפתור הבא. אתה עשוי לתהות מדוע בחרתי לכתוב 16 בתים. אם תקרא את גיליון הנתונים בעיון, תראה כי 24C16 עושה מחזור כתיבה בכל פעם שהוא מקבל 16 בתים גם אם נשלחים יותר בתים. אז זה נראה כמו מספר נחמד לשימוש. אם תבחר להגדיל זאת, יהיה עליך לשנות את הגודל של MESSAGEBUF_SIZE. יהיה עליך גם לשנות את הערך TWI_BUFFER_SIZE ב- TWI_Master.h. הסיבה לכך היא שהנהג מעתיק את הנתונים ממאגר ההודעות לשימוש בשגרת שירות ההפרעה. מזל טוב! כעת אתה מוכן להשתמש באוטובוס I2C בפרויקטים שלך!

שלב 7: משאבי אינטרנט

להלן הקישורים לדפי הנתונים של החלקים המשמשים לניסויים. אתה בהחלט צריך לקבל את אלה אם אתה לא מקבל שום דבר אחר. נמל הרחבה RamEEPROM בהיותו יוצר I2C, ל- NXP (פיליפס) יש המון דברים נהדרים. (הם אוהבים להשתמש בסוגריים מרובעים בכתובות האתרים שלהם, כך שאני לא יכול לכלול אותם כאן כראוי. מצטער.] כדי להגיע לאזור I2C, בחר ממשק מרשימת המוצרים. תוכל להגיע לאתר I2C שלהם ו גישה לכל גליונות הנתונים והערות האפליקציות שהם מציעים. תיאור האוטובוס I2C והפרטים הטכניים בפרט נמצאים כאן. קבל את גליונות הנתונים ATtiny2313 ו- ATmega168 (ספרי נתונים?) מאת Atmel. הערות היישום Atmel נמצאות כאן. תסתכל על AVR310 ו- AVR315. תפס גם את הקוד. חפש כאן עוד הרבה דברים I2C.

שלב 8: הערות לחנונים

עבור החנון האמיתי שרוצה לדעת את הפרטים, הנה כמה דברים שכדאי לזכור אם תסתכלו על פתקי Atmel Apps וקוד הנהג:- שיטת ההתייחסות והפקודה על מכשיר I2C אינה חלק מהמפרט! מלבד כתובת העבד וביט הקריאה/כתיבה, פקודות, מצבים וכו 'אינם מפורטים וספציפיים למכשיר נתון. כדי להבהיר זאת מאוד, שים לב כי התוכנית המשמשת בדוגמה Atmel חלה רק על הדוגמה הזו, והיא די לא סטנדרטית.- יישום USI שונה מהיישום TWI בכמה דרכים חשובות. + עם USI, השעון מסופק על ידי תוכנה; עם TWI הוא מסופק על ידי מחולל קצבי סיביות. + שיטת USI אינה משתמשת בהפרעות; ה- TWI כן. זה הגיוני במידה מסוימת מכיוון שמשפחת מגה (באמצעות TWI) עשויה לעשות הרבה דברים אחרים ואסור להדאיג אותם מהעברות I2C. בהחלט אפשרית גרסה מונעת הפרעה ל- USI, היא פשוט לא מיושמת במדריך זה. + החומרה של USI אינה מותאמת עבור I2C ויכולה להתמודד רק עם העברות של 8 סיביות. המשמעות היא ששתי העברות נדרשות לשליחת הסיביה התשיעית (NACK או ACK). חומרת ה- TWI מטפלת בכך באופן אוטומטי. זה הופך את יישום הנהג USI למעט יותר מסובך. + זיהוי שגיאות עבור ה- TWI מטופל בחומרה. USI דורש טיפול בתוכנות שמסבכות את העניינים במקצת. + חומרת ה- TWI שולטת ישירות בתצורת היציאה. חומרת USI דורשת הגדרת סיביות היציאה לפני שניתן להשתמש ביציאה. אתה תראה זאת בשגרת Master_Initialize עבור USI.-Atmel טוען שאפשר להשתמש במשיכות יציאת AVR עבור משיכות אוטובוס I2C. לא מצאתי דרך לגרום לגישה הזו לעבוד. שימוש בשני נגדים חיצוניים נראה כמו תוכנית די פשוטה, ולכן לא השקעתי בזה הרבה זמן.

מוּמלָץ: