راه اندازی EEPROM خارجی

هدف پروژه: آشنایی با رابط استاندارد سریال دو سیمه یا twi یا i2c و ارتباط برقرار کردن میکرو با دنیای خارج. روال کار به این صورت است است که ما توسط این رابط سریال به یک آی سی eeprom خارج از میکرو که پروتکل twi را پشتیبانی می کند، متصل می شویم و در آدرس 0 تا 7 آی سی که 8 بایت است مقدار 0x5f را می ریزیم و سپس این 8 بایت را خوانده و در صورت مغایرت با مقدار ریخته شده، نتیجه لازم را در lcd کاراکتری نمایش می دهیم.

سخت افزار مورد نیاز: در این پروژه از برد آموزشی avr شرکت نامینیک مبتنی بر تراشه ATMEGA32 استفاده می کنیم. رابط twi دو پایه روی میکرو در پین صفر و 1 پورت c دارد که به ترتیب به پایه های 6 و 5 آی سی eeprom (کلاک و دیتا) متصل است. ای سی eeprom موجود در بورد از نوع at24c02 بوده که 2 کیلو بایت حجم دارد. که شرکت سازنده پایداری اطلاعات را تا 40 سال تضمین می کند. ضمن اینکه در این آی سی می توان علاوه بر دسترسی بایتی، صفحه صفحه خواند و نوشت. برای راه اندازی ال سی دی هم روی برد از هدر 16 استفاده می شود.

کتابخانه های استفاده شده: در خطوط 9 تا 12 به ترتیب از کتابخانه های خود میکرو، کتابخانه راه اندازی twi به صورتی که میکرو master باشد، کتابخانه تاخیر ها و در نهایت کتابخانه راه اندازی ال سی دی فراخوانی شده است.

تشریح کد: رابط سریال twi یک رابط سنکرون محسوب می شود. یعنی دیتا با لبه بالا رونده کلاک معتبر است. این استاندارد به این صورت کار می کند که دو سیم به عنوان باس وجود دارد (یکی کلاک و دیگری دیتا) وتا 127 وسیله می توانند مستقیما به این باس وصل شوند. فقط و باید یکی از این ها به عنوان مدیر باس (master) وجود داشته باشد. مدیر باس وظیفه تولید کلاک را بر عهده داشته و اجازه نوشتن یا خواندن را به بقیه می دهد. بقیه پیرو (slave) بوده و باید خود را با کلاک مدیر باس سنکرون کنند و در صورت دیدن آدرس خود روی باس توسط مدیر باس، پاسخ دهند. هر کسی که به باس متصل است باید قبلا یک آدرس یکتا داشته باشد. ارتباط بین دستگاه ها با دستور start توسط مدیر باس شروع می شود. این دستور با یک لبه پایین رونده در باس دیتا هنگامی که باس کلاک 1 است ایجاد می شود و همه می فهمند که باید آماده تبادل اطلاعات باشند. سپس مدیر باس 7 بیت آدرس دستگاهی را که می خواهد با آن ارتباط برقرار کند و یک بیت بعدی که خواندن یا و نوشتن (از/به) دستگاه را مشخص می کند در روی باس دیتا می گذارد (هر بیت یک کلاک می خواهد). هر وسیله ای که آدرسش با این آدرس یکی بود و آماده بود، با صفر کردن بیت نهم پاسخ می دهد. اگر مدیر باس این پاسخ را ببیند به این معناست که وسیله مورد نظر آدرس خود را دیده، و برای خواندن یا نوشتن آماده است. بعد از موفقیت آمیز بودن این مرحله مدیر باس یک بایت اطلاعات را به دستگاه مورد نظر فرستاده یا از آن می خواند. در این مرحله اگر دریافت کننده مدیر باس نباشد، باید با صفر یا رها کردن بیت نهم  موفقیت آمیز بودن ارتباط را اطلاع دهد (هر دو باس دیتا و کلاک پول آپ شده اند یعنی مقدار پیش فرض 1 دارند). اگر مدیر باس بخواهد به فرستادن اطلاعات ادامه دهد باید دوباره یک شرط استارت روی باس ایجاد کند وگرنه با ایجاد شرط stop روی باس اعلام می کند که ارتباط پایان یافته است. شرط stop با یک لبه بالا رونده باس دیتا در هنگامی که باس کلاک 1 است اتفاق می افتد. و اما شرح برنامه.

در خطوط 18 تا 65 برنامه دو تابع تعریف شده است. که توضیحات در برنامه آمده. اما دلیل استفاده از دو شرط استارت در تابع device_read این است که آی سی های سری at24 آدرس آخرین بایتی را که در آن نوشته یا از آن ذخیره می کند را در خود نگه می دارد و هر بار آدرس خودش را روی باس دید دیتای آدرس بعدی را بر می گرداند یا به آدرس بعدی می نویسد. یعنی اگر نگوییم در چه آدرسی باید نوشت یا خواند خود آی سی کار را با آدرس فعلی خود انجام داده و برای خواندن و نوشتن بعدی یک واحد آدرس داخلی خود را اضافه می کند. به دلیل اینکه ما چنین چیزی را نمی خواهیم و می خواهیم هرگاه که خواستیم و در هر خانه ای از حافظه که خواستیم بنویسیم. با شرط استارت اول ابتدا آدرس داخلی آی سی را به آنچه می خواهیم عوض می کنیم و با شرط استارت دوم اطلاعات را از آدرس فعلی می خوانیم. توجه کنید این هیچ ربطی به پروتکل twi ندارد و ساختار آی سی است.

قبلا گفته ایم که سرعت نوشتن در eeprom ها کمی پایین است و نیاز به چند میلی ثانیه زمان دارد و روش ما در برنامه نوشتن بایتی بود. بعنی دو تابعی را که تعریف کردیم برای نوشتن یا خواندن تک بایت از حافظه بود که فقط برای اطلاعات کوچک کاربرد دارد. آی سی های سری at24 این قابلیت را دارد که صفحه صفحه نوشته یا خوانده شوند و در این حالت زمان نوشتن بسیار کمتر از زمان نوشتن همان تعداد بایت  با روش تک بایت تک بایت می شود در این حالت دیگر دو تابعی را که در برنامه نوشتیم معتبر نبوده و باید کمی تغییرات در آن ها بدهیم. ولی در روش صفحه صفحه فقط مجاز به خواندن و نوشتن آدرس های پشت سرهم هستید و تنها می توانید آدرس شروع و پایان را مشخص کنید. برای اطلاعات بیشتر در مورد چگونگی کار و برنامه نویسی آن به دیتاشیت آی سی مراجعه کنید. در تایع main برنامه و در حلقه while اصلی، ابتدا ال سی دی پیغامی را نمایش می دهد مبنی بر اینکه در حال نوشتن 8 بایت است و به مدت 4 ثانیه صبر می کند تا کاربر متوجه شود. بعد این 8 بایتی را که نوشته است می خواند و در صورت مغایرت حتی یکی از این بایت ها با مقدار نوشته شده در ال سی دی پیغام ERROR را نمایش می دهد. اگر همه 8 بایت مغایرتی نداشت، پیغام OK برای کاربر نمایش داده می شود. توجه کنید که ما آدرس ها را پشت سر هم داده ایم که ایرادی ندارد. ولی همانطور که در بالا گفته شد، زمان خواندن و نوشتن بالاتر می رود و این دو تابع برای خواندن و نوشتن پشت سرهم بهینه نیست. در پایان هم در خط 117، برنامه در حلقه while گیر کرده و عملا پایان می یابد.

/*****************************************************
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 <twi.h>
#include <delay.h>
#include <alcd.h>
#include <stdio.h>
 
#define AT24_ADDRESS 0xA0 >> 1
 
void main(void)
{
unsigned char AD_EE[5],result[10];
 
lcd_init(16);   //initiate lcd.
twi_master_init(400);
#asm("sei")
AD_EE[0]=0x01;       //eeprom address.
AD_EE[1]=0x75;       //data that write to address 0x01(above line)
AD_EE[2]=0x57;
 
while (1)
      {
         lcd_clear();
         lcd_gotoxy(0,0);
         lcd_putsf("Writing two     number in EEPROM");
         delay_ms(3000);
         twi_master_trans(AT24_ADDRESS,&AD_EE[0],3,0,0);
         delay_ms(40);
         
         twi_master_trans(AT24_ADDRESS,&AD_EE[0],1,&AD_EE[3],2);
         lcd_clear();
         lcd_gotoxy(0,0);
         switch(twi_result)
         {
            case TWI_RES_OK:
                lcd_putsf("Data readed is:");
                delay_ms(500);
                lcd_gotoxy(0,1);
                sprintf(result,"%d AND %d",AD_EE[3],AD_EE[4]);
                lcd_puts(result);
                break;
            case TWI_RES_BUFFER_OVERFLOW:
                lcd_putsf("Buffer is out of Full!");
                break;
            case TWI_RES_ARBITRATION_LOST:
                lcd_putsf("This Master losts the bus.");
                break;
            case TWI_RES_BUS_ERROR:
                lcd_putsf("BUS ERROR.");
                break;
            case TWI_RES_NACK_RECEIVED:
                lcd_putsf("The Device sends NACK signal.");
                break;
            case TWI_RES_BUS_TIMEOUT:
                lcd_putsf("Device Dosen't reply.");
                break;
            case TWI_RES_FAIL:
                lcd_putsf("TWI BUS can't initialize.");
                break;
            case TWI_RES_UNKNOWN:
                lcd_putsf("Unknown ERROR.");
                break;
            default:
                lcd_putsf("I confused! and don't know about error.");
         }
         
 
         while(1);      //end of 8 byte read/write test.
      }
}

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

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

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

Tags: , ,