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

בקר מיקרו AVR. נוריות LED מהבהבות באמצעות טיימר. טיימרים מפריעים. מצב CTC טיימר: 6 שלבים
בקר מיקרו AVR. נוריות LED מהבהבות באמצעות טיימר. טיימרים מפריעים. מצב CTC טיימר: 6 שלבים

וִידֵאוֹ: בקר מיקרו AVR. נוריות LED מהבהבות באמצעות טיימר. טיימרים מפריעים. מצב CTC טיימר: 6 שלבים

וִידֵאוֹ: בקר מיקרו AVR. נוריות LED מהבהבות באמצעות טיימר. טיימרים מפריעים. מצב CTC טיימר: 6 שלבים
וִידֵאוֹ: Using Digispark Attiny85 Mini Arduino boards: Lesson 108 2024, נוֹבֶמבֶּר
Anonim
Image
Image

שלום לכולם!

טיימרים הוא מושג חשוב בתחום האלקטרוניקה. כל רכיב אלקטרוני פועל על בסיס זמן. בסיס הזמן הזה עוזר לשמור על כל העבודה מסונכרנת. כל בקרי המיקרו עובדים בתדר שעון מוגדר מראש, לכולם יש הוראה להגדיר טיימרים. AVR מתגאה בכך שיש לו טיימר מדויק מאוד, מדויק ואמין. הוא מציע בו המון תכונות, ובכך הופך אותו לנושא עצום. החלק הטוב ביותר הוא שהטיימר אינו תלוי לחלוטין במעבד. לפיכך, הוא פועל במקביל למעבד ואין התערבות של המעבד, מה שהופך את הטיימר למדויק למדי. בחלק זה אני מסביר את מושגי היסוד של טיימרים AVR. אני כותב תכנית פשוטה בקוד C לשליטה על פלאש LED, באמצעות טיימרים.

שלב 1: תיאור

הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות
הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות

ב- ATMega328 ישנם שלושה סוגים של טיימרים:

טיימר/מונה 0 (TC0) - הוא מודול טיימר/מונה 8 סיביות למטרות כלליות, עם שתי יחידות OutputCompare עצמאיות ותמיכת PWM;

טיימר/מונה 1 (TC1) - יחידת הטיימר/מונה 16 סיביות מאפשרת תזמון מדויק של ביצוע התוכנית (ניהול אירועים), יצירת גל ומדידת תזמון אותות;

טיימר/מונה 2 (TC2) -הוא מטרה כללית, ערוץ, מודול טיימר/מונה 8 סיביות עם PWM ותפעול אסינכרוני;

שלב 2: הצהרת בעיות 1: בואו להבהב נורית נורה ראשונה (ירוק) כל 50 שניות

הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות
הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות
הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות
הצהרת בעיה 1: בואו להבהב נורית LED ראשונה (ירוק) כל 50 שניות

מֵתוֹדוֹלוֹגִיָה:

- שימוש במכשיר טיימר 0 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בפסיקה בכל פעם שה- Timer0 עולה על גדותיו;

טיימר 0 (8 סיביות) הוא נספר מ -0 עד 255 לאחר מכן, הם עולים על גדותיהם, ערך זה משתנה בכל דופק שעון.

F_CPU = 16MHz: פרק זמן שעון = 1000ms / 16000000Hz = 0.0000625ms

ספירת טיימר = (נדרשת עיכוב / זמן שעון) -1 = (50ms / 0.0000625ms) = 799999

השעון כבר תקתק 799999 פעמים כדי לתת עיכוב של 50 אלפיות השנייה בלבד!

אנו יכולים להשתמש בטכניקה של חלוקת תדרים הנקראת מידה מוקדמת כדי להקטין את ספירת הטיימר. ה- AVR מציע לנו את ערכי המקלחת הבאים לבחירה: 8, 64, 256 ו -1024. ראה הטבלה מסכמת את התוצאות של שימוש במכשירי מיון שונים.

ערך הנגד תמיד צריך להיות מספר שלם. בואו לבחור מכשיר טרום 256!

ברוב המיקרו -בקרים, יש משהו שנקרא Interrupt. ניתן לירות את ההפרעה הזו בכל פעם שמתקיימים תנאים מסוימים. כעת בכל פעם שהפרעה מופעלת, ה- AVR עוצר ושומר את ביצועו של השגרה הראשית, מטפל בשיחת ההפרעה (על ידי ביצוע שגרה מיוחדת, הנקראת שגרת השירות להפריע, ISR) וברגע שהיא מסתיימת איתה, חוזרת אל השגרה העיקרית וממשיכה לבצע אותה.

