الکترونیک، رباتیک و مکانیک

آموزش به زبان بسیار ساده و روان (از صفر تا بینهایت)

الکترونیک، رباتیک و مکانیک

آموزش به زبان بسیار ساده و روان (از صفر تا بینهایت)

الکترونیک، رباتیک و مکانیک

با سلام و عرض ادب خدمت هموطنان عزیز
در این سایت قصد داریم موضوعاتی که در حیطه الکترونیک ،مکانیک و برنامه نویسی ربات ها دارای جذابیت خاصی می باشد رو آموزش بدیم. امیدواریم که با نظرات شما عزیزان شاهد آموزشهای جامعی در این زمینه باشیم.
با تشکر

نویسندگان
پیوندهای روزانه
طبقه بندی موضوعی
آخرین نظرات

جمعه, ۴ دی ۱۳۹۴، ۱۱:۱۱ ق.ظ

۰

 

چهارمین قسمت کارگاه عملی با تشریح برنامه نویسی تایمر/کانتر یک آماده شده است.

 

پس با ما در ادامه مطلب همراه باشید ...

 

 

 

 به نام خدا

سلام

روزهای بهاریتون خوب و خوش...

 

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

 

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

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

پس به گوش و به هوش باشید ... wink

 

کد نویسی به زبان سی در محیط کامپایلر کدویژن :

 

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

 

 #include <mega32.h>

در ابتدای کار،طبق معمول فایل سرآیند مربوط به میکروکنترلر مورد نظرمون که اینجا ATmega32 هست رو اضافه میکنیم.

 

#include <mega32.h>

void timer1_configuration (){}

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

 

#include <mega32.h>

void timer1_configuration (){

TCCR1B |=(1<<CS11); // Prescaler=8
TIMSK |=(1<<TOIE1); // Enable Timer1 Overflow

TCNT1=0; // Initialize Timer/Counter1

#asm ("sei"); // Enable Global Interrupts

}

تموم اون حرفایی که قبلا زدیم رو داریم میاریم رو کامپایلر !

توضیحات رو بصورت کامنت روبروی هر عبارت براتون نوشتم.فکر نکنم مسئله خاصی باشه.

 

بریم سراغ تابع main :

void main(){

DDRB.0 = 1; // Config B.0 As Output Pin
timer1_configuration (); // Load Timer1 Configuration
while(1){} // Loop Forever

}

پین B.0 همون پایه ای هست که میخوایم بهش LED رو وصل کنیم.پس خروجی تعریف میشه !

در خط بعدی،تابع timer1_configuration رو فراخوانی میکنیم،تا تایمر/کانتر شماره یک پیکربندی بشه.

و در پایان،یه حلقه بینهایت تعریف شده که یجورایی برنامه تو این حلقه گیر میکنه و از داخل اون در نمیاد !

 

خب ...

توصیه میکنم که خوندن آموزش رو از همینجا متوقف کنید و برگردید یه نگاه بکنید ببینید اصلا چیکار کردیم و چیکار میخوایم بکنیم ! Cool

 

اگه آماده اید،ادامه میدیم ...

 

یه متغیری تعریف میکنیم از جنس int ، با نام مثلا : overflow

وظیفه این متغیر،شمارش تعداد سرریز های رخ داده است !

یادتونه گفتم طبق فرضیات باید 61 بار سرریز رخ بده تا 2 ثانیه طی بشه ؟!

پس این متغیر میخواد ببینه که، کِی تعداد سرریز ها 61 عدد میشه ؟

 

 #include <mega32.h>

int overflow=0;

این هم از تعریف متغیر از نوع integer با نام overflow و همچنین مقدار اولیه 0.

 

بریم سراغ اصل کار؛

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

 

 در مورد وقفه قبلا جداگانه بحث کردیم :

 

اما درباره برنامه نویسیش نه !

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

 

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

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++; // Increase The Number Of Overflow 

// Check If 2 Sec Passed

if(overflow>=61){ 

PORTB^=(1<<0); // Toggle B.0
overflow=0; // Reset The number Of Overflow

}
}

با هر بار سر ریز شدن،یک واحد به متغیر overflow اضافه میشه.

هنگامیکه تعداد سرریزها 61 (یا احیانا بیشتر از 61) بشه،پین B.0 شروع به Toggle شدن میکنه !

یعنی اگه خاموشه،روشن میشه و اگه روشنه خاموش.

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

 

و در انتها کل کد :

 

#include <mega32.h>

int overflow=0;

void timer1_configuration (){

TCCR1B |=(1<<CS11); // Prescaler=8
TIMSK |=(1<<TOIE1); // Enable Timer1 Overflow

TCNT1=0; // Initialize Timer/Counter1

#asm ("sei"); // Enable Global Interrupts

}

interrupt [10] void timer1_int (){

overflow++; // Increase The Number Of Overflow 

// Check If 2 Sec Passed

if(overflow>=61){ 

PORTB^=(1<<0); // Toggle B.0
overflow=0; // Reset The number Of Overflow

}
}

void main(){
DDRB.0 = 1; // Config B.0 As Output Pin 
timer1_configuration (); // Load Timer1 Configuration 
while(1){} // Loop Forever
}

 

چون دفعه اول بود که از وقفه ها استفاده میکردیم جا داره که یه بار بصورت مختصر بگم چه کارایی دقیقا انجام دادیم :

 

هدف این بود که تاخیری به میزان 2 ثانیه بسازیم.

با محاسباتی که انجام دادیم به این نتیجه رسیدیم که باید حدودا 61 بار سرریز در تایمر/کانتر یک رخ بده تا مدت زمان 2 ثانیه بدست بیاد.

با ایجاد یک تابع با نام timer1_configuration ، پیکربندی تایمر/کانتر یک رو انجام دادیم.

در تابع اصلی main هم،پین B.0 رو خروجی تعریف کردیم و تابع timer1_configuration رو فراخوانی کردیم.

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

منتظر میمونیم تا 2 ثانیه طی بشه !

حالا کِی 2 ثانیه طی میشه ؟! هر وقت تعداد سرریزها 61 تا شد !

پس تایمر/کانتر تا سرریز کرد،چون براش وقفه سرریز رو فعال کردیم،سریع میپره به برنامه زیرروال خودش (timer1_int).

برنامه زیرروال رو انجام میده و پس از اینکه انجام داد،مجددا برمیگرده به محل قبلی(حلقه بینهایت).

دائما طی سیکلهای زمانی مشخص،سرریز انجام میپذیره و برنامه زیرروال مربوطه انجام میشه.

حالا ببینیم زیرروال چی میگه ؟! Undecided

به تایمر/کانتر میگه آقا هروقت سرریز کردی،یه دونه به مقدار متغیر overflow که خودمون تعریفش کردیم و مقدار اولیش رو صفر تعیین کردیم،اضافه کن.

همونطور که گفتم؛دائما سرریز تایمر/کانتر یک انجام میشه و یکی یکی به مقدار متغیر overflow اضافه میشه.

میایم یه شرط هم تعریف میکنیم داخل زیر روال؛هر وقت تعداد این سرریزها 61 یا بیشتر شد(2 ثانیه گذشت !!!)؛پین B.0 رو Toggle کن.

 

 

بعععععله ...

این هم تا اینجای آموزش !

منتظر قسمت های بعدی آموزش باشید...

نظر هم فراموش نشه !

 

بای بای LaughingKiss


منبع : www.noise.blog.ir

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی