فهرست مطالب:

میکروکنترلر AVR چراغ های LED با استفاده از تایمر چشمک می زنند. وقفه تایمرها تایمر حالت CTC: 6 مرحله
میکروکنترلر AVR چراغ های LED با استفاده از تایمر چشمک می زنند. وقفه تایمرها تایمر حالت CTC: 6 مرحله

تصویری: میکروکنترلر AVR چراغ های LED با استفاده از تایمر چشمک می زنند. وقفه تایمرها تایمر حالت CTC: 6 مرحله

تصویری: میکروکنترلر AVR چراغ های LED با استفاده از تایمر چشمک می زنند. وقفه تایمرها تایمر حالت CTC: 6 مرحله
تصویری: code vision AVR آموزش 2024, نوامبر
Anonim
Image
Image

سلام به همگی!

تایمر یک مفهوم مهم در زمینه الکترونیک است. هر جزء الکترونیکی بر اساس زمان کار می کند. این زمانبندی کمک می کند تا همه کارها همزمان شوند. همه میکروکنترلرها با فرکانس ساعت از پیش تعیین شده ای کار می کنند ، همه آنها تنظیماتی برای تنظیم زمان سنج دارند. AVR دارای تایمر بسیار دقیق ، دقیق و قابل اعتماد است. این ویژگی های زیادی را در خود ارائه می دهد ، بنابراین آن را به یک موضوع گسترده تبدیل می کند. بهترین بخش این است که تایمر کاملاً مستقل از CPU است. بنابراین ، موازی با CPU اجرا می شود و هیچ مداخله ای از CPU وجود ندارد ، که تایمر را کاملاً دقیق می کند. در این بخش مفاهیم اولیه تایمرهای AVR را توضیح می دهم. من برنامه ساده ای را با کد C برای کنترل فلاشر LED با استفاده از تایمر می نویسم.

مرحله 1: توضیحات

بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم
بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم

در ATMega328 سه نوع تایمر وجود دارد:

Timer/Counter0 (TC0) - ماژول تایمر/شمارنده 8 بیتی با دو واحد مستقل OutputCompare و پشتیبانی PWM است

تایمر/شمارنده 1 (TC1) - واحد تایمر/شمارنده 16 بیتی زمان اجرای دقیق برنامه (مدیریت رویداد) ، تولید موج و اندازه گیری زمان سیگنال را امکان پذیر می کند

تایمر/شمارنده 2 (TC2) -یک هدف کلی ، کانال ، ماژول تایمر/شمارنده 8 بیتی با PWM و عملیات ناهمزمان است

مرحله 2: بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم

بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم
بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم
بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم
بیان مشکل 1: اجازه دهید هر 50 دقیقه یکبار LED اول (سبز) را فلش کنیم

روش شناسی:

- استفاده از پیش شمارش Timer0 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- با استفاده از وقفه هر بار که تایمر 0 سرریز می شود ؛

Timer0 (8 بیت) پس از آن از 0 تا 255 شمارش می کند ، آنها سرریز می شوند ، این مقدار در هر پالس ساعت تغییر می کند.

F_CPU = 16 مگاهرتز: مدت زمان ساعت = 1000ms / 16000000Hz = 0.0000625ms

تعداد تایمر = (تاخیر مورد نیاز / مدت زمان ساعت) -1 = (50ms / 0.0000625ms) = 799999

این ساعت تا به حال 799999 بار تیک زده تا 50 میلی ثانیه تأخیر داشته باشد!

ما می توانیم از تکنیک تقسیم فرکانس به نام prescaling برای کاهش تعداد تایمر استفاده کنیم. AVR مقادیر پیش فروشنده زیر را برای انتخاب به ما ارائه می دهد: 8 ، 64 ، 256 و 1024. جدول را به طور خلاصه نتایج استفاده از پیش فروشنده های مختلف پیش نمایش می دهد.

مقدار شمارنده همیشه باید یک عدد صحیح باشد. بیایید پیش فروش شماره 256 را انتخاب کنیم!

در اکثر میکروکنترلرها چیزی به نام Interrupt وجود دارد. این وقفه می تواند هر زمان که شرایط خاصی برآورده شود ، شلیک شود. اکنون هر زمان که وقفه ای شلیک می شود ، AVR متوقف می شود و اجرای اصلی خود را ذخیره می کند ، به تماس وقفه (با اجرای یک روال خاص ، به نام روال سرویس وقفه ، ISR) توجه می کند و پس از انجام آن ، به روال اصلی و اجرای آن را ادامه می دهد.