מכיוון שהעיכוב הנדרש (50ms) גדול מהעיכוב המרבי האפשרי: 4, 096ms = 1000ms / 62500Hz * 256, ברור שהטיימר יעלה על גדותיו. ובכל פעם שהטיימר עולה על גדותיו, מתבצעת הפרעה.

כמה פעמים צריך לפטר את ההפרעה?

50ms / 4.096ms = 3125 /256 = 12.207 אם הטיימר עלה על גדותיו 12 פעמים, 12 * 4.096ms = 49.152ms היו עוברים. באיטרציה ה -13, אנו זקוקים לעיכוב של 50ms - 49.152ms = 0.848ms.

בתדירות של 62500Hz (מכשיר קבוע מראש = 256), כל קרציה לוקחת 0.016ms. לכן כדי להשיג עיכוב של 0.848ms, הוא ידרוש 0.848ms / 0.016ms = 53 קרציות. לפיכך, באיטרציה ה -13, אנו מאפשרים רק לטיימר לספור עד 53 ולאחר מכן לאפס אותו.

אתחול טיימר 0/מונה (ראה תמונה):

TCCR0B | = (1 << CS02) // הגדרת טיימר עם prescaler = 256 TCNT0 = 0 // אתחול מונה TIMSK0 | = (1 << TOIE0) // אפשר הפסקת הצפה () // אפשר הפסקת עולמית tot_overflow = 0 // לאתחל משתנה של מונה הצפות

שלב 3: הצהרת בעיות 2: בואו להבהב LED שני (כחול) כל אחת

הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת
הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת
הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת
הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת
הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת
הצהרת בעיה 2: בואו להבהב LED שני (כחול) כל אחת

מֵתוֹדוֹלוֹגִיָה:

- שימוש במכשיר טיימר 1 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בטיימר נקה במצב השוואה (CTC);

- שימוש בפסיקות עם מצב CTC;

טיימר 1 (16 סיביות) הוא נספר מ 0 עד 65534 לאחר מכן, הם עולים על גדותיהם. ערך זה משתנה בכל דופק שעון.

