آموزش مقدماتی AVR – بخش نهم | تایمر کانتر 0

اگر مدت آشنایی شما با AVR زیاد باشد، قطعا بارها اسم تایمر را شنیده‌اید. تایمر کانترها جزء جدانشدنی میکروکنترلرها هستند و فقط مختص به AVR نیستند. در تمام میکروکنترلرها چه قدیمی مثل 8051 و چه جدید مثل ARM واحدهای تایمر کانتر به صورت مجزا تعبیه شده‌اند که امکانات بسیاری در اختیار برنامه‌نویس قرار می‌دهند. این امکانات در انواع میکروکنترلرها متفاوت است. حتی در AVR در میکروکنترلر mega16 و mega128 تعداد تایمر کانترها متفاوت بوده و برای اطلاعات دقیق از سخت افزار هر میکرو باید به دیتاشیت آن مراجعه کرد. در این بخش، بعد از بررسی کلی این مفهوم، به صحبت درباره‌ی تایمر کانتر 0 خواهیم پرداخت.

دلیل وجود تایمر کانتر

تایمر کانتر یک بخش سخت افزاری در میکرو کنترلر است که وظایفی چون شمارش، محاسبه زمان سپری شده، تولید شکل موج PWM و تولید فرکانس‌های متغیر را می‌توان برعهده آن گذاشت. احتمالا این سؤال برایتان پیش می‌آید که مگر این کارها را نمی‌شود داخل برنامه انجام داد؟ بله این کار شدنی است. اما اگر تمام زمان پردازشی CPU در نرم افزار صرف این وظایف شود، دیگر نمی‌توان همزمان به کار دیگری مشغول شد. به عنوان مثال فرض کنید می‌خواهیم برنامه‌ای بنویسیم که یک موج PWM روی یکی از پایه‌ها تولید کند و از طرف دیگر همزمان یک LCD مدیریت شود. اینکار ساده است؛ تولید PWM برعهده تایمر و مدیریت LCD برعهده CPU.

شکل موج سیگنال PWM

تایمر کانتر 0

در این قسمت در مورد تایمر کانتر 0 و امکانات و مدهای عملکردی اون صحبت می‌کنیم. در میکروکنترلر ATmega16 سه تایمر با شماره‌های 0 ، 1 و 2 تعبیه شده است که هرکدام نسبت به دیگری مزیتی دارند. تایمر کانتر 0 و 2 هشت بیتی بوده و تایمر کانتر شماره 1 شانزده بیتی است. در ادامه متوجه می‌شوید که منظور از 8 و 16 بیتی بودن چیست.

اگر قسمت‌های قبل را مطالعه کرده باشید، گفتیم که فضای SFR دارای رجیسترهایی برای کنترل بخش‌های سخت افزاری است. تایمرها هم دارای رجیسترهایی می‌باشند که مخصوص به خودشان است و همچنین یک سری رجیسترهایی وجود دارند که مابین تایمرها مشترک هستند. هر تایمر کانتر دارای 3 رجیستر منحصر به فرد به نام‌های TCCR ، TCNT و OCR است. همچنین هر سه تایمر دارای 2 رجیستر مشترک به نام‌های TIMSK و TIFR نیز می‌باشند که در مورد آن صحبت می‌کنیم.

اما در مورد سه رجیستر منحصر به فرد هر تایمر باید گفت که در تایمر کانتر 0 ، نام این سه رجیستر به صورت TCCR0 ، TCNT0 و OCR0 است؛ در تایمرهای 1 و 2 نیز به همین صورت و البته با کمی تفاوت که جلسات بعدی در مورد آن صحبت می‌کنیم.
تذکر: چون قسمتی از مفاهیم این قسمت، مربوط به بخش قبل است حتما قسمت هشتم آموزش را مطالعه بفرمایید.

ابتدا بحث رجیسترها را با رجیسترهای مشترک آغاز می‌کنیم یعنی TIMSK و TIFR. پس از معرفی این دو، رجیسترهای اختصاصی تایمر کانتر 0 (TCCR0 ، TCNT0 و OCR0) را به صورت کامل شرح خواهیم داد.

رجیستر Timer Interrupt Mask) TIMSK)

این رجیستر تنها فعال یا غیرفعال‌سازی وقفه‌های مربوط به هر سه تایمر را انجام می‌دهد. با نوشتن 1 بر روی هر کدام از بیت‌ها (در صورت فعال بودن بیت وقفه عمومی) آن وقفه فعال شده و می‌توان با نوشتن سرویس روتین مربوطه، برنامه مد نظر را نوشت.

رجیستر TIMSK در ATmega16

بیت‌های 0 و 1 مربوط به تایمر 0، بیت‌های 2 تا 5 مربوط به تایمر 1 و در نهایت بیت‌های 6 و 7 مربوط به تایمر 2 هستند. در این بخش ما تنها با بیت‌های 0 و 1 کار داریم که به واسطۀ این دو بیت (TOIE0 و OCIE0) می‌توانیم دو نوع وقفه برای تایمر کانتر 0 فعال کنیم.

وظیفه رجیستر به صورت مختصر: فعال سازی وقفه‌های تایمر کانتر.

رجیستر Timer Interrupt Flag Register) TIFR)

بیت‌های پرچم یا Flag در این رجیستر هستند و با یک شدن هرکدام از این بیت‌ها، CPU متوجه وقوع وقفه شده و به سرویس روتین مربوط رجوع می‌کند (در مورد بیت پرچم در بخش هشتم صحبت کردیم).

رجیستر TIFR در ATmega16

در این رجیستر هم تنها با دو بیت 0 و 1 (TOV0 و OCF0) که مربوط به تایمر کانتر 0 هستند کار داریم. مابقی بیت‌ها در جلسات آینده تشریح می‌شوند.

وظیفه رجیستر بصورت مختصر: در صورت وقوع وقفه، بیت‌های متناظر 1 می‌شوند.

رجیستر Timer Counter Register 0) TCNT0)

در تمام تایمرها یک کلاک به صورت مداوم به رجیستر TCNT اعمال می‌شود. در تایمر کانتر 0 این کلاک به TCNT0 اعمال شده و با هر کلاک مقدار آن یک واحد افزایش می‌یابد.

رجیستر TCNT0 در ATmega16

در شکل بالا به وضوح می‌توانید مشاهده کنید که TCNT0 از 8 بیت تشکیل شده که این نشان‌دهنده 8 بیتی بودن تایمر است. در حالت پیشفرض مقدار آن 0 است و درصورت فعال‌سازی کلاک (الان میگیم چجوری باید فعال بشه) با هرکلاک مقدار آن یک واحد زیاد شده تا به 255 برسد. در این صورت با یک کلاک دیگر دوباره مقدار TCNT0 برابر 0 شده و شمارش از اول آغاز می‌شود.

وظیفه رجیستر بصورت مختصر: TCNT0 تنها با اعمال هر کلاک به آن، 1 واحد افزایش می‌یابد.

رجیستر Output Compare Register 0) OCR0)

مقدار رجیستر OCR0 به طور دائم، به صورت سخت افزاری، با TCNT0 مقایسه می‌شود و در صورتی که برابر شوند دو اتفاق مهم می‌تواند رخ دهد:

  1. اگر وقفه OCIE0 در TIMSK فعال باشد، هنگام برابری OCR0 و TCNT0 وقفه رخ می‌دهد.
  2. متناسب با تنظیم بیت‌های COM (موجود در رجیستر بعدی) منظق پایه OC0 میکروکنترلر تغییر می‌کند.

رجیستر OCR0 در ATmega16

این رجیستر هم 8 بیتی بوده و مقدار داخل آن توسط نرم‌افزار تنظیم می‌شود. چگونگی مقداردادن به آن و این که مقدار چه عددی باشد، بستگی به مد کاری میکرو خواهد داشت.

وظیفه رجیستر بصورت مختصر: مقایسه لحظه به لحظه به صورت سخت‌افزاری با رجیستر TCNT0 و … (کمی صبر کنید🙏)

رجیستر Timer Counter Control Register 0) TCCR0)

رجیستر TCCR0 در واقع شامل بیت‌هایی است که هر کدام بخشی از تنظیمات تایمر را انجام می‌دهند. این رجیستر در اصل واحد کنترل تایمر کانتر 0 است.

رجیستر TCCR0 در ATmega16

در رجیستر بالا 4 نوع بیت مختلف وجود دارد: COM ، WGM ، CS و FOC. (نگران نباشید؛ همش رو توضیح میدیم💪)

بیت‌های CS

Clock Source یا به اختصار CS، سه بیت هستند که در تایمر 0 به نام‌های CS01 ، CS00 و CS02 شناخته می‌شوند. این سه بیت وظیفه تنظیم کلاک اعمالی به رجیستر TCNT0 را بر عهده دارند. به عبارت دیگر، تنظیم فرکانس کلاک اعمال شده به TCNT0 توسط این 3 بیت و مطابق شکل زیر انجام می‌شود.

عملکرد بیت‌های انتخاب کلاک تایمر 0

نقشه سخت افزاری توزیع کلاک تایمر کانترهادر حالت پیش‌فرض مقدار این 3 بیت صفر است؛ به همین خاطر طبق توضیح (No clock source) هیچ‌گونه کلاکی به TCNT0 اعمال نمی‌شود و تایمر خاموش است. قبل از گفتن حالت‌های بعدی باید ذکر کنیم که در جدول فوق ClkI/O همان فرکانس کاری میکروکنترلر است که به صورت مفصل در بخش چهارم در مورد آن بحث شد.

فرض کنیم کلاک میکروکنترلر 8 مگاهرتز باشد؛ اگر این 3 بیت در وضعیت 001 قرار گیرند، مطابق جدول، دقیقا همان ClkI/O به TCNT0 اعمال شده و اگر 010 تنظیم شود، ClkI/O بر 8 تقسیم شده و فرکانس 1 مگاهرتز (8MHz / 8) به TCNT0 اعمال خواهد شد. در بقیه حالات هم به همین صورت کلاک اعمالی به ترتیب بر 64 یا 256 و یا 1024 تقسیم می‌شود.

در حالت 000 که تایمر غیرفعال است. حالت‌های 001 تا 101 که ClkI/O که به ترتیب بر 1، 8، 64، 256 و 1024 تقسیم می‌شوند را حالت تایمر گویند. اما در حالت 110 و 111 کلاک باید از بیرون میکروکنترلر اعمال شود. این حالت، کانتر گفته می‌شود. در حالت کانتر مطابق شکل زیر کلاک موجود روی پایه T0 به TCNT0 اعمال می‌گردد.

پایه‌های T0 و OC0 در ATmega16

اگر وضعیت CS برابر 110 شود شمارش TCNT0 با لبه پایین رونده و اگر برابر 111 شود شمارش با لبه بالارونده انجام خواهد شد. به این دو حالت چون کلاک از بیرون اعمال ‌می‌شود، کانتر گویند. کاربرد این حالت مواقعی است که بخواهیم فرکانس یک سیگنال را اندازه‌گیری کنیم و یا تعداد پالس‌های خروجی یک سنسور را شمارش نماییم.

بیت‌های WGM و COM

پس از CS که وظیفه تنظیم کلاک را بر عهده داشت، Waveform Generation Mode یا به اختصار WGM که تنها در تایمر کانتر 0 از دو بیت تشکیل شده، قرار دارد که وظیفه‌ی آن تنظیم مد کاری تایمر است. تایمر کانتر 0 دارای چهار مد متفاوت است که هر کدام کاربرد متفاوتی دارند. این چهار مد عبارت‌اند از:

  1. مد Normal
  2. مد CTC
  3. مد Fast PWM
  4. مد Phase Correct PWM

در شکل زیر حالت‌های دوبیت WGM00 و WGM01 آمده است.

انتخاب مدهای عملکرد با WGM

با توجه به مقدار دو بیت WGM چهار مد به صورت زیر انتخاب می‌شوند:

  1. اگر 00 شوند، تایمر در مد Normal قرار می‌گیرد.
  2. اگر 01 شوند، تایمر در مد Phase Correct PWM عمل می‌کند.
  3. اگر 10 شوند، تایمر وارد مد CTC خواهد شد.
  4. اگر 11 شوند، تایمر در مد Fast PWM عمل خواهد کرد.

اما در مورد بیت‌های COM که مخفف کلمات Compare Output Match هستند، باید گفت که وظیفه اصلی این دو بیت ایجاد شکل موج بر روی پایه OC0 است (شکل بالا 👆) و عملکرد این بیت‌ها وابسته به مد کاری انتخابی توسط WGM بوده و در هر مد متفاوت است. حال تک تک مدها را معرفی کرده و وضعیت دو بیت COM را هم در هر مد مشخص می‌کنیم.