از آنجا که تأخیر مورد نیاز (50 میلی ثانیه) بیشتر از حداکثر تاخیر ممکن است: 4 ، 096ms = 1000ms / 62500Hz * 256 ، بدیهی است که تایمر سرریز می شود. و هر زمان که تایمر سرریز می شود ، وقفه ای شلیک می شود.

وقفه چند بار باید اخراج شود؟

50ms / 4.096ms = 3125 /256 = 12.207 اگر تایمر 12 بار بیش از حد پرواز کرده باشد ، 12 * 4.096ms = 49.152ms عبور می کند. در تکرار سیزدهم ، ما به تأخیر 50 میلی ثانیه نیاز داریم - 49.152 میلی متر = 0.848 میلی متر.

در فرکانس 62500 هرتز (پیش شماره = 256) ، هر تیک 0.016 میلی ثانیه طول می کشد. بنابراین برای رسیدن به تأخیر 0.848 میلی ثانیه ، به 0.848 میلی ثانیه / 0.016 میلی متر = 53 تیک نیاز است. بنابراین ، در تکرار سیزدهم ، ما فقط به تایمر اجازه می دهیم تا 53 را بشمارد و سپس آن را تنظیم مجدد کنید.

زمانبندی اولیه 0/شمارنده (عکس را ببینید):

TCCR0B | = (1 << CS02] // تنظیم تایمر با پیش شماره گیر = 256 TCNT0 = 0 // مقداردهی اولیه TIMSK0 | = (1 << TOIE0] // فعال کردن سرریز وقفه sei () // فعال کردن وقفه های جهانی tot_overflow = 0 // مقداردهی اولیه متغیر شمارنده سرریز

مرحله 3: بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم

بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم
بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم
بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم
بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم
بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم
بیان مشکل 2: اجازه دهید LED دوم (آبی) را هر 1 ثانیه فلش کنیم

روش شناسی:

- استفاده از پیش شمارش Timer1 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- استفاده از Clear Timer on Compare (CTC) Mode ؛

- استفاده از وقفه با حالت CTC ؛

تایمر 1 (16 بیت) پس از آن از 0 تا 65534 شمارش می کند ، آنها سرریز می شوند. این مقدار در هر پالس ساعت تغییر می کند.

F_CPU = 16 مگاهرتز: مدت زمان ساعت = 1000ms / 16000000Hz = 0.0000625ms شمارش زمان = (تاخیر / زمان مورد نیاز ساعت) -1 = (1000ms / 0.0000625ms) = 15999999

ساعت قبلاً 15999999 بار تیک زده است تا 1 ثانیه تأخیر داشته باشد!

ما می توانیم از تکنیک تقسیم فرکانس به نام prescaling برای کاهش تعداد تایمر استفاده کنیم. AVR مقادیر پیش فروشنده زیر را برای انتخاب به ما پیشنهاد می کند: 8 ، 64 ، 256 و 1024. جدول را به طور خلاصه نتایج استفاده از پیش فروشنده های مختلف پیش نمایش می دهد. مقدار شمارنده همیشه باید یک عدد صحیح باشد. بیایید پیش فروش شماره 256 را انتخاب کنیم!

در حالت Clear timer on Compare (CTC) ، از ثبت OCR1A یا ICR1 برای دستکاری وضوح شمارنده استفاده می شود. در حالت CTC زمانی که شمارنده (TCNT1) با OCR1A یا ICR1 مطابقت داشته باشد ، شمارنده به صفر می رسد. OCR1A یا ICR1 مقدار بالایی را برای شمارنده و از این رو وضوح آن را نیز مشخص می کند. این حالت امکان کنترل بیشتر فرکانس خروجی مقایسه را فراهم می کند. همچنین عملکرد شمارش رویدادهای خارجی را ساده می کند. ما باید به AVR بگوییم که Timer1/Counter را به محض اینکه مقدار آن به مقدار 62500 برسد ، تنظیم مجدد کند ، بنابراین تاخیر 1 ثانیه ای حاصل شود.

زمانبندی اولیه 1/شمارنده (عکس را ببینید):