F_CPU = 16MHz: פרק זמן שעון = 1000ms / 16000000Hz = 0.0000625ms Timer count ((נדרש עיכוב / זמן שעון) -1 = (1000ms / 0.0000625ms) = 15999999

השעון כבר תקתק 15999999 פעמים כדי לתת עיכוב של 1s!

אנו יכולים להשתמש בטכניקה של חלוקת תדרים הנקראת מידה מוקדמת כדי להקטין את ספירת הטיימר. ה- AVR מציע לנו את ערכי המקלחת הבאים לבחירה: 8, 64, 256 ו -1024. ראה הטבלה מסכמת את התוצאות של שימוש במכשירי מיון שונים. ערך הנגד תמיד צריך להיות מספר שלם. בואו לבחור מכשיר טרום 256!

במצב Clear timer on Compare (CTC) מצב, OCR1A או ICR1 משמשים כדי לתפעל את רזולוציית הנגד. במצב CTC המונה נמחק לאפס כאשר ערך המונה (TCNT1) תואם ל- OCR1A או ל- ICR1. ה- OCR1A או ICR1 מגדירים את הערך העליון של המונה, ומכאן גם הרזולוציה שלו. מצב זה מאפשר שליטה רבה יותר על תדירות פלט ההתאמה ההשוואת הוא גם מפשט את פעולת ספירת האירועים החיצוניים. עלינו לומר ל- AVR לאפס את טיימר 1/מונה ברגע שערכו יגיע לערך 62500, וכך להשיג עיכוב של 1 שניות.

אתחול טיימר 1/מונה (ראה תמונה):

TCCR1B | = (1 << WGM12) | (1 << CS12) // הגדרת טיימר עם prescaler = 256 ומצב CTC TCNT1 = 0 // אתחול המונה TIMSK1 | = (1 << OCIE1A) // הפעל השווה בין הפסקת OCR1A = 62500 // לאתחל ערך השוואה

שלב 4: הצהרת בעיות 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms

הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms
הצהרת בעיה 3: בואו נבהב נורית שלישית (אדומה) כל 16 ms

מֵתוֹדוֹלוֹגִיָה:

- שימוש במכשיר טיימר 2 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בטיימר נקה במצב השוואה (CTC);

- שימוש בחומרה CTC Mode ללא הפרעות;

טיימר 2 (8 סיביות) הוא נספר מ 0 עד 255 לאחר מכן, הם עולים על גדותיהם. ערך זה משתנה בכל דופק שעון.

F_CPU = 16MHz: פרק זמן שעון = 1000ms / 16000000Hz = 0.0000625ms

ספירת טיימר = (נדרשת עיכוב / זמן שעון) -1 = (16ms / 0.0000625ms) = 255999

השעון כבר תיקתק 255999 פעמים כדי לתת עיכוב של 16ms!

ראה הטבלה מסכמת את התוצאות של שימוש במכשירי prescalers שונים. ערך הנגד תמיד צריך להיות מספר שלם. בואו לבחור מכשיר טרום 1024!

במצב CTC המונה נמחק לאפס כאשר ערך המונה (TCNT2) תואם ל- OCR2A או ל- ICR2. Pin PB3 הוא גם סיכת השוואת הפלט של TIMER2 - OC2A (ראה תרשים).

טיימר/Counter2 Control Register A - TCCR2A Bit 7: 6 - COM2A1: 0 - השווה מצב פלט להשוואת יחידה A. מכיוון שאנו צריכים להחליף את הנורית, אנו בוחרים באפשרות: החלף OC2A על השוואת התאמה בכל פעם שמתרחשת התאמה השווה, סיכת OC2A מתחלפת אוטומטית. אין צורך לבדוק שום סימן דגל, אין צורך לטפל בהפרעות.

אתחול טיימר 2/מונה

TCCR2A | = (1 << COM2A0) | (1 << WGM21) // הגדרת סיכת טיימר OC2A במצב החלפה ובמצב CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20) // הגדרת טיימר עם מכשיר הגנה מראש = 1024 TCNT2 = 0 // אתחול מונה OCR2A = 250 // אתחול ערך השוואה

שלב 5: כתיבת קוד לתוכנית ב- C. העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר

כתיבת קוד לתוכנית ב- C. העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר
כתיבת קוד לתוכנית ב- C. העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר
כתיבת קוד לתוכנית ב- C. העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר
כתיבת קוד לתוכנית ב- C. העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר

כתיבה ובניית יישום מיקרו -בקר AVR בקוד C באמצעות פלטפורמת הפיתוח המשולב - Atmel Studio.

F_CPU מגדיר את תדר השעון בהרץ ונפוץ בתוכניות המשתמשות בספריית avr-libc. במקרה זה הוא משמש את שגרות העיכוב כדי לקבוע כיצד לחשב עיכובים בזמן.

#ifndef F_CPU

#define F_CPU 16000000UL // אומר תדר קריסטל בקר (16 MHz AVR ATMega328P) #endif

#include // כותרת כדי לאפשר בקרת זרימת נתונים על סיכות. מגדיר סיכות, יציאות וכו '.

הקובץ הראשון הכולל הוא חלק מ- avr-libc והוא ישמש כמעט בכל פרויקט AVR שאתה עובד עליו. io.h יקבע את המעבד שבו אתה משתמש (וזו הסיבה שאתה מציין את החלק בעת הידור) ובתורו יכלול את כותרת הגדרת IO המתאימה לשבב בו אנו משתמשים. הוא פשוט מגדיר את הקבועים של כל הפינים, היציאות, הרישומים המיוחדים וכו '.

#include // header כדי לאפשר הפרעה

uint8_t tot_overflow נדיף; // משתנה גלובלי לספירת מספר הצפות

מתודולוגיה של הצהרת בעיות: נורית הבזק (ירוקה) ראשונית כל 50 שניות

- שימוש במכשיר טיימר 0 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בפסיקה בכל פעם שה- Timer0 עולה על גדותיו;

void timer0_init () // לאתחל טיימר 0, הפרעה ומשתנה

{TCCR0B | = (1 << CS02); // הגדרת טיימר עם מכשיר הגנה מראש = 256 TCNT0 = 0; // לאתחל מונה TIMSK0 | = (1 << TOIE0); // אפשר הצפה nterrupt sei (); // לאפשר הפרעות גלובליות tot_overflow = 0; // לאתחל משתנה של מונה הצפות}

מתודולוגיה של הצהרת בעיות: נורית פלאש שנייה (כחולה) כל 1

- שימוש במכשיר טיימר 1 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בטיימר נקה במצב השוואה (CTC);

- שימוש בפסיקות עם מצב CTC;

void timer1_init () // לאתחל טיימר 1, הפרעה ומשתנה {TCCR1B | = (1 << WGM12) | (1 << CS12); // הגדרת טיימר עם prescaler = 256 ומצב CTC TCNT1 = 0; // לאתחל מונה OCR1A = 62500; // לאתחל ערך השוואה TIMSK1 | = (1 << OCIE1A); // אפשר השוואה להפריע}

מתודולוגיה של הצהרת בעיות: LED שלישי (Flash אדום) כל 16 ms

- שימוש במכשיר טיימר 2 להפחתת אות חשמלי בתדר גבוה לתדר נמוך יותר על ידי חלוקה שלמה;

- שימוש בטיימר נקה במצב השוואה (CTC);

- שימוש בחומרה CTC Mode ללא הפרעות;

void timer2_init () // לאתחל טיימר 2 {TCCR2A | = (1 << COM2A0) | (1 << WGM21); // הגדר סיכת טיימר OC2A במצב החלפה ובמצב CTC TCCR2B | = (1 << CS22) | (1 << CS21) | (1 << CS20); // הגדרת טיימר עם מכשיר הגנה מראש = 1024 TCNT2 = 0; // לאתחל מונה OCR2A = 250; // לאתחל ערך השוואה}

שגרת שירות הפסקת הצפת TIMER0 נקראת בכל פעם ש- TCNT0 עולה על גדותיו:

ISR (TIMER0_OVF_vect)

{tot_overflow ++; // עקוב אחר מספר הצפות}

ISR זה פוטר בכל פעם שמתרחשת התאמה מכאן, החלפה מובילה לכאן עצמה:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1); // החלפת הובלה כאן}

int main (void)

{DDRB | = (1 << 0); // חבר 1 (ירוק) הוביל לפין PB0 DDRC | = (1 << 1); // חבר 2 (כחול) הוביל לסיכת PC1 DDRB | = (1 << 3); // חבר 3 (אדום) הוביל לפין PB3 (OC2A) טיימר0_init (); // לאתחל טיימר 0 טיימר1_יניט (); // לאתחל טיימר 1 טיימר 2_init (); // אתחול טיימר 2 בעוד (1) // לולאה לנצח {

אם טיימר 0 עלה על גדותיו 12 פעמים, 12 * 4.096ms = 49.152ms היו עוברים. באיטרציה ה -13, אנו זקוקים לעיכוב של 50ms - 49.152ms = 0.848ms. לפיכך, באיטרציה ה -13, אנו מאפשרים רק לטיימר לספור עד 53 ולאחר מכן לאפס אותו.

if (tot_overflow> = 12) // לבדוק אם לא. של הצפות = 12 הערה: '> =' משמש

{if (TCNT0> = 53) // לבדוק אם מספר הטיימר מגיע ל -53 {PORTB ^= (1 << 0); // מחליף את ה- TCNT0 = 0; // אפס מונה tot_overflow = 0; // אפס מונה הצפה}}}}

העלאת קובץ HEX לזיכרון הבזק של המיקרו -בקר:

הקלד בחלון שורת DOS את הפקודה:

avrdude –c [שם המתכנת] –p m328p –u –U פלאש: w: [שם קובץ ה- hex שלך] במקרה שלי הוא: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

פקודה זו כותבת קובץ hex לזיכרון המיקרו -בקר. צפה בסרטון עם תיאור מפורט של צריבת זיכרון ההבזק של המיקרו -בקר:

צריבת זיכרון פלאש של מיקרו -בקר …

בסדר! כעת, המיקרו -בקר פועל בהתאם להוראות התוכנית שלנו. בוא נבדוק את זה!

שלב 6: יצירת מעגל חשמלי

יצירת מעגל חשמלי
יצירת מעגל חשמלי
יצירת מעגל חשמלי
יצירת מעגל חשמלי
יצירת מעגל חשמלי
יצירת מעגל חשמלי

חבר רכיבים בהתאם לתרשים סכמטי.

מוּמלָץ: