0

اموزش ميكروكنترلر AVR به زبان ساده(Basic)-قسمت دهم

 
mojehb
mojehb
کاربر برنزی
تاریخ عضویت : آبان 1391 
تعداد پست ها : 25
محل سکونت : اصفهان

اموزش ميكروكنترلر AVR به زبان ساده(Basic)-قسمت دهم
جمعه 3 آذر 1391  7:29 PM

قسمت دهم

1-   سلام خوبي
2-   سلام اي بد نيستيم تو خوبي
1-   قربانت . امروز چه مبحثي رو مي خاي بگي
2-   دستور ROTATE رو اول مي گم بعد مي ريم سر بحث شيرين تايمر كانتر
1-   برو كه رفتيم
2-   دستور ROTATE : توسط اين دستور مي شه بيت ها رو به سمت چپ يا راست ببري كه كاربرد زيادي هم داره مثلا در كنترل استپ موتور . بزار يك مثال بهت بگم تا به اهميت اين دستور پي ببري
فرض كن كه هشتا LED داري و مي خاي اولي روشن بشه بعد از چند ثانيه خاموش بشه و همزمان با خاموش شدنش دومين LED روشن بشه بعد از چند ثانيه خاموش بشه همزمان با خاموش شدنش LED سوم روشن بشه و الي اخر تا اين كه LED هشتم روشن بشه و چند ثانيه روشن بمونه و خاموش بشه و از دوباره LED اول روشن بشه و اين ريتم از دوباره تكرار بشه . خوب اگه ما بخايم اين كار رو انجام بديم بايد از برنامه زير استفاده كنيم در برنامه زير LED ها به پورت A متصل شده اند
Config Porta = Output
Do
Set Porta.0
Waitms 25
Reset Porta.0
Set Porta.1
Waitms 25
Reset Porta.1
Set Porta.2
Waitms 25
Reset Porta.2
Set Porta.3
Waitms 25
Reset Porta.3
Set Porta.4
Waitms 25
Reset Porta.4
Set Porta.5
Waitms 25
Reset Porta.5
Set Porta.6
Waitms 25
Reset Porta.6
Set Porta.7
Waitms 25
Reset Porta.7
Loop
End
برنامه بالا كار مي كنه ولي از نظر من غلط هستش چون كه ما با دستور ROTATE مي تونيم اين كار رو خيلي راحتر انجام بديم و نياز به نوشتن اين همه دستور نيست به مثال زير توجه كن
Config Porta = Output
Dim B As Byte
B = &B10000000
Do
  Rotate B , Right
  Porta = B
   Waitms 100
Loop
End
برنامه بالا همون كار برنامه قبلي رو انجام مي ده مي بيني كه چقدر دستورات كم شد البته من فقط يك مثال زدم كه بايد در مورد ستور هم بهت بگم كه چي به چيه. گفتيم كه يك بايت تشكيل شده است از هشت بيت .ما در اين برنامه يك متغيير به اسم B و از نوع بايت تعريف كرديم . اين بيت ها رو مي تونيم به يك پورت هم ارتباط بديم. حالا بزار بريم سر برنامه بهت مي گم كه چه اتفاقي افتاده .
خط اول ما اومديم پورت A رو به عنوان خروجي تعريف كرديم
خط دوم اومديم يك متغيير از نوع بايت و به اسم B تعريف كرديم
خط سوم با دستور B = &B10000000  كد باينري براي متغيير B انتخاب كرديم اگه توجه كني متوجه ميشي كه اين عدد يك عدد هشت رقمي است يعني هشت بيتي هستش اون يكي كه اول نوشته شده همون منطق يك ديجيتال و اون صفرهايي كه نوشته شده همون منطق صفر ديجيتال هستش . اين دستور يك نوع مقدار دهي به متغيير هستش. توضيحات اين دستور هنوز ادامه داره كه در ادامه توضيح ميدم.
خط بعدي با دستور DO اومدي و ابتداي حلقه رو مشخص كرديم
خط بعدي با دستور ROTATE  B , RIGHT به ميكرو دستور داديم كه بيت هاي متغيير B رو كه در خط قبل توضيح داديم يك گام به سمت راست جلوتر ببر يعني ميشه 01000000 اگه توجه كني متوجه مي شي كه عدد يك 1 يك گام جلو تر رفته البته صفرها هم جلوتر مي رن ولي هيچ بيتي خارج نمي شه و اگه به اخر برسه دوباره دور مي زنه و مياد اول قرار مي گيره.
خط بعد با دستور PORTA = B به ميكرو فرمان داديم كه مقدار بيت هاي متغيير B رو روي پايه هاي پورت A بار گذاري كن . حتما از خود مي پرسي كه يعني چي . خوب الان من بهت مي گم يعني چي . همونطور كه مي دوني هر پورت هشت پايه داره و هر متغيير از نوع بايت هم هشت بيت داره ما اومديم با اين دستوري كه نوشتيم به ترتيب بيت ها رو روي پايه هاي A.0 تا A.7 بار گذاري كرديم در اينجا عدد باينري ما هستش 01000000 پس پايه A.0 ميشه 0 پايه A.1 ميشه 1 پايه A.2 ميشه 0 پايه A.3 ميشه 0 و الي اخر كه بقيه پايه ها هم صفر هستش چون ادامه عدد باينري صفر هستش صفر در اينجا به معني خاموش بودن پايه مورد نظر و يك در اينجا به معني روشن شدن پايه مورد نظر است . پس تا اينجا پايه A.1 ما 1 هستش يعني روشن هستش پس اون LED ي كه به پايه A.1 وصل هستش بايد روشن بشه و تمام LED هاي ديگه خاموش باشه.
خط بعدي با دستور WAITMS 100 يك تاخير صد ميلي ثانيه اي در اجراي برنامه ايچاد كرديم  كه با تغيير اين عدد مي توني سرعت روشن روشن و خاموش بودن LED ها رو تغيير بدي.
خط بعدي با دستور LOOP انتهاي حلقه رو مشخص كرديم كه ميكروكنترلر وقتي به اين دستور مي رسه بر مي گرده و از خط بعدي DO شروع مي كنه به خوندن مجدد دستورات .
خط بعدي نوشتيم END كه برنامه هيچ زمان به END نمي رسه .
گفتيم كه برنامه وقتي به LOOP رسيد بر مي گرده مي ره خط بعدي DO رو مي خونه خط بعدي DO هستش  Rotate B , Right به محض اين كه اين دستور توسط ميكرو خونده شد بيت ها دوباره يك واحد به سمت راست هدايت مي شوند حالا قبلا بيتها بودن 01000000 كه بعد از خونده شدن دستور
Rotate B , Right  يك واحد به سمت راست هدايت مي شن يعني 00100000 اگه توجه كني مي بيني كه اين دفعه بيت سوم از سمت چپ يعني 1  جلوتر رفت اونم به سمت راست
خط بعدي PORTA = B هستش كه قبلا توضيح شو دادم به اين معني هستش كه مقدار فعلي بيت ها رو روي پورت A بارگذاري كن به محض خونده شدن اين دستور ميكرو ميياد اين بيت ها رو به ترتيب از سمت چپ روي پورت A بار گذاري مي كنه اين دفعه بيت سوم از سمت چپ شده 1 و بيت دوم از سمت چپ كه در دفعه قبل 1 بوده شده صفر پس پايه A.1  كه قبلا يك بوده يعني روشن بوده ميشه صفر و پايه A.2 كه قبلا صفر بوده حالا ميشه يك و LED ي كه بهش وصل هستش روشن ميشه
1-   همين جا وايستا كه يك سوال دارم چه اتفاقي افتاد كه بيتي كه قبلا يك بوده شد صفر و بيتي كه قبلا صفر بود شده يك
2-   به دليل همون دستور  Rotate B , Right   كه نوشتيم بوده . ببين ما با اين فرمان به ميكرو دستور داديم كه بيت ها رو يك واحد به سمت راست هدايت كن و از اونجايي هم كه گفتيم بيت ها خارج نميشن و دور مي زنن هر بيتي كه اخر از همه بود و يك واحد به سمت راست هدايت شد بر ميگرده ميره اول.
خوب بزار ادامه تحليل رو بگم:
خط بعدي هستش WAITMS 100 كه قبلا دربارش توضيح كافي داده شد
خط بعدي كه توسط ميكروكنترلر خونده ميشه  LOOP هستش و با خونده شدن اين دستور ميكرو ميپره دوباره مي ره از خط زيري DO شروع مي كنه به خوندن يعني خط  Rotate B , Right و با خونده شدن اين دستور دوباره تمام بيت ها يك واحد به سمت راست هدايت ميشن يعني 00010000 و الي اخر و هي اين برنامه دور مزنه و LED ها يكي پس از ديگري روشن و خاموش مي شه
1-   سوال دارم بعد از اين كه اين 1 به اخر رسيد يعني شد 00000001 و دوباره ميكرو به  دستور
Rotate B , Right   رسيد تكليف اين 1 چي مي شه چون كه بايد يك واحد به سمت راست هدايت بشه
2-   اين كه خيلي راحته خوب 1 دوباره بر مي گرده سر خط يعني 10000000
يكم اين مثال رو دستكاري كن تا همه چيز دستت بياد مثلا در اونجايي كه ما نوشتيم B = &B10000000
مي توني دستكاري كني و يك مقدار ديگه بدي مثلا B = &B 10101010 يا هر چيز ديگه .
خوب رسيديم به مبحث تايمر كانتر در ميكرو كنترلر AVR   :
درمیکرو کنترلر AVR  نهایتا دو سه تا تایمر و کانتر بیشتر نداریم البته در میکروکنترلر نوع
ATMEGA8   چهار تایمر کانتر داریم که در این نوع استسنا هستش
1-   تایمر رو فهمیدم ولی کانتر چی هست
2-   کانتر ( COUNTER ) به معنی شمارنده هستش که در میکروکنترلر هم وظیفه این کانتر شمردن پالس هایی هستش که به ورودیش اعمال میشه که سر فرصت بهم می گم . من اینجا فقط تایمر صفر 0 و تایمر یک 1 رو بهت می گم تایمر 3 هم به کارم نیومده که برم دنبالش به کار توهم نمیاد . این تایمر کانتر صفر و یک دو تا فرق باهم دارن و اون اینه که تایمر کانتر صفر 8 بیتی هسش و تایمر کانتر یک 16 بیتی .
1-   موارد کاربردش کجا هستش
2-   موارد کاربردش ساخت ساعت . شمارنده . فرکانس متر و ...
اول میرم سر تایمر کانتر صفر .ببین یزار یک چیز رو اول بهت بگم که بعضی از دستورات رو نمی شه موشکافی کنیم پس زیاد گیر نده .
1-   باشه
2-   اول تایمر صفر :  برای این که شما بتونی از تایمر کانتر برای زمان های دقیق استفاده کنی مجبوری بری و یک RTC از بازار بخری و وصل کنی به دو تا از پایه های مخصوص میکروکنترلر که بهش بعدا اشاره می کنم . برای ایجاد یک تایم مثلا یک ثانیه ای شما باید ابتدا به میکروکنترلر با دستور پیکره بندی CONFIG حالی کنی که اقای میکروکنترلر من می خام از تایمر صفر شما استفاده کنم . برای ایجای زمان یک ثانیه توسط تایمر صفر به ترتیب زیر باید عمل کنی
اول باید ببینی فرکانس کاری میکروکنترلرت چند هستش که اکثر میکروکنترلرها 8 مگا هستن.
Config Timer0 = Timer , Prescale = 256
Dim A As Byte
Dim B As Byte
Enable Interrupts
Enable Timer0
On Timer0 Show

Do
Loop
End
Show:
Timer0 = 6
Incr A
If A = 125 Then
Incr B
Cls
 Lcd B
Timer0 = 0
A = 0
End If
Return
اين برنامه بايد براي ما يك تايم يك ثانيه ايجاد مي كنه ولي در عمل اين طور نيست وزمان ها بيشتر از يك ثانيه طول مي كشه كه اين مشكل بايك RTC قابل حل هستش.
در خط اول برنامه ما با دستور Config Timer0 = Timer , Prescale = 256  اومديم و تايمر صفر رو براي مد تايمر پيكره بندي كرديم البته با اين دستور  CONFIG  TIMER0 = TIMER  در ادامه همين خط بعد از گذاشتن علامت ,  با دستور   Prescale = 256 اومديم و مقدار فركانس كاري ميكرو رو بر 256 تقسيم كرديم توجه كن كه به جاي اين عدد از اعداد 1 و 8 و 64 و 1024   هم مي توني استفاده كني كه گذاشتن يكي از اين اعداد بعد PRESCALE  اجباري هست با اين كار ما فركانس كاري ميكروكنترلر رو بر 256 تقسمت كرديم  يعني  8000000  / 256 = 31250  خوب حتما از خودت مي پرسي كه ما چرا اين تقسيم رو انجام داديم .بايد بهت بگم كه براي اين كه فركانس يكم كوچيكتر بشه و بتونيم ازش براي ايجاد يك ثانيه استفاده كنيم.
خط دوم اومديم يك متغيير از نوع بايت به نام A تعريف كرديم
خط سوم هم اومديم يك متغيير از نوع بايت به نام B تعريف كرديم كه در ادامه مي گم كه اين متغيير ها رو براي چه كاري هستن .
خط بعدي با دستور ENABLE  INTERRUPTS اومديم وقفه ميكرو كنترلر رو فعال كرديم توجه كن كه ما در ميكرو كنترلر يك وقفه داريم كه انواع مختلف هم داره كه بعدا در بارش توضيح مي دم ولي همين رو بدون كه هر وقت از تايمر و كانتر استفاده مي كني بايد اين دستور رو در اوايل برنامه بزاري تا هر وقت كه وقفه تايمر خورد به ميكرو اعلام بشه كه زمان يك ثانيه شد . در ضمن با دستور
DISABLE  INTERRUPTS هم مي تونيم اين فرمان رو غير فعال كنيم
خط بعد با دستور ENABLE  TIMER0 تايمر 0 رو فعال كرديم . بادستور DISABLE TIMER0 هم مي تونيم اين تايمر 0 رو غير فعال كنيم.
خط بعدي نوشتيم ON  TIMER0 SHOW اين دستور به اين معني هستش كه اگر تايمر صفر سرريز شد بپر برو توي زير برنامه SHOW  . توجه داشته باش كه اين سرريز شدن تايمر به منزله زمان يك ثانيه نيست كه در ادامه ميگم زمان يك ثانيه كي به وجود مياد .
خط بعدي نوشتيم DO  وپايين DO هم نوشتيم LOOP . اين حلقه DO –LOOP رو كه تو حلقه هم خالي گذاشتيم براي اين هستش كه اگه برنامه ديگه اي هم داشتيم بزاريم داخل اين حلقه مثلا شايد ما يك برنامه اي نوشته باشيم كه علاوه بر تايمر يك كيبرد هم در برنامه استفاده كرده باشيم كه برنامه مثلا كيبرد هم داخل اين حلقه بايد نوشته بشه.
در خط بعدي نوشتيم END كه برنامه ما هيچ وقت به اين END نمي رسه
خط بعدي نوشتيم SHOW: كه زير برنام ما رو مشخص كرده كه داخل اين زير برنامه عبارات زير نوشته شده:
اولي دستور داخل اين زيربرنامه هستش TIMER0 = 6  ببين ما گفتيم كه تايمر صفر يك تايمر 8 بيتي هستش يعني يك بايتي خوب يك بايت هم با 255 پر ميشه و با 256 تا هم سرريز ميشه و دوباره صفر ميشه
ما اومديم براي اين كه اين 256 سرراست بشه تايمر صفر رو با 6 تا پر كرديم كه تقسيمات هم اعشاري نشه .
قبل از اين كه بخام خط بعدي يعني INCR A رو توضيح بدم بزار يك چيزي رو اول بگم بعد برم سراغش چون كه به هم ربط دارن . ما يك تقسيم ديگه هم بايد انجام بديم يعني 31250  /  250  = 125 كه حاصل شد 125 اين 250 همون عدد تايمر هستش كه در دستور قبل با فرمان TIMER0  =6  شش واحد بهش اضافه كرده بوديم كه تقسيم ما سرراست بشه نه اين كه اعشاري بشه . حالا ما اين تقسيم رو براي اين انجام داديم كه بفهميم يك متغيير رو چند بار بايد افزايش بده تا تايم يك ثانيه ايجاد بشه  كه در اينجا عدد 125 به دست اومد يعني براي اين كه زمان يك ثانيه ايجاد بشه متغيير ( در اين جا متغيير A ) بايد 125 تا پر بشه  . حالا بريم سر خط دستور بعدي.
خط بعدي نوشتيم INCR A به اين معني كه هر وقت تايمر ما وقفه خورد بياد و يك واحد به اين متغيير A اضافه كنه
خط بعدي نوشتيم IF A = 125 THEN   ما گفتيم كه براي به دست اومدن زمان يك ثانيه طبق تقسيماتي كه انجام داديم متغيير A بايد 125 تا پر بشه براي همين دستور شرط رو نوشتيم كه اگر متغيير A مساوي 125 شد برو دستور شرط رو اجرا كن اين دستور شرط هر چيزي مي تونه باشه مثال برو يك پورت رو يك كن يا اين كه يك واحد به يك متغيير ديگه اضافه كن . يا يك پايه رو صفر كن يا هر چي كه دوست داشتي فقط ما اين جا اومديم و دستورات شرط رو در خط هاي پايين نوشتيم كه دستورات شرطي كه نوشتيم به اين ها هستن :
اولين دستور شرط اين هستش INCR B يعني يك واحد به متغيي B اضافه كن  كه هر دستور ديگه اي هم مي تونستيم بزاريم مثلا اين كه يك پايه رو TOGGLE كن كه ما حال كرديم بعد از يك ثانيه يك متغيير ديگه رو بره اضافه كنه .
دستور شرط بعدي CLS هستش يعني ال سي دي رو پاك كن
دستور شرط بعدي  LCD  B  هستش كه ما  به ميكرو دستور داديم كه مقدار متغيير B رو روي ال سي دي نمايش بده.
دستور شرط بعدي TIMER0 = 0 قرار داديم تا براي شروع مجدد صفر بشه
دستور شرط بعدي A = 0 هستش كه با اين كار مقدار متغيير A رو صفر كرديم تا براي بار بعدي كه مي خاد متغيير رو اضافه كنه دوباره از صفر شروع به اضافه كردن كنه نه اين كه از ادامه 125
خط بعدي END IF هستش كه ما هر وقت دستورات شرط تمام ميشه بايد از اين دستور استفاده كنيم تا ميكرو بفهمه كه دستورات شرط تموم شده . پس از اين كه ميكرو به اين خط رسيد و اين دستور رو خوند هيچ كاري انجام نمي ده و فقط از خط پايين اين دستور شروع به خوندن ادامه برنامه مي كنه
خط اخر نوشتيم RETURN ببين ما براي اين كه دوباره يك تايم يك ثانيه ديگه به وجود بياد مجبوريم كه دوباره برگرديم به اول برنامه در تايمر ها با دستور RETURN اين كار رو انجام مي ديم . و ميكرو ميره به اول برنامه از دوباره روز از نو روزي از نو و اين ايجاد زمان يك ثانيه ادامه داره .
1-   يك سوال اگه ما خاستيم كه يك زمان بيشتر از يك ثانيه ايجاد كنيم مثلا دو ثانيه يا بيشتر بايد چكار كنيم
2-   سوال خوبي كرديم اين كار خيلي راحته  در خطي كه نوشتيم IF A = 125  و اين 125 براي يك ثانيه بود رو دو برابركنيم تا زمان دو ثانيه حاصل شه يعني بزاريم 250   . يك چيز ديگه هم بايد بهت بگم كه اگه زمان بيشتري مثلا از دو ثانيه بيشتر خاستي بايد 125 رو ضرت در اون تايمي كه مي خاي بكني
مثلا زمان سه ثانيه مي خاي  125 * 3 = 375  كه حاصل شد 375 كه اين جا چون متغيير A  فقط تا 255 تا مي تونه پر بشه و با 256 تا سرريز ميشه ما نمي تونيم از اين نوع متغيير استفاده كنيم و مجبوريم از يك متغيير ديگه استفاده كنيم كه از نوع WORD هستش كه ظرفيت خيلي بالا داره . حالا كافيه در اويل برنامه به جاي   دستور DIM A  AS BYTE بنويسيم DIM A AS WORD  و به جاي دستور
IF A = 125    بنويسيم IF A = 375 (البته براي تايم سه ثانيه)
خوب براي امروز ديگه كافيه بقيه باشه براي جلسه بعدي

تشکرات از این پست
دسترسی سریع به انجمن ها