آموزش AVR

آموزش تایمر / کانتر در میکروکنترلر AVR

سلام. آموزش جامع تایمر / کانتر در میکروکنترلر های AVR  را آماده کردیم.

آموزش کامل مبحث تایمر و کانتر AVR

در قسمت قبلی سری آموزش های AVR ، ما مبحث آنالوگ به دیجیتال را به طور کامل مورد بحث قرار دادیم. و در این قسمت میخواهیم با تایمر و کانتر در AVR آشنا شویم.

قسمت قبلی : آموزش کامل مبدل آنالوگ به دیجیتال ADC در میکروکنترلر های AVR (آموزش AVR #7)

محتویات

تایمر / کانتر چیست ؟

در زندگی روزمره ما برنامه ریزی هایی داریم که با توجه به زمان انجام میشوند. یعنی چه کاری را در چه زمانی و به چه مدت انجام میدهیم. وظیفه واحد تایمر/کانتر هم مثل همین کارهاست. در برنامه ای که شما برای میکروکنترلر مینویسید همه زیر نظر واحد Timer/Counter انجام میشود.

برای یادگیری کامل آردوینو (برنامه نویسی حرفه ای، ارتباط با اندروید، ساخت ربات) ، روی دوره آموزش آردوینو کلیک کنید.

همچنین اگر میخواهید الکترونیک را با فیلم های آموزشی یاد بگیرید، روی دوره آموزش الکترونیک کلیک کنید.

بخش تایمر/کانتر از CPU میکروکنترلر جدا است تا محاسبات زمانی دقیق تر انجام شود و تحت تاثیر فعالیت پردازنده میکروکنترلر قرار نگیرد. توجه داشته باشید با این که از CPU جدا است اما پردازنده آن را کنترل میکند.

به تصویر زیر نگاه کنید :

تایمر / کانتر چیست ؟

همانطور که میبینید بخش ها از هم جدا هستند و دلیل این جدایی کاهش بار پردازشی CPU میکروکنترلر است. و واحد تایمر / کانتر وظیفه شمارش را بر عهده دارد.

تایمر مانند یک رجیستر است که مقادیر آن به صورت اتوماتیک کم و زیاد میشود. میکروکنترلر AVR دارای تایمر بسیار دقیقی است. نحوه کار تایمر / کانتر به این صورت است که اغلب از صفر شروع میکند به شمارش و ترتیب میشمارد تا به مقدار حداکثری که برای آن تعریف شده است برسد.

بعد از این که به مقدار ماکزیمم رسید Overflow میشود و اعلام مکیند شمارش مورد نظر انجام شده است.

انواع Timer / Counter در میکروکنترلر های AVR

در میکروکنترلرهای AVR دو نوع تایمر/کانتر وجود دارد :

  1. تایمر/کانتر 8 بیتی
  2. تایمر/کانتر 16 بیتی

مفهوم 8 بیتی و 16 بیتی را در قسمت قبلی به طور کامل توضیح دادیم. و به طور خلاصه : در نوع 8 بیتی طول داده ها 8 بیت است و در نوع 16 بیتی طول داده ها 16 بیت است.

در تایمر 8 بیتی شمارش از 0 شروع میشود و تا 255 میتواند ادامه پیدا کند. و در تایمر 16 بیتی شمارش از 0 شروع میشود و تا 65535 میتواند ادامه پیدا کند.

با یک مثال بحث را برایتان کامل باز میکنم.

همچنین اگر در مورد این مطلب سوالی داشتید در انتهای صفحه در قسمت نظرات بپرسید

مثال مبحث تایمر و کانتر

فرض کنید یک چراغ چشمک زن داریم. این چراغ به طور متناوب چشمک میزند. خب شیوه کار این چشمک زن چطور است ؟

فرض میکنیم که تاخیر چشمک زن یک ثانیه است. یعنی :

  1. روشن میشود
  2. 1 ثانیه روشن میماند
  3. خاموش میشود
  4. 1 ثانیه خاموش میماند

>> و تکرار همین 4 مرحله به طور متناوب

خب ما باید این چهار مرجله را به صورت الگوریتم بنویسیم. یعنی :

  1. روشن شو
  2. یک ثانیه صبر کن >> تاخیر
  3. خاموش شو
  4. یک ثانیه صبر کن >> تاخیر

در مثال بالا با نحوه کار یک چراغ چشمک زن آشنا شدید.

خب حالا بحث را علمی تر میکنیم و به جای 10 ثانیه از 10 میلی ثانیه استفاده میکنیم !

یک فرمول وجود دارد که همه با آن آشنایی دارید اما باز هم دقت کنید به آن :

فرمول دوره تناوب

این فرمول به ما نشان میدهد دوره تناوب با فرکانس رابطه عکس دارد. با فرض اینکه فلاشر دارای تاخیر 10 میلی ثانیه ای باشد، یعنی دوره تناوب آن 10 میلی ثانیه است. یعنی هر 10 میلی ثانیه یک عمل تکرار میشود.

خب با استفاده از فرمول بالا داریم :

فرمول فرکانس تایمر کانتر AVR

یعنی فرکانس فلاشر 100 هرتز است. خب اگر فرکانس کاری میکروکنترلر را روی 4MHz تنظیم کنیم :

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

با توحه به محاسبه بالا یعنی هر پالس میکروکنترلر 0.00025 میلی ثانیه طول میکشد.حالا تصویر میکنیم که مقدار شمارنده ما 0 است و قرار است شمارش را شروع کند تا به مقدار حداکثر برسد.

وقتی از مقدار 0 به 1 برسد یک پالس اعمال شده است. وقتی از 0 به 2 برسد یک پالس اعمال شده است. و وقتی …

حالا هر پالس ما بر طبق محاسبات بالا 0.00025 ثانیه طول میکشد. یعنی اگر ما بخواهیم زمان بسازیم باید مقدار متناظر آن را به تعداد پالس بدست آوریم. اینجا از فرمول زیر استفاده میکنیم :

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

TimerCount : تعداد شمارشی که باید تایمر/کانتر انجام دهد.(مجهول)

Duration : مدت زمانی که میخواهیم تایمر/کانتر صرف کند.

Period : دوره تناوبی که بدست آوردیم.

1- : این 1- هم بخاطر این است که شمارش همیشه از 0 شروع میشود نه از 1 .

خب حالا همان مثال 10 میلی ثانیه تاخیر را حل میکنیم. دقت کنید با اینکه 10 میلی ثانیه برای ما بسیااااااار ناچیز است، برای میکروکنترلر بسیاااااار بزرگ است.

اعداد را در فرمول جایگذاری میکنیم :

عدد نهایی تایمر و کانتر AVR

میبینید که عدد 39999 در خروجی ظاهر میشود و یعنی تایمر/کانتر باید از صفر تا 39999 را به ترتیب بشمارد و وقتی رسید به این عدد یعنی 10 میلی ثانیه طی شده است زیرا هر شمارش 0.00025 میلی ثانیه طول کشیده است.

اگر به عدد 39999 دقت کنید متوجه خواهید شد که تنها میتوانیم از تایمر/کانتر 16 بیتی برای ساختن آن استفاده کنیم.

زیرا همانطور که گفتیم تایمر کانتر 8 بیتی تنها میتواند نهایتا تا عدد 255 را بشمارد در حالی که تایمر/کانتر 16 بیتی میتواند تا عدد 65535 را بشمارد. و این عدد 39999 در بازه تایمر / کانتر 16 بیتی قرار دارد.

اگر محاسبه کنیم متوجه میشویم که حداکثر زمانی که میتوانیم با یک تایمر/کانتر 16 بیتی بسازیم ، 16.384 میلی ثانیه است !

حالا اگر خواستیم یک تاخیر بزرگ مثلا 20 میلی ثانیه ای ایجاد کنیم باید چه کنیم ؟

تنظیم تایمر/کانتر برای زمان های بالا

اگر به یاد داشته باشید ما در ابتدا فرکانس کاری میکروکنترلر را 4 مگا هرتز قرار دادیم. اگر این مقدار را به 0.5 مگاهرتز کاهش دهیم، در این صورت دوره تناوب 0.002 میلی ثانیه میشود و Timer Count هم میشود 9999.

مطلب پیشنهادی:  آموزش اتصال اپتوکوپلر به میکروکنترلر AVR

حالا نتایج را با هم مقایسه کنید.

فرکانس پردازنده =4 MHz , دوره تناوب =0.00025 ms , تایمر کانت=39999

فرکانس پردازنده =0.5 MHz , دوره تناوب=0.002 ms , تایمر کانت =9999

خوب به این دو نتیجه بالا دقت کنید.

همانطور که متوجه شدید در فرکانس 0.5 مگاهرتز دوره تناوب بیشتر میشود یعنی تقریبا 10 برابر اما TimerCount کمتر شده است. کم شدن مقدار تایمر کانت چه مفهمومی دارد ؟

یعنی در حالت 4 مگاهرتزی برای رسیدن به مدت زمان 10 میلی ثانیه 39999 پالس نیاز بود. اما در حالت 0.5 مگاهرتزی تعداد پالس ها کمتر شده است یعنی 9999.

یعنی همین مدت زمان را با تعداد پالس های کمتر ساختیم یعنی یک میکروکنترلر با تایمر/کانتر 16 بیتی که حداکثر مقدار آن 65636 پالس هست میتوانیم با فرکانس کمتر زمان بیشتری بسازیم.

خب جالبه بدانید که حداکثر زمانی که میتوانیم با فرکانس 0.5 مگاهرتز و تایمر/کانتر 16 بیت بسازیم ، 131.072 میلی ثانیه است. به این نتیجه میرسیم که برای اینکه مدت زمان بیشتری را بسازیم باید فرکانس را کم کنیم تا دوره تناوب بزرگ تر شود.

خب حتما با خودتان میگویید فرکانس را به حداقل برسانیم ؟ خیر این کار اشتباه است. زیرا با این کار سرعت پردازش میکروکنترلر کم میشود و همه چیز به هم میریزد ! یعنی واحد های ADC ، USART و … تنظیم هایشان بهم میریزد.

حالا باید چه کار کنیم ؟

در قسمت ADC ، راجع به تقسیم فرکانس صحبت کردیم. حالا نیز باید همان کار را انجام دهیم. مثلا یک مقدار تقسیم شده از فرکانس اصلی را به واحد Timer/Counter میدهیم. شرکت Atmel این تکنیک را برای واحدهای میکروکنترلر در نظر گرفته است و به آن prescaling میگویند.

میکروکنترلر مورد نظر ما Atmega32 است که دارای تایمر/کانتر های زیر است :

  1. تایمر/کانتر 0 (8 بیتی)
  2. تایمر/کانتر 1 (16 بیتی)
  3. تایمر/کانتر 2 (8 بیتی)

در قسمت های بعد راجع به این Timet / Counter ها بحث خواهیم کرد.

سلام. آموزش کامل تایمر / کانتر 0 در میکروکنترلر های AVR (توضیح Timer/Counter صفر) ( آموزش AVR #9) را آماده کردیم.

تایمر کانتر صفر در میکروکنترلر AVR

در قسمت قبلی به طور کلی با نحوه کار تایمر کانتر ها در میروکنترلر های AVR آشنا شدیم. یعنی با فرمول ها و نحوه محاسبه زمان و…

در پایان قسمت قبلی گفتیم که میکروکنترلر مورد نظر ما Atmega32 است و دارای تایمر/کانتر های زیر است :

  1. تایمر/کانتر 0 (8 بیتی)
  2. تایمر/کانتر 1 (16 بیتی)
  3. تایمر/کانتر 2 (8 بیتی)

بررسی کامل تایمر کانتر 0 در میکروکنترلر AVR

خب باید بدانید که تایمر کانتر صفر ، خود نیز سه نوع دارد :

  1. ساده (8 بیتی) – Atmega8
  2. پیشرفته (8 بیتی) – Atmega16 , Atmega32
  3. پیشرفته (16 بیتی) – Attiny13

این تقسیم بندی به صورت کلی است و میکروکنترلر های مختلف دارای خصوصیات مختلف هستند. اما برای بررسی همانطور که گفته شد ما مگا 32 را در نظر میگیریم یعنی نوع “پیشرفته 8 بیتی”.

میکروکنترلر Atmega 32

با یک مثال بحث را شروع میکنیم.

مثال برای فهمیدن تایمر کانتر صفر در AVR

ما قصد داریم یک فلاشر بسازیم که هر 6 میلی ثانیه یکبار چشمک بزند. همچنین فرکانس کالری میکروکنترلر را 32 کیلو هرتز در نظر میگیریم (فرضا*).

این فرکانس برای میکروکنترلر بسیار پایین است و همانطور که میدانید Microcontroller با فرکانس هایی در حدود مگاهرتز کار میکند. اما چون صرفا بحث یادگیریست این فرکانس را پایین در نظر گرفتیم تا ساده تر متوحه شوید.

بررسی رجیستر های مربوط به Timer / Counter صفر در میکروکنترلر AVR

در این قسمت ما رجیستر های مربوط به تایمر کانتر صفر را به طور کامل مورد بررسی قرار میدهیم.

رجیستر TCNT0

بررسی رجیستر های تایمر کانتر 0 در AVR

 

همانطور که در تصویر بالا میبینید این رجیستر حاوی مقدار تایمر/کانتر شماره 0 است. مقدار تایمر/کانتر در این رجیستر قرار میگیرد و به صورت اتوماتیک افزایش / کاهش پیدا میکند. این رجیستر به شمارنده 8 بیتی تایمر/کانتر صفر دسترسی مستقیم دارد و هم خواندنی است و هم نوشتنی. هنگام خواندن مقدار شمارش شده را برمیگرداند و به هنگام نوشتن مقدار جدید را به شمارنده انتقال میدهد.

رجیستر TCCR0

بررسی رجیستر کنترلی تایمر / کانتر 0

در این بخش فقط بیتهای شماره 0 و 1و 2 رو بررسی میکنیم.

بیت های 0 و 1 و 2 ؛CS02:00 – Clock Select Bits

با استفاده از این سه بیت میشود چند کار انجام داد :

  1. تایمر / کانتر را 0 یا غیرفعال کرد.
  2. فرکانس پالس تایمر / کانتر را که تقسیم تقسیم فرکانسی از فرکانس اصلی میکروکنترلر است را تعیین کرد.
  3. میتوان حساسیت timer/counter را به لبه بالا رونده یا پایین رونده اعمالی به پایه T0 را کنترل کرد.

اگر هیچ منبع پالس ساعتی انتخاب نشود، تایمر/کانتر غیر فعال خواهد شد.

انتخاب فرکانس ساعت برای تایمر کانتر

چون ما فرکانس کاری میکرو را 32 کیلوهرتز فرض کردیم (در مثال) و این فرکانس، فرکانس مناسبی برای کارکرد تایمر/کانتر هم هست، در نتیجه ما سطر دوم رر انتخاب میکنیم.یعنی نیازی به استفاده از تقسیم فرکانسی نداریم ! (در این مثال***)

رجیستر TIMSK

بررسی تایمر کانتر رجیستر timsk

این رجیستر یک رجیستر مشترک میان تمامی تایمر/کانترها میباشد. برای تایمر/کانتر صفر فقط از بیتهای 0 و 1 آن استفاده میشود و دیگر بیتها مربوط به تایمر/کانترهای دیگر میباشد !

بیت 0 ؛TOIE0 – Timer/Counter0 Overflow Interrupt Enable

با یک شدن این بیت وقفه سرریز تایمر/کانتر صفر فعال خواهد شد. لازم بذکر است که شرط فعال شدن این وقفه آن است که بیت فعال ساز وقفه (I) در رجیستر SREG نیز فعال باشد.

رجیستر TIFR

بررسی رجیستر TIFR تایمر کانتر صفر

این رجیستر هم بین تمامی تایمر/کانترها مشترک میباشد. برای تایمر/کانتر صفر فقط از بیتهای 0 و 1 آن استفاده میشود !

بیت 0 ؛ TOV0 : Timer/Counter0 Overflow Flag

این بیت هنگامی که تایمر/کانتر صفر سرریز شود یک میشود و وقتی هنوز زیر روال وقفه در حال انجم است مقدار صفر دارد. اگر هیچ زیر روالی در حال انجام نباشد با نوشتن یک در آن، بصورت دستی میتوان آن را پاک کرد.

در قسمت بعد مبحث وقفه ها را مورد بحث قرار میدهیم.

نحوه استفاده از Timer / Counter 0 در میکروکنترلر های AVR

در قسمت قبلی آموزش AVR ما با استفاده از میکروکنترلر AVR ، آنالوگ به دیجیتال ، سون سگمنت و سنسور LM35 یک دماسنج را ساختیم.

قسمت قبل : آموزش کامل پروژه دماسنج AVR با سنسور LM35 و سون سگمنت (آموزش AVR #12)

پروژه AVR برای کار با تایمر / کانتر صفر

در این آموزش هم مانند خیلی از آموزش های قبلی ، با ایجاد یک پروژه مطلب را آموزش میدهیم. ما در این پروژه میخواهیم نحوه ساخت یک ال ای دی چشمک زن که هر 8 میلی ثانیه یک بار روشن و خاموش شود را آموزش دهیم.

در این پروژه از کریستال خارجی 16 مگاهرتز و نرم افزار کدویژن استفاده میکنیم. همانطور که قبلا گفتیم با فرکانس کاری 16 مگاهرتز میتوانیم نهایتا 16 میکروثانیه زمان بسازیم.

با توجه به اینکه تایمر / کانتر شماره 0 ، یک تایمر کانتر با دقت 8 بیتی است، حداکثر میتواند تا 255 را بشمارد پس باید حاصل Timer Count ما در محدوده 0 تا 255 قرار بگیرد.

فرمول ها را که یادتان هست ؟

به جدول زیر دقت کنید.

مطلب پیشنهادی:  آموزش ایجاد سیگنال PWM در میکروکنترلر AVR

کار با تایمر کانتر 0 در AVR

مشاهده میکنید که رنج مورد نظر ما، تنها در ضریب تقسیم 1024 قابل دسترسی است. در ضریب تقسیم های دیگر مقدار شمارش بیشتر از 255 است و از محدوده شمارش تایمر/کانتر صفر خارج است.

توضیحات کد پروژه

در ابتدا کتابخانه میکروکنترلر Atmega32 را فراخوانی میکنیم.

#include <mega32.h>
void timer0_configuration(){}
void main(){}

تابعی تعریف شده با نام timer0_configuration که پیکربندی تایمر/کانتر صفر در آن انجام میشود.

همانطور که در قسمت های قبل گفته شد، رجیستری داریم با نام TCCR0 که با سه بیت اول آن ضریب تقسیم را مشخص میکنیم. (اگر نمیدانید رجیستر TCCR0 چیست حتما قسمت 9 آموزش های AVR را بخوانید!)

void timer0_configuration(){
TCCR0 |=(1<<CS00)|(1<<CS02);
}

و رجیستر دیگری نیز داشتیم به نام TCNT0 که مقدار تایمر/کانتر در آن قرار میگرفت. برای اطمینان بیشتر مقدار آن را در ابتدا صفر قرار میدهیم.

void timer0_configuration(){
TCCR0 |=(1<<CS00)|(1<<CS02);
TCNT0 |=;
}

میخواهیم ال ای دی را به پایه B0 میکروکنترلر Atmega 32 متصل کنیم. پس باید این پایه را به عنوان Output یا همان خروجی تعریف کنیم.

void main(){
DDRB = 0x01;
}

یه دونه حلقه بینهایت تعریف کردیم و داخلش یه شرط گذاشتیم که اگه مقدار شمارش شده به 124 یا احیانا بیشتر از اون رسید پین B0 رو Toggle (خاموش/روشن) کنه !

در پایان هم مقدار تایمر/کانتر صفر رو صفر کردیم تا شمارش مجددا از صفر شروع بشه و به 124 برسه !

یک حلقه بی نهایت void main تعریف میکنیم و در داخل آن یک شرط میگذاریم. که اگر مقدار شمارش به 124 یا بیشتر رسید پین B0 را روشن / خاموش کند. در پایان هم مقدار تایمر کانتر را صفر میکنیم تا شمارش از نو آغاز شود.

void main(){
DDRB = 0x01;
timer0_configuration();
while(1){
if(TCNT0>=124){
PORTB ^= (1<<PORTB0);
TCNT0 = 0; } } }

کد کامل :

#include <mega32.h>
void timer0_configuration(){
TCCR0 |=(1<<CS00)|(1<<CS02);
TCNT0 |=;
}
void main(){
DDRB = 0x01;
timer0_configuration();
while(1){
if(TCNT0>=124){
PORTB ^= (1<<PORTB0);
TCNT0 = 0; 
 } } }

این آموزش نسبت به آموزش های دیگر کوتاه بود اما لازم بود این مطالب گفته شود. انشالله در قسمت بعدی آموزش در مورد تایمر / کانتر 1 صحبت میکنیم.

آموزش کامل Timer / Counter یک در میکروکنترلر AVR

در قسمت های قبلی آموزش ما به طور کامل با مبحث تایمر کانتر ها و به خصوص با تایمر / کانتر 0 آشنا شدیم. حتما قبل از خواندن این مطلب قسمت های قبل را بخوانید.

در این قسمت از سری آموزش های AVR ما به طور کامل با Timer Counter 1 آشنا میشویم. در این آموزش هم با طرح یک مسئله مفهوم را به شما منتقل میکنیم.

طرح مسئله برای تایمر / کانتر 1

فرض کنید ما میخواهیم یک فلاشر LED بسازیم که هر 2 ثانیه یک بار چشمک بزند. همانطور که میدانید تایمر / کانتر یک ، یک تایمر / کانتر 16 بیتی است. ما فرکانس کاری میکروکنترلر را 16MHz در نظر میگیریم.

حل مسئله

فرمول زیر را که یادتان هست.

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

با فرکانس 16MHz حداکثر تاخیری که میتوانیم بسازیم 4.096 میلی ثانیه است. با انتخاب ضریب 8 ، فرکانس پردازنده به 2 مگاهرتز کاهش پیدا میکند و حداکثر تاخیر به 32.768 افزایش پیدا میکند. اما همانطور که گفتیم ما نیاز به تاخیر 2 ثانیه ای داریم، باید چکار کنیم ؟

2s ÷ 32.768 ms = 61.035 ≈ 61

به محاسبه بالا دقت کنید. 2 ثانیه مدنظر ما بود را به 32.768 تقسیم کردیم که حاصل تقریبا 61 شده است. معنی 61 چیست ؟

61 یعنی اگر 61 بار تایمر از صفر بشمارد و به ماکزیمم 65535 برسد، 2 ثانیه طول میکشد.

تایمر / کانتر یک در میکروکنترلر های AVR

بررسی رجیستر های تایمر / کانتر یک در AVR

در این قسمت به طور کامل رجیستر های timer / Counter 1 را بررسی میکنیم.

رجیستر TCCR1B

رجیستر TCCR1B :Timer/Counter1 Control Register B - TCCR1B

بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS12:0: Clock Select :

بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS12:0: Clock Select :

از این بیت ها برای تعیین فرکانس تایمر / کانتر 1 یا همان انتخاب ضریب تقسیم استفاده میشود. در اینجا، ضریب تقسیم را 8 انتخاب کردیم، باید مقدار سطر سوم رو انتخاب کنیم (010).

رجیستر TCNT1

مقدار timer / counter 1 در این رجیستر قرار میگیرد. تایمر کانتر 1 ، یک تایمر کانتر 16 بیتی است که از دو رجیستر 8 بیتی در کنار هم تشکیل شده است که با پسوند H و L مشخص شده اند.

بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS12:0: Clock Select :

رجیستر TIMSK

بررسی رجیستر TIMSK : Timer/Counter-Interrupt Mask-Register

در مورد این رجیستر هم که قبلا خیلی صحبت کرده ایم. بیت هایی که پس زمینه سفید دارند مربوط به Timer / Counter 1 هستند. در اینجا تنها بیت TOIE1 را استفاده میکنیم که با 1 شدن آن ، وقفه سرریز تایمر / کانتر فعال میشود.

رجیستر TIFR

بررسی رجیستر TIFR : Timer/Counter Interrupt Flag Register – TIFR

در مورد این رجیستر هم قبلا خیلی صحبت کرده ایم. در اینجا تنها بیت مورد نظر ما ، TOV1 است. وقتی که Timer / Counter 1 سر ریز شود ، این بیت 1 میشود و پس از اینکه موارد مربوط به وقفه ها به صورت کامل انجام شد 0 میشود.

آموزش کامل کار با تایمر /  کانتر یک در AVR

در این قسمت همچنین از وقفه ها استفاده میکنیم. ما در این آموزش یک پروژه را با زبان C در کامپایلر Codevision برنامه نویسی میکنیم. برای این آموزش از میکروکنترلر مگا 32 استفاده میکنیم. هدف کلی ما این است که تاخیری به میزان 2 ثانیه بسازیم.

در اینجا نیز فرکانس کاری میکروکنترلر را 16 مگاهرتز خارجی تعریف میکنیم.

 #include <mega32.h>

تابعی تعریف میکنیم با نام timer1_configuration که در آن تنظیمات اولیه و پیکربندی تایمر / کانتر را انجام میدهیم.

void timer1_configuration (){ 
TCCR1B |=(1<<CS11); // Prescaler=8 
TIMSK |=(1<<TOIE1); // Enable Timer1 Overflow 
TCNT1=; // Initialize Timer/Counter1 
#asm ("sei"); //فعال سازی وقفه های سراسری 
}

یعنی توضیحاتی را که در قسمت قبل دادیم را وارد محیط کدویژن میکنیم. سپس میرسیم به تابع main.

void main(){ 
DDRB. = 1; // تنظیم پین B0 به عنوان خروجی
timer1_configuration (); // بارگذاری Timer1 Configuration 
while(1){} // چرخه بی انتها
}

ما میخواهیم به پین b0 ال ای دی را وصل کنیم پس آنرا به عنوان خروجی تعریف میکنیم. در خط بعدی تابع timer1_configuration را فراخوانی میکنیم.

یه متغیری تعریف میکنیم از جنس int ، با نام : overflow . وظیفه این متغیر شمارش تعداد سرریز هایی است که رخ میدهد. همانطور که در قسمت قبل گفتیم ، باید 61 بار سرریز شود تا 2 ثانیه طور بکشد. پس وظیفه این متغیر این است که بفهمد چه زمانی تعداد سرریز ها به 61 میرسد.

int overflow=0;

همچنین مقدار اولیه آن را 0 قرار میدهیم.

تعریف زیرروال مربوط به وقفه

در مورد وقفه ها قببلا به طور کامل توضیح داده ایم برای ادامه باید حتما با وقفه ها آشنا باشید : وقفه چیست ؟ آموزش کامل وقفه در میکروکنترلر AVR

برای تعریف وقفه از تابع کلیشه ای زیر استفاده میکنیم :

interrupt [Vector Number] void int_expression (void) {
 برنامه سرویس وقفه 
}

به جای عبارت int_expression ، یک نام دلخواه برای تابع وقفه انتخاب میکنیم. به جای [Vector Number] هم عدد وکتور مورد نظر را از روی دیتاشیت انتخاب میکنیم. در مورد Vector Number هم از روی دیتاشیت نگاه میکنیم و عدد مورد نظر رو انتخاب میکنیم و از آن استفاده میکنیم.

مطلب پیشنهادی:  پروژه دماسنج با میکروکنترلر AVR و سنسور LM35

نحوه کار با تایمر / کانتر 1 در میکروکنترلر AVR

نکته : در داخل براکت به جای عدد، میتوان از عبارت متناظر در ستون Source جدول بالا نیز استفاده کرد.

interrupt [10] void timer1_int (){}

اینجا هم برای Vector Number عدد 10 را انتخاب میکنیم که مربوط به وقفه Timer/Counter1 Overflow میشود. اسم آن را هم timer1_int انتخاب میکنیم.

interrupt [10] void timer1_int (){ 
overflow++; // افزایش تعداد Overflow
if(overflow>=61){ // چک کردن در صورتی که 2 ثانیه بگذرد
PORTB^=(1<<); // Toggle B.0 
overflow=; // شمارش تعداد Overflow ها
} 
}

با هر بار سر ریز شدن،یک واحد به متغیر overflow اضافه میشود. وقتی که تعداد سرریز ها از 61 یا بیشتر شود ، پین B0 شروع به Toggle میکند.

Toggle شدن = فعال و غیر فعال شدن

در انتها مقدار متغیر overflow را صفر میکنیم تا تایمر/کانتر یک، مجددا اقدام به محاسبه زمان مورد نظر کند.

کد کامل استفاده از تایمر / کانتر 1 در کدویژن AVR

کد کامل این آموزش را در باکس زیر میتوانید مشاهده کنید :

#include <mega32.h> 
int overflow=; 
void timer1_configuration (){ 
TCCR1B |=(1<<CS11);
TIMSK |=(1<<TOIE1);
TCNT1=;
#asm ("sei"); 
} 
interrupt [10] void timer1_int (){ 
overflow++; 
if(overflow>=61){ 
PORTB^=(1<<);
overflow=;
} 
} 
void main(){ 
DDRB. = 1;
Pin timer1_configuration (); 
while(1){}
}

با محاسباتی که در قسمت قبلی آموزش انجام دادیم فهمیدیم که برای ایجاد تاخیر 2 ثانیه ای حدودا 61 بار سرریز تایمر / کانتر یک لازم است. با ایجاد یک تابع به نام timer1_configuration ، پیکربندی تایمر / کانتر را انجام دادیم.در تابع main پین B.0 را به عنوان پین خروجی تعریف کردیم و تابع timer1_configuration را فراخوانی کردیم.

در واقع ما کاری نمیخوایم انجام بدیم و کار اصلی را تایمر انجام میدهد و فعالیت تایمر/کانتر هم مستقل است. یک حلقه بینهایت میسازیم و برنامه را در آن قرار میدهیم. منتظر میمانیم که 2 ثانیه بگذرد (یعنی وقتی که تایمر / کانتر 61 بار سرریز شد.)

تا Timer Counter 1 سرریز کرد ، سریع میرود به برنامه زیرروال timer1_int و آن را انجام میدهد و سپس به محل قبلی برمیگردد. زیر روال به تایمر کانتر دستور میدهد که هروقت سرریز شد ، یک مقدار به متغیر overflow اضافه کند.

سپس یک شرط تعیین کردیم که هر وقت تعداد این سرریز ها 61 شد ، پین B.0 را روشن / خاموش کند.

این آموزش AVR هم تمام شد. انشالله در قسمت بعد با تایمر / کانتر 2 آشنا میشویم.

سلام. آموزش کامل تایمر / کانتر 2 در میکروکنترلر AVR به همراه مثال هایی از Timer / counter دو را آماده کرده ایم.

آموزش کامل تایمر کانتر دو در AVR

در قسمت قبلی سری آموزش های AVR ما به طور کامل با تایمر کانتر 1 در میکروکنترلر های AVR آشنا شدیم. پیشنهاد میکنم آموزش ها را به بخوانید ، پس اگر قسمت های قبلی را نخوانده اید ، آن ها را بخوانیدو

در این قسمت آموزش AVR ما به طور کامل به صورت تئوری و عملی با کدنویسی و تنظیم Timer counter 2 آشنا میشویم.

تایمر / کانتر 2 چیست ؟

تایمر / کانتر شماره دو مانند تایمر کانتر شماره 0 است یعنی 8 بیتی است و رجیستر های آنها نیز مشابه است. منتهی تایمر کانتر 2 ، ویژگی خاصی دارد که به آن میگویند عملیات آسنکرون (Asynchronous Operation ).

ما باز هم مانند قسمت های قبلی آموزش ، مسئله ای طرح میکنیم.

ما میخواهیم یک فلاشر طراحی کنیم که هر 50 میلی ثانیه چشمک بزند. ما از کریستال خارجی 16 مگاهرتز استفاده میکنیم.

تایمر / کانتر دو 2 در میکروکنترلر AVR

حل مسئله :

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

با انتخاب ضریب تقسیم 256،زمان سرریز 4.096 میلی ثانیه میشود. با 12 بار سرریز شدن تایمر/کانتر،و شمرده شدن تا گام 53 در 13 اُمین سرریز مدت زمان 50 میلی ثانیه طی خواهد شد. تمامی صحبتهایی که شد تکراری است و از توضیح مجدد خودداری میکنیم.

بررسی رجیسترها

رجیستر TCCR2 : Timer/Counter2 Control Register

رجیستر TCCR2 : Timer/Counter2 Control Register

بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS22:0: Clock Select :

بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS22:0: Clock Select :

از این بیتها استفاده میکنیم برای انتخاب ضریب تقسیم مورد علاقه. ما 256 رو انتخاب میکنیم.

رجیستر TCNT2 : Timer/Counter2

این رجیستر هم مقدار Timer Counterشماره 2 را در خودش نگه میدارد.

رجیستر TIMSK : Timer/Counter-Interrupt Mask-Register

رجیستر TIMSK : Timer/Counter-Interrupt Mask-Register

در اینجا تنها بیت TOIE2 مد نظر ماست که با 1 کردن آن وقفه سر ریز تایمر/کانتر 2 فعال میشود.

رجیستر TIFR : Timer/Counter Interrupt Flag Register – TIFR

رجیستر TIFR : Timer/Counter Interrupt Flag Register – TIFR

در اینجا هم تنها بیت TOV2 مد نظر ماست.

هنگامی که تایمر/کانتر 1 سر ریز شود، این بیت 1 میشود و پس از اینکه زیرروال مربوط به وقفه (interrupt) بصورت کامل انجام شد 0 میشود و اگر زیرروالی وجود نداشت، با نوشتن یک 1 دیگر روی آن، 0 میشود.

اگر با وقفه ها آشنا نیستید، مقاله آموزش وقفه در AVR را بخوانید.

آموزش کدنویسی تایمر کانتر 2 در کدویژن

فرکانس کاری میکروکنترلر 16 مگاهرتز خارجی تعریف شده است. در ابتدا مانند همیشه کتابخانه میکروکنترلر مگا 32 را فراخوانی میکنیم. سپس تابعی را با نام timer2_configuration تعریف میکنیم که تنظیمات Timer / Counter 2 را در آن انجام میدهیم.

#include <mega32.h> 
unsigned int overflow; 
void timer1_configuration (){
TCCR2 |=(1<<CS21)|(1<<CS22);
TIMSK |=(1<<TOIE2); 
TCNT2=; 
#asm ("sei"); 
overflow = 0;
}

این بخش از کد مانند کد های قسمت های قبل است پس از ارائه توضیحات اضافی میگذریم.

سپس به تابع main میرسیم.

void main(){ 
DDRB. = 1;
timer2_configuration ();
}

پین B0 را به عنوان خروجی (Output) تعریف میکنیم زیرا همان پینی است که ال ای دی به آن متصل میشود. در خط سوم نیز تابع timer2_configuration را فراخوانی میکنیم تا تنظیمات تایمر / کانتر 2 انجام شود.

و سپس  :

while(1){ 
if(overflow>=12){ 
if(TCNT2>=53){ 
PORTB. ^=(1<<); // روشن و خاموش کردن ال ای دی 
TCNT2=; // ریست کردن تایمر / کانتر
overflow=; // ریست شمارنده Overflow  
} 
} 
}

این قسمت نیز مانند قسمت های قبلی آموزش AVR بود و نیازی به ارائه توضیحات اضافه نیست در صورتی که متوجه نشدید قسمت های قبلی مربوط به تایمر کانتر را بخوانید 🙂

حالا میرسیم به قسمت وقفه و زیرروال :

interrupt [TIMER2 OVF] void timer2_isr (void) { 
overflow++; // اضافه کردن یک مقدار به متغیر overflow 
}

کد کامل :

#include <mega32.h> 
void timer2_configuration (){
TCCR2 |=(1<<CS21)|(1<<CS22); 
TIMSK |=(1<<TOIE2); 
TCNT2=;
#asm ("sei");
overflow = ;
} 
interrupt [TIMER2 OVF] void timer2_isr (void) { 
overflow++; 
} 
while(1){ 
if(overflow>=12){ 
if(TCNT2>=53){ 
PORTB. ^=(1<<);
TCNT2=; 
overflow=;
} 
} 
}

خب این قسمت هم از سری آموزش های میکروکنترلر های AVR تمام شد، در قسمت بعد به طور کامل با مد CTC آشنا میشویم.

قسمت بعد : آموزش مود های مختلف تایمر / کانتر در میکروکنترلر های AVR (آموزش AVR #17)

میخواهید آردوینو را به صورت فیلم، و پروژه محور یاد بگیرید؟

دوره آموزش آردوینو

میخواهید الکترونیک را با فیلم های آموزشی یاد بگیرید؟

دوره آموزش الکترونیک
برای مشاهده توضیحات روی دوره مورد نظر کلیک کنید
محمد رحیمی

محمد رحیمی

محمد رحیمی هستم. سعی میکنم در آیرنکس مطالب مفید را قرار دهم. (در خصوص سوال در مورد این مطلب از قسمت نظرات همین مطلب اقدام کنید) سعی میکنم تمام نظرات را پاسخ دهم.

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

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