مد Normal

اگر WGM را 00 کنیم، تایمر وارد مد نرمال می‌شود.در این مد مقدار TCNT0 از 0 تا 255 با هر کلاک افزایش یافته و با یک کلاک دیگر دوباره صفر می‌شود. بنابراین یک دور کامل تایمر 256 کلاک احتیاج دارد. به شکل زیر دقت کنید:

نمودار عملکرد مد Normal

در صورت فعال شدن تایمر این چرخه بی نهایت بار ادامه پیدا می‌کند مگر اینکه تایمر را خاموش کنیم (CS برابر 000 شود).

نکته: هر موقع با اعمال یک پالس دیگر مقدار TCNT0 برابر 0 شد، به این حالت overflow گفته می‌شود و اصطلاحا می‌گویند تایمر سرریز کرده است. در این حالت اگر بیت TOIE0 واقع در رجیستر TIMSK یک شده باشد و بیت وقفه عمومی هم 1 باشد، با وقوع یک overflow وقفه‌ای صادر می‌شود که به آن وقفه سرریز تایمر 0 گویند. شماره Vector این وقفه مطابق جدول وقفه‌ها عدد 10 است.

مثال مد Normal

میخواهیم برنامه‌ای بنویسیم که بدون درگیر شدن CPU یکی از پایه‌های میکروکنترلر به صورت چشمک‌زن عمل کند. این کار به دو روش میسر است:

  1. استفاده از وقفه و معکوس کردن پین مورد نظر در سرویس روتین وقفه (مثلا PORTA.0 = !PORTA.0).
  2. استفاده از بیت‌های COM و خروجی گرفتن روی پایه OC0 (این حالت حتی به وقفه هم احتیاج ندارد).
روش اول

با فرض اینکه فرکانس کاری میکروکنترلر 1 مگاهرتز باشد، برنامه را به صورت زیر می‌نویسیم:

در این برنامه پین صفرم پورت A خروجی شده و مقدار آن 0 است. رجیستر TIMSK را برابر 0x01 می‌کنیم. با این کار بیت TOIE0 یک شده و وقفه سرریز فعال می‌شود. مقدار TCNT0 را هم 0x00 کردیم که البته لزومی به اینکار نیست چون در حالت پیشفرض 0 است. سپس با مقدار 0b00000101 سه بیت CS در حالت 101 قرار گرفته و کلاک اعمالی به TCNT0 تقسیم به 1024 می‌شود. از آن جایی که فرکانس میکرو 1 مگ است، فرکانس اعمالی 976Hz خواهد شد (976 = 1000000/1024). در آخر هم بیت وقفه عمومی فعال و CPU وارد حلقه بدونه دستور while می‌شود.

چون یک دور کامل شمارش TCNT0 به 256 کلاک احتیاج دارد، پس با هر 256 کلاک یکبار وقفه اتفاق می‌افتد. به دلیل این که فرکانس اعمالی 976 هرتز است، در نتیجه در هر ثانیه تقریبا 4 بار (3.81 = 976/256) وقفه اتفاق می‌افتد. فرمول آن را مشاهده می‌نمایید:

محاسبه فرکانس در مد Normal

در فرمول فوق N همان ضرایب تقسیم (1 ، 8 ، 64 و …) و ClkI/O همان فرکانس کاری میکروکنترلر است.
در خارج از main با نوشتن interrupt سرویس روتین وقفه را تعریف کردیم که شماره Vector مربوط به سرریز تایمر 0 برابر 10 است. در نهایت هربار که تایمر سرریز شود، دستورات داخل آن اجرا خواهد شد.

روش دوم

در این روش بدون استفاده از وقفه این کار توسط رجیستر OCR0 انجام می‌شود. اگر مقدار OCR0 را 128 بگذاریم، با رسیدن TCNT0 به 128 دو رجیستر برابر شده و می‌توان مطابق جدول زیر عملی را روی پایه OC0 انجام داد.

عملکرد OC0 در حالت غیر PWM

در مد Normal دو بیت COM00 و COM01 چهار حالت دارند:

  1. اگر 00 شوند هیچگونه عملی روی پایه OC0 رخ نمی‌دهد.
  2. اگر 01 شوند، با هربار برابری OCR0 و TCNT0 منطق پایه OC0 برعکس می‌شود.
  3. اگر 10 شوند، با برابری دو رجیستر نام برده منظق پایه OC0 مطلقا 0 می‌شود.
  4. اگر 11 شوند، منطق پایه با برابری دو رجیستر 1 می‌شود.

حال که اطلاعات کافی را داریم برنامه را می‌نویسیم.

نکته: پایه OC0 نقش دیگر پایه 4 میکروکنترلر است. پس باید آن را با رجیستر DDR خروجی کنیم.
با شروع از main پایه 4 را خروجی کردیم. مقدار TCNT0 را 0 و مقدار OCR0 را هم 128 دادیم. اما مهم‌ترین خط، مقداردهی TCCR0 است. با مقداردهی 0b00010101، بیت‌های CS در وضعیت 101 قرار گرفته و کلاک را بر 1024 تقسیم می‌کنند. همینطور مطابق جدول بالا دو بیت COM00 و COM01 به ترتیب 1 و 0 می‌شوند. در این حالت با هربار برابری OCR0 و TCNT0 حالت Toggle یا برعکس شدن پایه OC0 رخ خواهد داد.

]چشمک زدن Led در مد Normal

مزیت این روش انجام تمام کار به صورت کاملا سخت‌افزاری است و نرم افزار دخالتی ندارد. تنها کاری که باید داخل برنامه انجام دهیم مقداردهی رجیسترهای تایمر است. پس از روشن شدن تایمر، بقیه کار توسط سخت‌افزار انجام می‌شود.

مد CTC

اگر WGM00 و WGM01 به ترتیب 0 و 1 شوند، میکرو در مد Clear Timer On Compare) CTC) قرار می‌گیرد. در مد CTC رجیستر TCNT0 بجای شمارش از 0 تا 255، از 0 تا مقدار موجود در OCR0 شمارش می‌کند. در این مد پس از برابر شدن TCNT0 و OCR0 با یک پالس دیگر TCNT0 صفر شده و overflow اتفاق می‌افتد.

نمودار عملکرد مد CTC

همانطور که در شکل بالا می‌بینید، نقطه چین‌های سبز رنگ مقدار 0 تا 255 را نشان می‌دهند. اما واضح است که TCNT0 پس از رسیدن به خط قرمز رنگ با یک کلاک دیگر 0 می‌شود. این خط قرمز همان مقدار OCR0 است.

مثال مد CTC

کاربردی‌ترین مزیت مد CTC ایجاد یک فرکانس متغیر است. طوری که با کم و زیاد کردن OCR0 (بین محدوده 0 تا 255) می‌توان فرکانس را تغییر داد. در شکل بالا واضح است که هر چه OCR0 بیشتر باشد، مقدار زمان هر سیکل (Period) نیز بیشتر می‌شود و برعکس. فرکانس پایه OC0 بصورت زیر محاسبه می‌گردد.

فرمول محاسبه فرکانس خروجی مد CTC

در فرمول فوق، N ضریب تقسیم فرکانس است. چون TCNT0 تا OCR0 شمارش می‌کند و با یک کلاک دیگر 0 می‌شود، عبارت (1 + OCR0) در مخرج قرار می‌گیرد (بجای 256 در مد نرمال). دلیل وجود عدد 2 این است که برای یک سیکل کامل باید دوبار منطق پایه OCR0 عوض شود (یکبار 0 شدن و یکبار 1 شدن).

با این اطلاعات برنامه‌ای می‌نویسیم که فرکانس 1KHz روی پایه OCR0 ایجاد کند (فرکانس میکرو 1MHz می‌باشد).

مطابق توضیحات، پایه 4 که همان OC0 است را با مقدار دادن DDRB خروجی کردیم. مقدار تایمر را صفر کردیم و طبق فرمول بالا با قرار دادن مقدار 1 مگاهرتز بجای ClkI/O و مقدار 1KHz بجای Focn و همچنین ضریب تقسیم 8 برای N ، مقدار OCR0 بصورت تقریبی برابر 61 شد. سپس رجیستر TCCR0 مقدارش 0b00011010 شد. با نوشتن 0b می‌توان به صورت دودویی مقداردهی کرد. با مقدار ذکر شده، ضریب تقسیم فرکانس 8 و تایمر در مد CTC قرار می‌گیرد. وضعیت بیت‌های COM نیز مشابه مد نرمال تنظیم شده است.

عملکرد OC0 در حالت غیر PWM

تذکر: عملکرد بیت‌های COM در مد Normal و CTC کاملا یکسان است.

نحوه تولید فرکانس با مد CTC

با شبیه‌سازی در پروتئوس مدت زمان هر نیم سیکل (T) یک میلی ثانیه است. پس فرکانس 1KHz خواهد شد.

مد Fast PWM

اگر WGM00 و WGM01 هر دو 1 شوند، تایمر در مد Fast PWM قرار می‌گیرد. در این مد TCNT0 بین 0 تا 255 شمارش کرده و در بین راه در صورت برابری با OCR0 متناسب با وضعیت بیت‌های COM (جدول زیر) منطق پایه OC0 تغییر می‌کند.

نمودار عملکرد مد Fast PWM

عملکرد OC0 در حالت Fast PWM

همانطور که می‌بینید مقدار TCNT0 بین 0 تا 255 شمارش می‌کند. اما در صورت برابری با OCR0 با توجه به بیت‌های COM دو حالت می‌تواند رخ دهد:

  1. اگر مقدار دو بیت COM برابر 10 باشد، پایه OC0 هنگام برابری TCNT0 و OCR0 برابر 0 می‌شود و هنگامی که TCNT0 به مقدار TOP خود یعنی 255 رسید، پایه OC0 برابر 1 منطقی خواهد شد.
  2. اگر دوبیت COM برابر 11 شوند، عکس مورد 1 اتفاق می‌افتد. در هنگام برابری، منطق پایه OC0 برابر 1 و هنگام Top شدن TCNT0 برابر 0 می‌شود.

نکته: حالت 00 باعث غیر فعال بودن پایه OC0 می‌شود و حالت 01 غیرمجاز است.
در مد Fast PWM فرکانس خروجی OC0 با رابطه زیر محاسبه می‌گردد.

فرمول محاسبه فرکانس خروجی مد Fast PWM

عدد 256 ثابت است (تعداد کلاک‌هایی که TCNT0 یک دور کامل را طی کند) و N هم ضریب تقسیم فرکانس است.

مثال مد Fast PWM

برنامه‌ای می‌نویسیم که یک موج PWM با Duty Cycle = 25% تولید کند. دقت شود که تنظیم فرکانس دلخواه در این مد کمی دشوار است. چون تنها 2 پارامتر ClkI/O و N برای تنظیم فرکانس دخیل هستند و کنترل ما روی این 2 پارامتر محدود است.

پایه 4 را خروجی و مقدار TCNT0 را 0 قرار دادیم. اما چون می‌خواهیم زمان وظیفه 25 درصد شود و می‌دانیم که یک سیکل کامل 256 پالس کلاک احتیاج دارد، با یک تناسب ساده مقدار OCR0 را باید 64 انتخاب کنیم. چون با شمارش TCNT0 از 0 تا 63 پایه OC0 در وضعیت 1 منطقی و از 64 تا 255 در حالت 0 منطقی است. در این صورت دقیقا زمان وظیفه 25 درصد می‌شود.

خروجی OC0 در مد Fast PWM

مشخص است که زمان وظیفه 25 درصد بوده و فرکانس تقریبا 500Hz است. حال اگر بخواهیم مثلا زمان وظیفه 75 درصد شود تنها کافی است در داخل برنامه فقط و فقط مقدار OCR0 را به 192 تغییر دهیم. (چرا؟ 🤔)

مد Phase Correct PWM

این مد بیشتر به Correct PWM معروف است و وقتی WGM00 و WGM01 به ترتیب 0 و 1 می‌شوند، تایمر در این مد قرار می‌گیرد. در این مد رجیستر TCNT0 از 0 تا 255 شمارش کرده و سپس سیر نزولی گرفته و از 255 تا 0 کاهش می‌یابد. پس یک سیکل کامل شامل 510 کلاک می‌شود. اما با توجه به بیت‌های COM پایه OC0 مطابق جدول زیر عمل می‌کند.

نمودار عملکرد مد Correct PWM

عملکرد OC0 در حالت Correct PWM

چون در این مد شمارش ابتدا صعودی و سپس نزولی می‌شود، در میان راه دو بار رجیسترهای TCNT0 و OCR0 برابر خواهند شد؛ یک بار در حالت صعودی و یک بار در حالت نزولی. در صورت برابری دو حالت برای پایه OC0 می‌تواند تنظیم شده باشد:

  1. اگر دو بیت COM برابر 10 شوند، هنگام تساوی TCNT0 و OCR0 در حالت صعودی، OC0 برابر 0 منطقی و در حالت نزولی برابر 1 منطقی می‌شود.
  2. اگر دو بیت COM برابر 11 شوند، عکس مورد یک اتفاق می‌افتد.

نکته: باز هم مقدار 00 باعث غیرفعال شدن پایه OC0 و مقدار 01 حالت غیرمجاز است.
در مد Correct PWM فرکانس تولیدی نسبت به مد Fast PWM کم‌تر است و مطابق فرمول زیر محاسبه می‌شود.

فرمول محاسبه فرکانس خروجی مد Correct PWM

عدد 510 ثابت است (چون یک بار شمارش صعودی و یک بار نزولی است، تعداد کلاک برای یک سیکل 510 می‌شود) و N هم ضریب تقسیم فرکانس است.

مثال مد Correct PWM

فرق زیادی بین دو مد Fast PWM و Correct PWM نیست و با توجه به فرمول‌های ذکر شده، تفاوت در 2 برابر بودن فرکانس در مد Fast PWM است. اگر در برنامه مثال Fast PWM تنها وضعیت رجیستر TCCR0 را به 0b01100010 تغییر دهیم نتایج به صورت زیر می‌شود.

شکل موج خروجی OC0 در مد Correct PWM

مشخص است که فرکانس این مد نصف مثال Fast PWM و برابر 250Hz است.

جمع‌بندی

در این مطلب سعی بر این شد که تمام مدها و عملکرد رجیسترها مورد بررسی قرار گیرد و مطالب به صورت جزئی و کامل بیان شوند. به عنوان یک جمع‌بندی کلی می‌توان به موارد زیر اشاره کرد:

  1. تایمر کانتر 0 یک تایمر 8 بیتی است. یعنی محدوده شمارش آن نهایتا بین 0 تا 255 می‌باشد.
  2. تایمر کانتر 0 دارای 3 رجیستر منحصربه فرد و 2 رجیستر مشترک است.
  3. تایمر کانتر 0 دارای چهار مد Correct PWM – Fast PWM – CTC – Normal است.
  4. تایمر کانتر 0 دو وقفه دارد که با فعال‌سازی آنها در رجیستر TIMSK می‌توان از این وقفه‌ها استفاده کرد.

همراهان عزیز این بخش طولانی به پایان رسید. چون مباحث این قسمت گیج‌کننده است، با تمرین و تکرار سعی کنید تا عملکرد مدها و رجیسترها را تا جایی که امکان دارد فرا گیرید. در قسمت دهم آموزش، بحث ما تایمر کانتر 1 است و چون مطالب مشابه هستند، حتما این بخش را بدون مشکل تمام کنید.

اگر سؤالی باقی مانده است، زیر همین پست کامنت بگذارید. تا دیداری دیگر خدانگه‌دار👋

محمد نصر

محمد نصر

محمد نصر هستم. 9 سال سابقه کار در حوزه الکترونیک و همینطور برنامه‌نویسی میکروکنترلر به صورت پیشرفته دارم. سعی میکنم هر روز چیزهای جدید یاد بگیرم و خوشحال میشم با شما به اشتراک بگذارم.

9 پاسخ

  1. سلام وقتت بخیر
    بسار عالی بود. نسبت به سایت های دیگه خیلی شفاف بود و حرف اضافه ای نبود. فقط یک سوال اگر بخواهیم فرکانس 50 هرتز ایجاد کنیم. چه کریستالی نیازه و تنظیمات به چه صورتیه؟
    ممنون

  2. سلام
    در روش دوم مد نرمال گفته شده OCR0 برابر با 128. چرا؟ تا DC 50 درصد داشته باشیم؟؟ ایا در مد نرمال میشود DC غیر 50 هم داشت؟

  3. آموزش خیلی خوب و قابل قبول بود امیدوارم موفق باشید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *