آموزش AVR

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

سلام. آموزش مود های مختلف تایمر کانتر (مد CTC) در میکروکنترلر های AVR را آماده کردیم.

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

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

حتما حتما حتما قبل از خواندن این قسمت از آموزش AVR ، قسمت قبلی را بخوانید :

خب تا اینجا ما به طور کامل متوجه شدیم که تایمر کانتر چیست و چه میکند. از این به بعد مبحث timer / counter ها را حرفه ای تر ادامه میدهیم. برای استفاده بهتر و بهینه تر از تایمر و کانتر ها شرکت اتمل مد های متفاوتی را تعریف کرده است.

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

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

  1. Normal Mode = مود معمولی
  2. CTC Mode = مود CTC
  3. Fast PWM Mode = مود PWM سریع
  4. Phase Correct PWM Mode = مود PWM فاز صحیح
  5. Phase And Frequency Correct PWM Mode > فقط در بعضی از میکروکنترلر های AVR

در ابتدا نگاهی گذرا به حالت Normal میاندازیم. اما در این آموزش بیشتر با مود CTC آشنا میشویم.

Normal Mode = مود معمولی چیست؟

این مود همان مدی است که تا کنون با ان کار کرده ایم. در مود معمولی تایمر کانتر از صفر شروع میکند و تا مقدار ماکزیموم خود میشمارد و سپس 0 میشود و تکرار این داستان. از این مود تایمر کانتر برای عملیات های ساده استفاده میشود.

CTC Mode = مود CTC چیست ؟

CTC مخفیف Clear Timer On Compare Match میباشد که به معنی “پاک کردن تایمر در هنگام مچ شدن عمل مقایسه”  است. یعنی هر وقت مقدار تایمر (TCNT0) با یک مقدار دیگر (OCR0) برابر شد، مقدار تایمر/کانتر 0 میشود. به عبارت دیگر، مقدار ماکزیمم ما در اینجا FF نیست. بلکه مقدار ماکزیمم مثل شکل زیر OCR0 میباشد.

CTC Mode = مود CTC چیست ؟

در قسمتهای قبلی آموزش،عمل مقایسه رو بصورت نرم افزاری انجام میدادیم. یعنی با فرمول، مقدار TimerCount را حساب میکردیم و در برنامه شرط میگذاشتیم که هر وقت مقدار رجیستر TCNTx برابر با مقدار TimerCount شد، یک کاری انجام شود.

اما استفاده از اینگونه شروطی که دائما CPU را درگیر خود میکند برای همیشه مناسب نیست. با استفاده از مود CTC، عمل مقایسه بصورت سخت افزاری انجام میشود و در نتیجه احتمال خطا کمتر میشود و بار مقایسه نرم افزاری از روی دوش CPU برداشته میشود.

تصویر زیر را ببینید :

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

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

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

این تصویر مربوط به تایمر کانتر 0 است. ببینید در ردیف شکل ردیف اول یک موج دندان اره ای داریم که از 0 شروع میشود و تا 255 میشمارد. بعد از آن مجددا صفر میشود و تکرار داستان.

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

یک خط چین افقی وجود دارد که همان مقدار مقایسه ای ما است یعنی OCR0A که برای مثال مقدار آن 250 در نظر گرفته شده است. توجه داشته باشید که نمودار اول، توسط میکروکنترلر ساخته نمیشود و کاملا نمایشی است برای درک مسئله ! تایمر شروع به شمردن از 0 میکند و به مقدار OCR0 میرسد.

هنگامی که تایمر به OCR0 برسد یعنی همان مقدار ماکزیمم ، Microcontroller مطلع میشود که مقادیر با هم برابر شده اند. در شکل بالا که یک مثال است ، با برابر ششدن مقدار دو رجیستر TCNT0 و OCR0،پایه OC0 میکرو فعال / غیر فعال میشود. اما ما میتوانیم حالتهای مختلفی برای پایه OCx انتخاب کنیم.

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

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

بررسی رجیستر OCR0 : Output Compare Register

بررسی رجیستر OCR0 : Output Compare Register

مقدار ماکزیمم مورد نظر خود را در این رجیستر قرار میدهیم. دقت داشته باشید که تایمر کانتر صفر ، یک تایمر کانتر 8 بیت است تنها میتواند مقداری بین 0 تا 255 را استفاده کنیم.

بررسی رجیستر TCCR0 : Timer/Counter Control Register

بررسی رجیستر TCCR0 : Timer/Counter Control Register

بیت های 3 و 6 ؛ Bit 6 , 3 – Wave Generation Mode Bits : با استفاده از این 2 بیت و جدول پایین میتوانیم مود کاری تایمر کانتر 0 را مشخص کنیم.

بیت های 3 و 6 ؛ Bit 6 , 3 – Wave Generation Mode Bits :

که در اینجا ردیف سوم جدول بالا مد نظر ماست و مقدار WGM0:1 برابر با 10 در نظر گرفته خواهد شد.

بیت های 4 و 5 ؛ Bit 5 , 4 – Compare Match Output Mode :

مشخصا در میکروکنترلر ATmega32 پایه ای داریم به نام OC0 . به جدول زیر نگاه کنید :

این جدول میگوید با برابر شدن مقدار تایمر / کانتر 0 با مقدار رجیستر OCR0 ، در پایه OC0 میکروکنترلر فعالیتی انجام شود.

  • حالت 00 : غیر فعال بودن OC0 یعنی پایه OC0 در حالت عادی به کار خود ادامه خواهد داد.
  • حالت 01 : به محض برابر شدن، وضعیت پایه OC0 میکروکنترلر Toggle خواهد شد یعنی اگر 1 منطقی روی پایه هست 0 میشود و اگه 0 هست 1 میشود !
  • حالت 10 : به محض برابر شدن، وضعیت پایه OC0 میکرو Clear خواهد شد. یعنی وقتی برابری اتفاق بیافتد وضعیت پایه OC0 صفر خواهد شد.
  • حالت 11 : به محض برابر شدن، وضعیت پایه OC0 میکرو Set خواهد شد یعنی وقتی برابریاتفاق افتاد وضعیت پایه OC0 یک خواهد شد.

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

بیت 1 ؛ Bit 1 – OCIE0: Timer/Counter0 Output Compare Match Interrupt Enable :

با یک کردن این بیت، میتوانید وقفه برابری مقدار تایمر/کانتر صفر و مقدار رجیستر OCR0 را فعال کنید.

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

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

بیت 1 ؛ Bit 1 – OCF0: Output Compare Flag 0 :

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

همچنین با نوشتن 1 بر روی این فلگ، میتوانیم به صورت دستی آن را 0 کنیم. دقت داشته باشید که با فعال بودن بیت وقفه سراسری (I) از رجیستر SREG ( با دستور اسمبلی “sei” در محیط کدویژن ) و همچنین بیت OCIE0 از رجیستر TIMSK و فعال شدن همین بیت، وقفه اجرا خواهد شد.

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

رجیستر در تایمر کانتر 1 میکروکنترلر AVR

در اینجا رجیستر های مربوط به timer counter یک را بررسی میکنیم.

رجیسترهای OCR1A , OCR1B :

Output Compare Register 1 A – OCR1AH and OCR1AL و Output Compare Register 1 B – OCR1BH and OCR1BL

بررسی رجیسترهای OCR1A , OCR1B :

این دو رجیستر از نوع 16 بیتی هستند و میتوانند عددی بین 0-65535 را در خود قرار دهند. گفتیم که این مقایسه به صورت سخت افزاری انجام میشود. اگر یادتان باشد عددی بدست آوردیم که مقدارش 24999 بود. حالا این عدد را در یکی از این دو رجیستر قرار میدهیم. در واقع کمپانی اتمل برای این بخش 2 تا Compare Register تعریف کرده است تا قادر باشیم مقدار تایمر/کانتر یک را همزمان با دو مقدار (OCR1A , OCR1B) مقایسه کنیم. این دو رجیستر تفاوتی با هم ندارند.

رجیستر TCCR1A : Timer/Counter1 Control Register A – TCCR1A

رجیستر TCCR1A : Timer/Counter1 Control Register A - TCCR1A

بیت های  و 1؛ Bit 1:0 – Wave Generation Mode Bits :
با این دو بیت و بیتهای WGM12:13 از رجیستر TCCR1B میتوانیم مد کاری Timer / Counter 1 را مشخص کنیم.

بیت های 4 و و 6 و 7 ؛ Bit 4:7 – Wave Generation Mode Bits :

برای تایمر / کانتر یک هم مشخصا پایه هایی با نام های OC1A و OC1B وجود دارد. جدول زیر را ببینید :

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

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

بیت های 3 و 4؛ Bit 4:3 – Wave Generation Mode Bits :

از این رجیستر هم با دو بیت WGM12,WGM13 سر و کار داریم. این چهار بیت (WGM10,WGM11,WGM12,WGM13) از دو رجیستر TCCR1A و TCCR1B در کنار هم میتوانند مود کاری تایمر/کانتر را تعیین کنند.

بیت های 3 و 4؛ Bit 4:3 – Wave Generation Mode Bits :

مود شماره 4 و 12 جدول بالا مدنظر ماست. ما مود 4 رو انتخاب میکنیم که مقدار متناظر آن برای 4 فلگ WGM10:13 برابر 0100 خواهد بود.

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

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

بیت 3 و 4 ؛ Bit 3:4 – OCIE1A:B: Timer/Counter1, Output Compare A:B Match Interrupt Enable :

با یک کردن هر یک از دو بیت بالا میشود وقفه های برابری مقدار timer / counter 1 با رجیستر های OCR1A و OCR1B را فعال کرد.

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

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

بیت 3 و 4 : Bit 4:3 – OCF1A:B – Timer/Counter1, Output Compare A/B Match Flag Bit :

هرگاه مقدار رجیستر TCNT1 با مقدار رجستر OCR1A (یا OCR1B) برابر باشد، مقدار فلگ OCF1A (یا OCF1B) یک خواهد شد. این فلگ پس از اجرا شدن روتین وقفه بصورت اتوماتیک 0 خواهد شد. در صورت عدم استفاده از وقفه با نوشتن 1 بر روی این فلگ میتوانید مقدار آن را به 0 برگردانید. فعال بودن فلگ وقفه سراسری از رجیستر SREG و همچنین فعال بودن بیت OCIE1A (یا OCIE1B) و فعال شدن فلگ OCF1A (یا OCF1B) وقفه رخ خواهد داد.

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

در اینجا رجیستر های مربوط به timer counter دو را بررسی میکنیم.

رجیستر OCR2 : Output Compare Register

بررسی رجیستر OCR2 : Output Compare Register

مقدار مورد نظر برای مقایسه در این رجیستر قرار میگیرد.

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

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

بیت های 3 و 6 ؛ Bit 6, 3 – WGM21:0: Waveform Generation Mode :

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

بیت های 3 و 6 ؛ Bit 6, 3 – WGM21:0: Waveform Generation Mode :

بیت های 4 و 5 ؛ Bit 5:4 – COM21:0: Compare Match Output Mode :

با این بیتها هم میشود مثل قبل وضعیت پایه OC2 را مشخص کرد. طبق جدول زیر :

بیت های 4 و 5 ؛ Bit 5:4 – COM21:0: Compare Match Output Mode :

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

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

بیت 7 ؛ Bit 7 – OCIE2: Timer/Counter2 Output Compare Match Interrupt Enable :

با یک کردن این بیت،وقفه تایمر/کانتر دو فعال میشود.

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

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

بیت 7 ؛ Bit 7 – OCF2: Output Compare Flag 2 :

اگر مقدار تایمر/کانتر دو با مقدار رجیستر OCR2 برابر شود، این بیت 1 میشود.

سلام. آموزش کامل برنامه نویسی تایمر / کانتر یک در مود CTC (آموزش AVR #18) را آماده کردیم.

آموزش کار با مود CTC در تایمر کانتر 1

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

این آموزش را نیز با تعریف یک مسئله شروع میکنیم.

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

به طور مثال ما میخواهیم یک فلاشر ال ای دی بسازیم که هر 100 میلی ثانیه چشمک بزند. ما از Timer / Counter 1 و مد CTC استفاده میکنیم. میدانیم که تایمر کانتر یک نهایتا میتواند تا 65535 میتونه بشمارد. با انتخاب ضریب تقسیم 64 ، فرکانس تایمر/کانتر به 250 کیلوهرتز کاهش پیدا میکند و برای ایجاد تاخیر 100 میلی ثانیه ای ، مقدار TimerCount برابر 24999 میشود.

چند تا رجیستر هم داریم که قبلا با اکثرشان آشنا شدید و اینجا با فلگ های جدیدتری از آن ها آشنا میشویم.

ابتدا مثل همیشه کتابخانه میکروکنترلر Atmega 32 را فراخوانی میکنیم.

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

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

#include <mega32.h>
void timer1_configuration (void){
TCCR1A = 0x00; //WGM10 = 0 , WGM11 = 0
TCCR1B = (1 << WGM12)|(1 << CS11)|(1 << CS10); 
TCNT1 = ; 
OCR1A = 24999; 
} 

مقدار ضریب تقسیم 64 در نظر گرفته شده و مقادیر فلگ های CS10 و CS11 از رجیستر TCCR1B جهت استفاده در مد CTC و با توجه به جدول زیر یک شده اند.

برنامه نویسی تایمر / کانتر یک در مود CTC (آموزش AVR #18)

تا اینجای کار تایمر/کانتر در مود CTC برنامه ریزی شد. مقدار رجیستر OCR1A هم با توجه به محاسبات انجام شده در ابتدای پست 24999 تعیین شد.

تابع اصلی یعنی تابع main :

void main(){

DDRC |=(1 << );

timer1_configuration();

while(1){

  if (TIFR & (1 << OCF1A)){
    PORTC ^=(1 << );
  }

TIFR |=(1 << OCF1A);

}
} 

پین 0 از پورت C بعنوان خروجی در نظر گرفته میشود و به LED مربوطه وصل میشود. در خط بعدی تابع timer1_configuration فراخوانی میشود که حاوی تنظیمات تایمر/کانتر شماره یک است. پس از آن یه حلقه بی نهایت داریم که در آن یک شرط مینویسیم.

یک شرط گذاشتیم که هر وقت فلگ OCF1A از رجیستر TIFR یک شود، پین 0 از پورت C فعال / غیرفعال شود.

فلگ OCF1A وظیفه اش این بود که هروقت مقدار تایمر/کانتر یک، با مقدار مشخص شده در رجیستر OCR1A برابر شد یک شود. و از یک شدن این فلگ متوجه میشیم که سرریز رخ داده و عمل برابر شدن اتفاق افتاده است.

پس از اینکه فلگ OCF1A یک شد،باید بصورت دستی آن را 0 کنیم.

مثال برای فهمیدن مود CTC در تایمر کانتر 1

مثال دوم برای فهمیدن مود CTC در تایمر کانتر 1

میتوانیم همین برنامه را حرفه ای بنویسیم در آن از اینتراپت (وقفه) استفاده کنیم.

اول از همه شروع میکنیم به پیکربندی تایمر/کانتر یک با استفاده از ویژگی وقفه !

بار دیگر تابع timer1_configuration را بازنویسی میکنیم و تغییرات مورد نیاز را اعمال میکنیم.

void timer1_configuration (void){

TCCR1A = 0x00; //WGM10 = 0 , WGM11 = 0
TCCR1B = (1 << WGM12)|(1 << CS11)|(1 << CS10); //Mode = CTC , Prescaler = 64

TCNT1 = ; //initialize timer/counter 1

OCR1A = 24999; //initialize compare value

TIMSK |=(1<<OCIE1A); //Enable Compare Interrupt

#asm("sei") //Enable Global Interrupt
} 

فلگ OCIE1A از رجیستر TIMSK را یک میکنیم تا وقفه مقایسه ای تایمر/کانتر یک فعال بشود. در انتها هم فلگ I از رجیستر SREG را فعال میکنیم.

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

interrupt [8] void compare_interrupt (void){
PORTC ^=(1 << );
}  

تابع اینتراپت را نوشتیم با Vector Number معادل 8 که همان بردار Timer/Counter1 Compare Match A است. یک اسم هم گذاشتیم برای تابع وقفه ؛ compare_interrupt که ورودی هم نداره (void). در زیرروال وقفه هم دستور Toggle شدن PORTC.0 میکروکنترلر را نوشتیم.

نوبت میرسه به تابع main :

void main (void){
DDRC |= (1<<);

timer1_configuration ();

while(1){}
}

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

تمام کاری که میخوایم انجام بدیم داخل زیرروال وقفه انجام میشود. بنابراین تنها دلیل ما برای نوشتن این حلقه بینهایت اینه که برنامه تمام نشود و از داخل تابع main بیرون نیاید و برنامه به کار خودش ادامه بدهد.

آموزش کامل سخت افزار CTC

به تصویر زیر که دیتاشیت میکروکنترلر ات مگا 32 است دقت کنید.

آموزش کامل سخت افزار CTC

4 تا از پایه ها یعنی PB3 , PD4 , PD5 , PD7 داخل پرانتزهاشون به ترتیب نوشته شده است : OC0 , OC1B , OC1A , OC2

این پایه ها به پایه های مقایسه گر خروجی یا Output Compare Pins معروف هستند که به تایمر/کانتر 0 ، 1 و 2 مربوط میشوند.

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

رجیستر TCCR1A : Timer/Counter1 Control Register A – TCCR1A

رجیستر TCCR1A : Timer/Counter1 Control Register A - TCCR1A

بیت های 6 و 7 ؛ COM1A1 و COM1A0 :

این بیت ها وظیفه کنترل پایه های OC را بر عهده دارند.

بطور کلی این بیتها برای مود های کاری مختلف، بصورت جداگانه بحث میشوند که در اینجا مد CTC مدنظر ماست. جدول زیر را ببینید :

آموزش کار با مود CTC در تایمر کانتر 1

در اینجا چون خاموش/روشن کردن LED مدنظر ماست از ردیف دوم جدول بالا یعنی حالت 01 استفاده میکنیم. البته دقت داشته باشید که ما اینجا از تایمر/کانتر یک داریم استفاده میکنیم و به همین دلیل هم رفتیم سراغ رجیستر TCCR1A. و اگر میخواستیم از تایمر/کانتر صفر یا دو استفاده کنیم قطعا باید به رجیستر های مربوط به خودشون مراجعه میکردیم.

کد کامل : 

#include <mega32.h>

void timer1_configuration (void){

TCCR1A = (1<<COM1A0); //WGM10 = 0 , WGM11 = 0 , Set OC1A In CTC Toggle Mode
TCCR1B = (1 << WGM12)|(1 << CS11)|(1 << CS10); //Mode = CTC , Prescaler = 64

TCNT1 = ; //initialize timer/counter 1

OCR1A = 24999; //initialize compare value
}

void main (void) {

DDRC |=(1<<);
timer1_configuration ();

while(1) {

}

}

مقدار COM1A0 را 1 کردیم و در نتیجه حالت روشن / خاموش شدن را برای پایه‌ی OC1A فعال کردیم.

یعنی هربار که تایمر/کانتر 1 سرریز شود، با توجه به تنظیماتی که ما برایش انجام دادیم، مقدار پایه‌ی PD5 شروع به روشن و خاموش شدن میکند.

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

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

میخواهید برنامه نویسی STM32 را یاد بگیرید؟

دوره آموزش STM32

میخواهید الکترونیک را یاد بگیرید؟

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

میخواهید آردوینو را به صورت پروژه محور یاد بگیرید؟ برای مشاهده توضیحات روی دوره مورد نظر کلیک کنید

برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام آیرنکس عضو شوید.

محمد رحیمی

محمد رحیمی

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

2 نظر

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

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

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

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