آموزش تایمر کانتر در میکروکنترلر AVR (کامل و جامع)
محتویات
- تایمر کانتر چیست؟
- انواع تایمر کانتر در میکروکنترلر AVR
- مثال مبحث تایمر و کانتر
- تنظیم تایمر/کانتر برای زمان های بالا
- تایمر کانتر صفر در میکروکنترلر AVR
- بررسی کامل تایمر کانتر 0 در میکروکنترلر AVR
- مثال برای فهمیدن تایمر کانتر صفر در AVR
- رجیستر های تایمر صفر در میکروکنترلر AVR
- رجیستر TCNT0
- رجیستر TCCR0
- بیت های 0 و 1 و 2 ؛CS02:00 – Clock Select Bits
- رجیستر TIMSK
- بیت 0 ؛TOIE0 – Timer/Counter0 Overflow Interrupt Enable
- رجیستر TIFR
- بیت 0 ؛ TOV0 : Timer/Counter0 Overflow Flag
- نحوه استفاده از Timer / Counter 0 در میکروکنترلر های AVR
- پروژه AVR برای کار با تایمر / کانتر صفر
- توضیحات کد پروژه
- آموزش کامل Timer / Counter یک در میکروکنترلر AVR
- طرح مسئله برای تایمر / کانتر 1
- حل مسئله
- بررسی رجیستر های تایمر / کانتر یک در AVR
- رجیستر TCCR1B
- رجیستر TCNT1
- رجیستر TIMSK
- رجیستر TIFR
- آموزش کامل کار با تایمر / کانتر یک در AVR
- تعریف زیرروال مربوط به وقفه
- کد کامل استفاده از تایمر / کانتر 1 در کدویژن AVR
- آموزش کامل تایمر کانتر دو در AVR
- تایمر / کانتر 2 چیست ؟
- بررسی رجیسترها
- آموزش کدنویسی تایمر کانتر 2 در کدویژن
سلام. آموزش جامع تایمر / کانتر در میکروکنترلر های AVR را آماده کردیم.
در قسمت قبلی سری آموزش های AVR ، ما مبحث آنالوگ به دیجیتال را به طور کامل مورد بحث قرار دادیم. و در این قسمت میخواهیم با تایمر و کانتر در AVR آشنا شویم.
قسمت قبلی : آموزش کامل مبدل آنالوگ به دیجیتال ADC در میکروکنترلر های AVR
تایمر کانتر چیست؟
در زندگی روزمره ما برنامه ریزی هایی داریم که با توجه به زمان انجام میشوند. یعنی چه کاری را در چه زمانی و به چه مدت انجام میدهیم. وظیفه واحد تایمر/کانتر هم مثل همین کارهاست. در برنامه ای که شما برای میکروکنترلر مینویسید همه زیر نظر واحد Timer/Counter انجام میشود.
بخش تایمر/کانتر از CPU میکروکنترلر جدا است تا محاسبات زمانی دقیق تر انجام شود و تحت تاثیر فعالیت پردازنده میکروکنترلر قرار نگیرد. توجه داشته باشید با این که از CPU جدا است اما پردازنده آن را کنترل میکند.
به تصویر زیر نگاه کنید :
همانطور که میبینید بخش ها از هم جدا هستند و دلیل این جدایی کاهش بار پردازشی CPU میکروکنترلر است. و واحد تایمر / کانتر وظیفه شمارش را بر عهده دارد.
تایمر مانند یک رجیستر است که مقادیر آن به صورت اتوماتیک کم و زیاد میشود. میکروکنترلر AVR دارای تایمر بسیار دقیقی است. نحوه کار تایمر / کانتر به این صورت است که اغلب از صفر شروع میکند به شمارش و ترتیب میشمارد تا به مقدار حداکثری که برای آن تعریف شده است برسد.
بعد از این که به مقدار ماکزیمم رسید Overflow میشود و اعلام مکیند شمارش مورد نظر انجام شده است.
انواع تایمر کانتر در میکروکنترلر AVR
در میکروکنترلرهای AVR دو نوع تایمر/کانتر وجود دارد :
- تایمر/کانتر 8 بیتی
- تایمر/کانتر 16 بیتی
مفهوم 8 بیتی و 16 بیتی را در قسمت قبلی به طور کامل توضیح دادیم. و به طور خلاصه : در نوع 8 بیتی طول داده ها 8 بیت است و در نوع 16 بیتی طول داده ها 16 بیت است.
در تایمر 8 بیتی شمارش از 0 شروع میشود و تا 255 میتواند ادامه پیدا کند. و در تایمر 16 بیتی شمارش از 0 شروع میشود و تا 65535 میتواند ادامه پیدا کند.
با یک مثال بحث را برایتان کامل باز میکنم.
مثال مبحث تایمر و کانتر
فرض کنید یک چراغ چشمک زن داریم. این چراغ به طور متناوب چشمک میزند. خب شیوه کار این چشمک زن چطور است ؟
فرض میکنیم که تاخیر چشمک زن یک ثانیه است. یعنی :
- روشن میشود
- 1 ثانیه روشن میماند
- خاموش میشود
- 1 ثانیه خاموش میماند
>> و تکرار همین 4 مرحله به طور متناوب
خب ما باید این چهار مرجله را به صورت الگوریتم بنویسیم. یعنی :
- روشن شو
- یک ثانیه صبر کن >> تاخیر
- خاموش شو
- یک ثانیه صبر کن >> تاخیر
در مثال بالا با نحوه کار یک چراغ چشمک زن آشنا شدید.
خب حالا بحث را علمی تر میکنیم و به جای 10 ثانیه از 10 میلی ثانیه استفاده میکنیم !
یک فرمول وجود دارد که همه با آن آشنایی دارید اما باز هم دقت کنید به آن :
این فرمول به ما نشان میدهد دوره تناوب با فرکانس رابطه عکس دارد. با فرض اینکه فلاشر دارای تاخیر 10 میلی ثانیه ای باشد، یعنی دوره تناوب آن 10 میلی ثانیه است. یعنی هر 10 میلی ثانیه یک عمل تکرار میشود.
خب با استفاده از فرمول بالا داریم :
یعنی فرکانس فلاشر 100 هرتز است. خب اگر فرکانس کاری میکروکنترلر را روی 4MHz تنظیم کنیم :
با توحه به محاسبه بالا یعنی هر پالس میکروکنترلر 0.00025 میلی ثانیه طول میکشد.حالا تصویر میکنیم که مقدار شمارنده ما 0 است و قرار است شمارش را شروع کند تا به مقدار حداکثر برسد.
وقتی از مقدار 0 به 1 برسد یک پالس اعمال شده است. وقتی از 0 به 2 برسد یک پالس اعمال شده است. و وقتی …
حالا هر پالس ما بر طبق محاسبات بالا 0.00025 ثانیه طول میکشد. یعنی اگر ما بخواهیم زمان بسازیم باید مقدار متناظر آن را به تعداد پالس بدست آوریم. اینجا از فرمول زیر استفاده میکنیم :
TimerCount : تعداد شمارشی که باید تایمر/کانتر انجام دهد.(مجهول)
Duration : مدت زمانی که میخواهیم تایمر/کانتر صرف کند.
Period : دوره تناوبی که بدست آوردیم.
1- : این 1- هم بخاطر این است که شمارش همیشه از 0 شروع میشود نه از 1 .
خب حالا همان مثال 10 میلی ثانیه تاخیر را حل میکنیم. دقت کنید با اینکه 10 میلی ثانیه برای ما بسیااااااار ناچیز است، برای میکروکنترلر بسیاااااار بزرگ است.
اعداد را در فرمول جایگذاری میکنیم :
میبینید که عدد 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.
حالا نتایج را با هم مقایسه کنید.
فرکانس پردازنده =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 است که دارای تایمر/کانتر های زیر است :
- تایمر/کانتر 0 (8 بیتی)
- تایمر/کانتر 1 (16 بیتی)
- تایمر/کانتر 2 (8 بیتی)
در قسمت های بعد راجع به این Timet / Counter ها بحث خواهیم کرد.
سلام. آموزش کامل تایمر / کانتر 0 در میکروکنترلر های AVR (توضیح Timer/Counter صفر) ( آموزش AVR #9) را آماده کردیم.
تایمر کانتر صفر در میکروکنترلر AVR
در قسمت قبلی به طور کلی با نحوه کار تایمر کانتر ها در میروکنترلر های AVR آشنا شدیم. یعنی با فرمول ها و نحوه محاسبه زمان و…
در پایان قسمت قبلی گفتیم که میکروکنترلر مورد نظر ما Atmega32 است و دارای تایمر/کانتر های زیر است :
- تایمر/کانتر 0 (8 بیتی)
- تایمر/کانتر 1 (16 بیتی)
- تایمر/کانتر 2 (8 بیتی)
بررسی کامل تایمر کانتر 0 در میکروکنترلر AVR
خب باید بدانید که تایمر کانتر صفر ، خود نیز سه نوع دارد :
- ساده (8 بیتی) – Atmega8
- پیشرفته (8 بیتی) – Atmega16 , Atmega32
- پیشرفته (16 بیتی) – Attiny13
این تقسیم بندی به صورت کلی است و میکروکنترلر های مختلف دارای خصوصیات مختلف هستند. اما برای بررسی همانطور که گفته شد ما مگا 32 را در نظر میگیریم یعنی نوع “پیشرفته 8 بیتی”.
با یک مثال بحث را شروع میکنیم.
مثال برای فهمیدن تایمر کانتر صفر در AVR
ما قصد داریم یک فلاشر بسازیم که هر 6 میلی ثانیه یکبار چشمک بزند. همچنین فرکانس کالری میکروکنترلر را 32 کیلو هرتز در نظر میگیریم (فرضا*).
این فرکانس برای میکروکنترلر بسیار پایین است و همانطور که میدانید Microcontroller با فرکانس هایی در حدود مگاهرتز کار میکند. اما چون صرفا بحث یادگیریست این فرکانس را پایین در نظر گرفتیم تا ساده تر متوحه شوید.
رجیستر های تایمر صفر در میکروکنترلر AVR
در این قسمت ما رجیستر های مربوط به تایمر کانتر صفر را به طور کامل مورد بررسی قرار میدهیم.
رجیستر TCNT0
همانطور که در تصویر بالا میبینید این رجیستر حاوی مقدار تایمر/کانتر شماره 0 است. مقدار تایمر/کانتر در این رجیستر قرار میگیرد و به صورت اتوماتیک افزایش / کاهش پیدا میکند. این رجیستر به شمارنده 8 بیتی تایمر/کانتر صفر دسترسی مستقیم دارد و هم خواندنی است و هم نوشتنی. هنگام خواندن مقدار شمارش شده را برمیگرداند و به هنگام نوشتن مقدار جدید را به شمارنده انتقال میدهد.
رجیستر TCCR0
در این بخش فقط بیتهای شماره 0 و 1و 2 رو بررسی میکنیم.
بیت های 0 و 1 و 2 ؛CS02:00 – Clock Select Bits
با استفاده از این سه بیت میشود چند کار انجام داد :
- تایمر / کانتر را 0 یا غیرفعال کرد.
- فرکانس پالس تایمر / کانتر را که تقسیم تقسیم فرکانسی از فرکانس اصلی میکروکنترلر است را تعیین کرد.
- میتوان حساسیت timer/counter را به لبه بالا رونده یا پایین رونده اعمالی به پایه T0 را کنترل کرد.
اگر هیچ منبع پالس ساعتی انتخاب نشود، تایمر/کانتر غیر فعال خواهد شد.
چون ما فرکانس کاری میکرو را 32 کیلوهرتز فرض کردیم (در مثال) و این فرکانس، فرکانس مناسبی برای کارکرد تایمر/کانتر هم هست، در نتیجه ما سطر دوم رر انتخاب میکنیم.یعنی نیازی به استفاده از تقسیم فرکانسی نداریم ! (در این مثال***)
رجیستر TIMSK
این رجیستر یک رجیستر مشترک میان تمامی تایمر/کانترها میباشد. برای تایمر/کانتر صفر فقط از بیتهای 0 و 1 آن استفاده میشود و دیگر بیتها مربوط به تایمر/کانترهای دیگر میباشد !
بیت 0 ؛TOIE0 – Timer/Counter0 Overflow Interrupt Enable
با یک شدن این بیت وقفه سرریز تایمر/کانتر صفر فعال خواهد شد. لازم بذکر است که شرط فعال شدن این وقفه آن است که بیت فعال ساز وقفه (I) در رجیستر SREG نیز فعال باشد.
رجیستر TIFR
این رجیستر هم بین تمامی تایمر/کانترها مشترک میباشد. برای تایمر/کانتر صفر فقط از بیتهای 0 و 1 آن استفاده میشود !
بیت 0 ؛ TOV0 : Timer/Counter0 Overflow Flag
این بیت هنگامی که تایمر/کانتر صفر سرریز شود یک میشود و وقتی هنوز زیر روال وقفه در حال انجم است مقدار صفر دارد. اگر هیچ زیر روالی در حال انجام نباشد با نوشتن یک در آن، بصورت دستی میتوان آن را پاک کرد.
در قسمت بعد مبحث وقفه ها را مورد بحث قرار میدهیم.
نحوه استفاده از Timer / Counter 0 در میکروکنترلر های AVR
در قسمت قبلی آموزش AVR ما با استفاده از میکروکنترلر AVR ، آنالوگ به دیجیتال ، سون سگمنت و سنسور LM35 یک دماسنج را ساختیم.
قسمت قبل : آموزش کامل پروژه دماسنج AVR با سنسور LM35 و سون سگمنت
پروژه AVR برای کار با تایمر / کانتر صفر
در این آموزش هم مانند خیلی از آموزش های قبلی ، با ایجاد یک پروژه مطلب را آموزش میدهیم. ما در این پروژه میخواهیم نحوه ساخت یک ال ای دی چشمک زن که هر 8 میلی ثانیه یک بار روشن و خاموش شود را آموزش دهیم.
در این پروژه از کریستال خارجی 16 مگاهرتز و نرم افزار کدویژن استفاده میکنیم. همانطور که قبلا گفتیم با فرکانس کاری 16 مگاهرتز میتوانیم نهایتا 16 میکروثانیه زمان بسازیم.
با توجه به اینکه تایمر / کانتر شماره 0 ، یک تایمر کانتر با دقت 8 بیتی است، حداکثر میتواند تا 255 را بشمارد پس باید حاصل Timer Count ما در محدوده 0 تا 255 قرار بگیرد.
فرمول ها را که یادتان هست ؟
به جدول زیر دقت کنید.
مشاهده میکنید که رنج مورد نظر ما، تنها در ضریب تقسیم 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 |=0; }
میخواهیم ال ای دی را به پایه 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 |=0; } 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
در این قسمت به طور کامل رجیستر های timer / Counter 1 را بررسی میکنیم.
رجیستر TCCR1B
بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS12:0: Clock Select :
از این بیت ها برای تعیین فرکانس تایمر / کانتر 1 یا همان انتخاب ضریب تقسیم استفاده میشود. در اینجا، ضریب تقسیم را 8 انتخاب کردیم، باید مقدار سطر سوم رو انتخاب کنیم (010).
رجیستر TCNT1
مقدار timer / counter 1 در این رجیستر قرار میگیرد. تایمر کانتر 1 ، یک تایمر کانتر 16 بیتی است که از دو رجیستر 8 بیتی در کنار هم تشکیل شده است که با پسوند H و L مشخص شده اند.
رجیستر TIMSK
در مورد این رجیستر هم که قبلا خیلی صحبت کرده ایم. بیت هایی که پس زمینه سفید دارند مربوط به Timer / Counter 1 هستند. در اینجا تنها بیت TOIE1 را استفاده میکنیم که با 1 شدن آن ، وقفه سرریز تایمر / کانتر فعال میشود.
رجیستر 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=0; // Initialize Timer/Counter1 #asm ("sei"); //فعال سازی وقفه های سراسری }
یعنی توضیحاتی را که در قسمت قبل دادیم را وارد محیط کدویژن میکنیم. سپس میرسیم به تابع main.
void main(){ DDRB.0 = 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 هم از روی دیتاشیت نگاه میکنیم و عدد مورد نظر رو انتخاب میکنیم و از آن استفاده میکنیم.
نکته : در داخل براکت به جای عدد، میتوان از عبارت متناظر در ستون 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<<0); // Toggle B.0 overflow=0; // شمارش تعداد Overflow ها } }
با هر بار سر ریز شدن،یک واحد به متغیر overflow اضافه میشود. وقتی که تعداد سرریز ها از 61 یا بیشتر شود ، پین B0 شروع به Toggle میکند.
Toggle شدن = فعال و غیر فعال شدن
در انتها مقدار متغیر overflow را صفر میکنیم تا تایمر/کانتر یک، مجددا اقدام به محاسبه زمان مورد نظر کند.
کد کامل استفاده از تایمر / کانتر 1 در کدویژن AVR
کد کامل این آموزش را در باکس زیر میتوانید مشاهده کنید :
#include <mega32.h> int overflow=0; void timer1_configuration (){ TCCR1B |=(1<<CS11); TIMSK |=(1<<TOIE1); TCNT1=0; #asm ("sei"); } interrupt [10] void timer1_int (){ overflow++; if(overflow>=61){ PORTB^=(1<<0); overflow=0; } } void main(){ DDRB.0 = 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 مگاهرتز استفاده میکنیم.
حل مسئله :
با انتخاب ضریب تقسیم 256،زمان سرریز 4.096 میلی ثانیه میشود. با 12 بار سرریز شدن تایمر/کانتر،و شمرده شدن تا گام 53 در 13 اُمین سرریز مدت زمان 50 میلی ثانیه طی خواهد شد. تمامی صحبتهایی که شد تکراری است و از توضیح مجدد خودداری میکنیم.
بررسی رجیسترها
رجیستر TCCR2 : Timer/Counter2 Control Register
بیت های 0 و 1 و 2 ؛ Bit 2:0 – CS22:0: Clock Select :
از این بیتها استفاده میکنیم برای انتخاب ضریب تقسیم مورد علاقه. ما 256 رو انتخاب میکنیم.
رجیستر TCNT2 : Timer/Counter2
این رجیستر هم مقدار Timer Counterشماره 2 را در خودش نگه میدارد.
رجیستر TIMSK : Timer/Counter-Interrupt Mask-Register
در اینجا تنها بیت TOIE2 مد نظر ماست که با 1 کردن آن وقفه سر ریز تایمر/کانتر 2 فعال میشود.
رجیستر 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=0; #asm ("sei"); overflow = 0; }
این بخش از کد مانند کد های قسمت های قبل است پس از ارائه توضیحات اضافی میگذریم.
سپس به تابع main میرسیم.
void main(){ DDRB.0 = 1; timer2_configuration (); }
پین B0 را به عنوان خروجی (Output) تعریف میکنیم زیرا همان پینی است که ال ای دی به آن متصل میشود. در خط سوم نیز تابع timer2_configuration را فراخوانی میکنیم تا تنظیمات تایمر / کانتر 2 انجام شود.
و سپس :
while(1){ if(overflow>=12){ if(TCNT2>=53){ PORTB.0 ^=(1<<0); // روشن و خاموش کردن ال ای دی TCNT2=0; // ریست کردن تایمر / کانتر overflow=0; // ریست شمارنده 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=0; #asm ("sei"); overflow = 0; } interrupt [TIMER2 OVF] void timer2_isr (void) { overflow++; } while(1){ if(overflow>=12){ if(TCNT2>=53){ PORTB.0 ^=(1<<0); TCNT2=0; overflow=0; } } }
خب این قسمت هم از سری آموزش های میکروکنترلر های AVR تمام شد، در قسمت بعد به طور کامل با مد CTC آشنا میشویم.
قسمت بعد : آموزش مود های مختلف تایمر / کانتر در میکروکنترلر های AVR
درود و عرض ادب
در عین این که سرفصل مهم و گاهی هم گیج کننده است شما بسیار شیوا و ساده بیان کردید
من که خیلی یادگرفتم لطفا همچنان ادامه بدید
سالم و موفق باشید
سلام عزیز
خوشحالم که براتون مفید بوده
میتونید از دوره ای وی آر هم استفاده کنید.
سلام خیلی ممنون از مطلب شما بخش کد نویسی اش برام بهتر جا افتاد.
سلام عزیز
خوشحالم که براتون مفید بوده
سلام و وقت بخیر
من یه مشکلی دارم
چه جوری 1تقسیم بر 4 مگا هرت میشه 0.00025 میلی ثانیه
1تقسیم بر 4000000 میشه 0.00000025
میشه لطفا منو کمک بدین
گیج شدم
سلام عزیز
دقت کنید که عددی که شما بدست آوردید برای ثانیه هست.
زمانی که به میلی ثانیه تبدیل شود یعنی ضرب در 1000 میشود.
ممنونم از شما مرسی
آموزش کد نویسی فرکانس متر دارین تو سایتتون به همین خوبی؟
خواهش میکنم،
در رابطه با فرکانس متر یک آموزش آردوینو موجود هست. جستجو کنید در سایت مشاهده میکنید.
از کلام شیواتون خیلی متشکرم مهندس.
سلام عزیز
خوشحالم که براتون مفید واقع شده
سلام مهندس
واقعا ممنونم از اموزش های مفیدتون
سوالم این هست که در دوره ها چه مطالبی اضافه تر گفته میشه ؟
چون در کتاب های اموزش AVR همین مطالب وجود داره که شما به صورت رایگان قرار میدید و حتی خیلی وقت ها به این شیوایی هم بیان نشده ؛
سلام عزیز
خوشحالم که از مطالب رضایت داشتین، در دوره ها شیوا تر و با جزئیات گفته میشه و عملکرد هر واحد مثلا ADC یا تایمر ها با پروژه های عملی با توضیحات کامل تست میشه.
ممنون از زحماتی که کشیدید ولی جناب رحیمی عزیز آدرس سایت رو که رو عکس رجیستری ها نذار عزیز من !! ادرس سایت اومدی قشنگ رو عکس نوشته ها رجیستری ها گذاشتی خونده نمیشه بعضی جاها!!
سلام عزیز
این اتفاقی بود که در سایت رخ داد و تمامی تصاویر سایت دارای واتر مارک irenx.ir شدند. به زودی تصاویر رو ویرایش میکنیم و بدون آدرس قرار میدیم
با درود
در زبان و فرهنگ ما اگه چیزی انقدر کامل و بدون کم و کاستی بود میگن (سیر کننده و بالاتراز سیر کننده = رفع گرسنگی)
که الان مصداق زحمت و مطالب ارزنده شماست. واقعلا لطف کردید اموزشتون خیلی جامع و کامل بود.خیلی ممنونم.
واقعا جای تقدیر و تشکر دارد.
سلام عزیز
خوشحالم که براتون مفید بوده