راه اندازی EEPROM داخلی AVR

هدف پروژه: توانایی تعریف و استفاده از متغییر های ماندگار با قطع برق در میکرو توسط  کدویژن. روال برنامه به این صورت است که سه پوش باتن داریم و دو عدد led، یکی از پوش باتن ها برای ریست است و هرگاه فشرده شود 2 عدد led خاموش می شوند. دو پوش باتن دیگر هرکدام فشرده شود، led مربوط به آن روشن شده و حتی بعد از قطع و وصل تغذیه یا بعد از ریست میکرو به حالت قبلی بر می گردد. تا اینکه پوش باتن سوم فشرده شود و led ها خاموش شوند. هر led وضعیت روشن یا خاموش بودن خود را نگه می دارد.

سخت افزار مورد استفاده: در این مقاله از برد آموزشی avr شرکت نامینیک مبتنی بر تراشه ATMEGA32 استفاده شده است. و حافظه eeprom یکی از واحد های جانبی درون تراشه است. پوش باتن های شمار s1 الی s3 روی بورد که یک سر مشترک هر سه به پین صفر پورت c و سه سر دیگر به ترتیب به پین های 4 الی 6 پورت c میکرو وصل می شود. برای دو عدد led هم از led های شماره 11 و 12 بورد که به ترتیب به پایه های 2 و 3 پورت c وصل شده است، استفاده می شود.

کتابخانه های استفاده شده: در این جا فقط پورت ها استفاده می شود و خود eeprom در کدویژن کتابخانه ای ندارد. بلکه متغییر هایی از جنس eeprom تعریف می کنیم و در برنامه به کار می بریم. در خط 9 ملزومات شناخت میکرو از جمله پورت ها فراخوانی شده و در خط 10 کتابخانه تاخیر ها استفاده شده است.

تشریح کد: eeprom یک حافظه ماندگار با قابلیت نوشتن و خواندن الکتریکی است. سرعت آن از حافظه های موسوم به flash کمتر است ولی مزیت آن نسبت به این حافظه ها قابلیت دسترسی مستقیم به بایت های آن است. حافظه های فلش به علت تکنولوژی به کار رفته در آن، صفحه صفحه یکجا نوشته یا خوانده می شوند. (معمولا اندازه هر صفحه 512 بایت است) ضمن اینکه حجم حافظه های eeprom هم پایین است. اما هرکدام کاربرد خودش را دارد. در ATMEGA32 یک کیلو بایت حافظه eeprom داخلی داریم. که سازنده تراشه حدود 10 هزار بار نوشتن در آن را قبل از خراب شدن تضمین می کند. (عدد کمی هم نیست) توجه کنید که متغییر های eeprom فقط به صورت سراسری باید تعریف شوند. اما می پردا زیم به کد پروژه.

در خط 12یک بایت بدون علامت از eeprom به نام led_state تعریف شده است. بیت 2 و 3 این متغییر روشن بودن یا نبودن led مربوطه را نشان می دهد. اتصال مشترک پوش باتن ها (پین صفر پورت c) خروجی و صفر تعیین شده و 3 سر دیگر پوش باتن ها (پین های 4 و 5 و 6 پورت c) ورودی با پول آپ داخلی. پین های 2 و 3 پورت c یعنی led ها هم خروجی با مقدار اولیه صفر. در خط 21 مقدار قبلی متغییر led_state با پورت or c  می شود تا در ابتدای برنامه وضعیت قبلی led ها برگردد. ضمنا or شدن برای این است که اگر بقیه پین ها در استفاده های دیگری بود مقدار شان از دست نرود. بایت led_state فقط روی بیت 2 و 3 پورت  c اثر دارد یعنی همان 2 عدد دیود نورانی استفاده شده در این پروژه. خطوط 25 الی 35،خطوط 37 الی 47 و در نهایت خطوط 49 الی 59 برای آشکار شدن فشرده بودن یا نبودن پوش باتن های s1، s2 و s3 است. می توانستیم از یک حلقه while استفاده کنیم. به دو علت این کار را نکردیم. دلیل اول آن است که حلقه while برنامه را منتظر می گذارد تا کلید رها شود. ولی در این روش اگر کد های دیگری در main داشته باشیم می توانند به کار خود ادامه دهند. دلیل دوم این است که با این روش می توان فشرده شدن چند کلید را به طور همزمان و موازی از هم آشکار کرد (البته در این برنامه متغییر ها برای این کار بهینه نیستند مثلا با تعریف یک آرایه می توان همزمانی را مدیریت کرد). به هر حال این دو مزیت همیشه مزیت نبوده و ممکن است در بعضی برنامه ها بر عکس ضرر باشد و حلقه while تنها انتخاب. ضمن اینکه برای این کار حداقل یک متغییر اضافی به فضای حافظه تحمیل شده است. پس انتخاب روش به عهده برنامه نویس است. در صورتی که کاربر دستش را از پوش باتن بردارد، کلید فشرده شده مشخص شده و متغییر led_state و پورت c مقدار دهی می شوند. دقت شود چون نوشتن هر بایت در حافظه eeprom زمان بر است (کمتر از 4 میلی ثانیه)، و خواندن از آن هم به سرعت sram خود میکرو نیست. پس سعی کردیم حداقل میزان نوشتن و خواندن را در eeprom داشته باشیم و بلافاصله بعد از نوشتن از آن نخوانیم و برعکس. ملاحظه عمر eeprom برای کارهای معمولی لازم نیست و حتی برای این کاربرد ها life time محسوب می شود.

/*****************************************************
Chip type               : ATmega32
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/
 
#include <mega32.h>
#include <delay.h>
 
eeprom unsigned char led_state;
 
void main(void)
{
int i=0;
 
PORTC=0x70;      
DDRC=0x0D;           //pins(0,2) defined out with zero value and pins(4,5,6) defined in with pull up.
 
PORTC |=led_state;    
 
while (1)
      {
       if(PINC.4==0)    //mark pin(4) when pushed.
       {
          i=1;
       }
       if(PINC.4==1 && i==1)     //detect pin(4) as a user selected pin when released. 
       {
          i=0;
          led_state |=0x04;
          PORTC |=0x04;
          delay_ms(10);
       }
       
       if(PINC.5==0)
       {
          i=2;
       }
       if(PINC.5==1 && i==2)
       {
          i=0;
          led_state |=0x08;
          PORTC |=0x08;
          delay_ms(10);
       }
       
       if(PINC.6==0)
       {
          i=3;
       }
       if(PINC.6==1 && i==3)
       {
          i=0;
          led_state =0x00;
          PORTC &=0xF3;
          delay_ms(10);
       }
      }//end of while(1).
}

دانلود سورس کد

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

با کلیک بر روی عکس زیر فیلم راه اندازی این پروژه را مشاهده کیند.

 

Tags: ,