TCCR1B | = (1 << WGM12] | (1 << CS12) // تنظیم زمان سنج با پیش شماره گیر = 256 و حالت CTC TCNT1 = 0 // مقداردهی اولیه TIMSK1 | = (1 << OCIE1A] // فعال کردن مقایسه وقفه OCR1A = 62500 // مقدار مقدماتی را مقداردهی کنید

مرحله 4: بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم

بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم
بیان مشکل 3: اجازه دهید هر 16 میلی ثانیه LED سوم (قرمز) را فلش کنیم

روش شناسی:

- استفاده از پیش شمارش Timer2 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- استفاده از Clear Timer on Compare (CTC) Mode ؛

- استفاده از حالت سخت افزاری CTC بدون وقفه ؛

Timer2 (8 بیت) پس از آن از 0 تا 255 شمارش می کند ، آنها سرریز می شوند. این مقدار در هر پالس ساعت تغییر می کند.

F_CPU = 16 مگاهرتز: دوره زمانی ساعت = 1000ms / 16000000Hz = 0.0000625ms

تعداد تایمر = (تاخیر مورد نیاز / مدت زمان ساعت) -1 = (16ms / 0.0000625ms) = 255999

ساعت تا به حال 255999 بار تیک زده تا 16 میلی ثانیه تأخیر داشته باشد!

جدول را به طور خلاصه نتایج استفاده از پیش فروشنده های مختلف پیش نمایش نشان دهید. مقدار شمارنده همیشه باید یک عدد صحیح باشد. بیایید پیش فروش 1024 را انتخاب کنیم!

در حالت CTC زمانی که شمارنده (TCNT2) با OCR2A یا ICR2 مطابقت داشته باشد ، شمارنده به صفر می رسد. پین PB3 همچنین پین مقایسه خروجی TIMER2 - OC2A است (نمودار را ببینید).

Timer/Counter2 Control Register A - TCCR2A Bit 7: 6 - COM2A1: 0 - مقایسه حالت خروجی برای مقایسه واحد A. از آنجا که ما نیاز به تغییر حالت LED داریم ، این گزینه را انتخاب می کنیم: Toggle OC2A on Compare Match هر زمان که یک مسابقه مقایسه ای رخ می دهد ، پین OC2A به طور خودکار تغییر حالت می دهد. نیازی به بررسی هیچ بیت پرچم نیست ، نیازی به توجه به وقفه ها نیست.

Timer2/Counter را اولیه کنید

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 Code با استفاده از بستر توسعه یکپارچه - Atmel Studio.

F_CPU فرکانس ساعت را در هرتز تعریف می کند و در برنامه هایی که از کتابخانه avr-libc استفاده می کنند متداول است. در این حالت از روال تاخیر برای تعیین نحوه محاسبه تاخیرهای زمانی استفاده می شود.

#ifndef F_CPU

#تعریف F_CPU 16000000UL // کنترل فرکانس کریستال کنترل (16 مگاهرتز AVR ATMega328P) #endif

#include // header برای فعال کردن کنترل جریان داده روی پین ها. پین ها ، پورت ها و غیره را تعریف می کند.

اولین فایل شامل بخشی از avr-libc است و تقریباً در هر پروژه AVR که روی آن کار می کنید استفاده می شود. io.h CPU مورد استفاده شما را تعیین می کند (به همین دلیل قسمت را هنگام کامپایل مشخص می کنید) و به نوبه خود هدر تعریف IO مناسب برای تراشه ای که ما استفاده می کنیم را شامل می شود. این به سادگی ثابت ها را برای همه پین ها ، پورت ها ، ثبت های ویژه و غیره تعریف می کند.

#include // header برای فعال کردن وقفه

فرار uint8_t tot_overflow؛ // متغیر سراسری برای شمارش تعداد سرریزها

روش بیان مشکل: LED اول (سبز) هر 50 میلی ثانیه روشن می شود

- استفاده از پیش شمارشگر Timer0 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- با استفاده از وقفه هر بار که تایمر 0 سرریز می شود ؛

void timer0_init () // مقداردهی اولیه timer0 ، وقفه و متغیر

{TCCR0B | = (1 << CS02) ؛ // تنظیم زمان سنج با پیش شماره گیر = 256 TCNT0 = 0؛ // مقداردهی اولیه TIMSK0 | = (1 << TOIE0] ؛ // فعال کردن overflow nterrupt sei ()؛ // وقفه های سراسری را فعال کنید tot_overflow = 0؛ // مقداردهی اولیه متغیر شمارنده سرریز}

روش بیان مشکل: LED دوم فلش (آبی) هر 1 ثانیه

- استفاده از پیش شمارش Timer1 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- استفاده از Clear Timer on Compare (CTC) Mode ؛

- استفاده از وقفه با حالت CTC ؛

void timer1_init () // مقداردهی اولیه timer1 ، وقفه و متغیر {TCCR1B | = (1 << WGM12] | (1 << CS12) ؛ // تنظیم زمان سنج با پیش شماره گیر = 256 و حالت CTC TCNT1 = 0 ؛ // مقداردهی اولیه OCR1A = 62500 ؛ // مقداردهی اولیه را مقایسه TIMSK1 | = (1 << OCIE1A) ؛ // فعال کردن مقایسه وقفه}

روش بیان مشکل: چراغ LED سوم (قرمز) را هر 16 میلی ثانیه فلش کنید

- استفاده از پیش شمارش Timer2 برای کاهش سیگنال الکتریکی با فرکانس بالا به فرکانس پایین تر با تقسیم صحیح ؛

- استفاده از Clear Timer on Compare (CTC) Mode ؛

- استفاده از حالت سخت افزاری CTC بدون وقفه ؛

void timer2_init () // مقداردهی اولیه timer2 {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 هر زمان که یک مسابقه اتفاق می افتد ، شلیک می شود ، ضامن led خود را اینجا تغییر می دهد:

ISR (TIMER1_COMPA_vect) {PORTC ^= (1 << 1) ؛ // ضامن led اینجا}

int main (باطل)

{DDRB | = (1 << 0] ؛ // اتصال 1 (سبز) منجر به پین PB0 DDRC | = (1 << 1) ؛ // اتصال 2 (آبی) منجر به پین PC1 DDRB | = (1 << 3) ؛ // اتصال 3 (قرمز) منجر به پین PB3 (OC2A) timer0_init ()؛ // مقداردهی اولیه timer0 timer1_init ()؛ // مقداردهی اولیه timer1 timer2_init ()؛ // مقداردهی اولیه تایمر 2 در حالی که (1) // حلقه برای همیشه {

اگر تایمر 0 12 بار پرتاب کرده باشد ، 12 * 4.096ms = 49.152ms عبور می کند. در تکرار سیزدهم ، ما به تأخیر 50 میلی ثانیه نیاز داریم - 49.152 میلی متر = 0.848 میلی متر. بنابراین ، در تکرار سیزدهم ، ما فقط به تایمر اجازه می دهیم تا 53 را بشمارد و سپس آن را تنظیم مجدد کنید.

if (tot_overflow> = 12) // بررسی کنید که آیا وجود ندارد. of overflows = 12 توجه: '> =' استفاده می شود

{if (TCNT0> = 53) // بررسی کنید که آیا شمار تایمر به 53 برسد {PORTB ^= (1 1 0 0) ؛ // تغییر led TCNT0 = 0 ؛ // تنظیم مجدد شمارنده tot_overflow = 0؛ // تنظیم مجدد شمارنده سرریز}}}}

بارگذاری فایل HEX در حافظه فلش میکروکنترلر:

دستور زیر را در پنجره اعلان DOS تایپ کنید:

avrdude –c [نام برنامه نویس] –p m328p –u –U flash: w: [نام فایل هگز شما] در مورد من این است: avrdude –c ISPProgv1 –p m328p –u –U flash: w: Timers.hex

این دستور فایل hex را در حافظه میکروکنترلر می نویسد. ویدیو را با شرح مفصل در مورد سوختن فلش حافظه میکروکنترلر تماشا کنید:

در حال سوختن فلش مموری میکروکنترلر…

خوب! در حال حاضر ، میکروکنترلر مطابق دستورالعمل برنامه ما کار می کند. بگذار چک کنیم!

مرحله ششم: ایجاد مدار الکتریکی

ساخت مدار الکتریکی
ساخت مدار الکتریکی
ساخت مدار الکتریکی
ساخت مدار الکتریکی
ساخت مدار الکتریکی
ساخت مدار الکتریکی

قطعات را مطابق نمودار شماتیک متصل کنید.

توصیه شده: