سلام
به نظر من اجرای چنین پروژه ای با توجه به وجود تنوع در عناصر ذخیره سازی داده ( حافظه ها ) زیاد قابل توجیح نیست .
معمولا من از حافظه های زیر ذخیره کردن داده استفاده میکنم :
این قطعات به صورت استاندارد برای ذخیره سازی داده استفاده میشن و می شه گفت دیتابیس میکروکنترلر هستند :
1- حافظه های EEPRM سریال ( با پروتکل I2C مثل AT24C512)
2- حافظه های فلش سریال ( با پروتکل SPI مثل AT45DB163 )
3- حافظه های FLASH و EEPROM موازی ( مثل AT28C64 ) .
سایر حافظه ها مثل MMC یا SD یا ... برای ذخیره سازی داده های مهم پیشنهاد نمیشن و استفاده از اونا ممکنه باعث ایجاد خطا بشه ( از بین رفتن داده ، ایجاد خطا در هنگام خوندن یا نوشتن ، در دسترس نبودن ( جدا شدن توسط کاربر از میکروکنترلر ) و ... ) .
تمامی این قطعات دارای پایه ای به نام WP یا Write Protect هستند ، یا صفر یا یک شدن این پایه ، حافظه به حالت فقط خوندنی میره و به نوعی دیتابیس در برابر نوشتن محافظت میشه .
برنامه نویس میتونه با توجه به نوع داده ای که داره ، این حافظه ها رو تقسیم بندی کنه و به هر بخش ، یک نام یا شماره رو اختصاص رو بده .
مثال :
در یک پروژه که از میکروکنترلر AT91SAM7X256 به عنوان کنترل کننده اصلی استفاده شده ، کلیه داده های در یک AT24C512 ذخیره میشن ، در برنامه میکروکنترلر از توابع زیر برای خوندن و نوشتن حافظه استفاده میشه :
کد:
//-----------------------------------------------------------------------------
// reads data from a slave on the TWI bus. An optional
unsigned int Eeprom_Read(
unsigned int iaddress)
{ // Set STOP signal if only one byte is sent
unsigned char Data1,Data2;
unsigned short eedata=0;
AT91C_BASE_TWI->TWI_CR |= AT91C_TWI_STOP;
// Start read
// Set slave address and number of internal address bytes
AT91C_BASE_TWI->TWI_MMR = 0;
AT91C_BASE_TWI->TWI_MMR = (2 << 8) | AT91C_TWI_MREAD | (0x50 << 16);
// Set internal address bytes
AT91C_BASE_TWI->TWI_IADR = 0;
AT91C_BASE_TWI->TWI_IADR = iaddress;
// Send START condition
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
// Read all bytes, setting STOP before the last byte
AT91C_BASE_TWI->TWI_CR |= AT91C_TWI_STOP;
// Wait for byte then read and store it
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY));
Data1 = AT91C_BASE_TWI->TWI_RHR;
// Wait for transfer to be complete
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP) == AT91C_TWI_TXCOMP));
AT91C_BASE_TWI->TWI_IADR = iaddress+1;
// Send START condition
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
// Read all bytes, setting STOP before the last byte
AT91C_BASE_TWI->TWI_CR |= AT91C_TWI_STOP;
// Wait for byte then read and store it
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY));
Data2 = AT91C_BASE_TWI->TWI_RHR;
// Wait for transfer to be complete
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP) == AT91C_TWI_TXCOMP));
eedata=(Data2<<8)|Data1;
return eedata;
}
//------------------------------------------------------------------------------
// sends data to a slave on the TWI bus. An optional callback
unsigned char Eeprom_Write(
unsigned int iaddress,
unsigned int pData)
{
unsigned short temp2;
// Set slave address and number of internal address bytes
AT91C_BASE_TWI->TWI_MMR = 0;
AT91C_BASE_TWI->TWI_MMR = (2 << 8) | (0x50 << 16);
// Set internal address bytes
AT91C_BASE_TWI->TWI_IADR = 0;
AT91C_BASE_TWI->TWI_IADR = iaddress;
minDel();
temp2=(pData<<8);
WRITE_PROTECT=0;
minDel();
// Wait before sending the next byte
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXRDY) == AT91C_TWI_TXRDY));
AT91C_BASE_TWI->TWI_THR = (temp2>>8);
// Wait for transfer to be complete
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP) == AT91C_TWI_TXCOMP));
minDel();
minDel();
minDel();
AT91C_BASE_TWI->TWI_IADR = iaddress+1;
minDel();
// Wait before sending the next byte
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXRDY) == AT91C_TWI_TXRDY));
AT91C_BASE_TWI->TWI_THR =(pData>>8);
// Wait for transfer to be complete
while(!((AT91C_BASE_TWI->TWI_SR & AT91C_TWI_TXCOMP) == AT91C_TWI_TXCOMP));
minDel();
minDel();
minDel();
WRITE_PROTECT=0;
//– In multiple data write operation, when both THR and shift register are empty, a STOP condition is automatically
//sent and we dont need to setd stop bit .
return 0;
}
داده ها که همگی دارای طول 16 بیت هستند ( از 0 تا 65535) در دو بایت از حافظه ی EEPROM ذخیره میشن ، پس برای نوشتن داده کافیه که به صورت زیر عمل بشه :
کد:
Eeprom_Write(154,Cold_overload_I_ib_setting[1]) ;
Eeprom_Write(156,Cold_overload_I_ib_setting[2]) ;
Eeprom_Write(158,Cold_overload_I_ib_setting[3]) ;
Eeprom_Write(160,Cold_overload_I_ib_setting[4]) ;
Eeprom_Write(162,Cold_overload_I_ib_setting[5]) ;
Eeprom_Write(164,Cold_overload_I_ib_setting[6]) ;
Eeprom_Write(166,Cold_overload_I_ib_setting[7]) ;
Eeprom_Write(168,Cold_overload_I_ib_setting[8]) ;
Eeprom_Write(170,Cold_overload_I_ib_setting[9]) ;
Eeprom_Write(172,Cold_overload_I_ib_setting[10]) ;
Eeprom_Write(174,Cold_overload_I_ib_setting[11]) ;
Eeprom_Write(176,Cold_overload_Time_setting[1]) ;
Eeprom_Write(178,Cold_overload_Time_setting[2]) ;
Eeprom_Write(180,Cold_overload_Time_setting[3]) ;
و برای خوندن داده کافیه دستور زیر اجرا بشه :
کد:
VAR=Eeprom_Read(DATA_ID);
همون طور که مشاهده میکنید ، این روش که به صورت معمول در اغلب برنامه ها استفاده میشه ، همون روشی هست که اقای shahin توضیح دادن . به بیان ساده تر در میکروکنترلر به دلیل دسترسی ساده به لایه های سخت افزاری ، امکان خوندن و نوشتن داده میتونه در بالاترین سرعت و با کمترین خطا ، در صورت استفاده از قطعه ی ذخیره ساز استاندارد ( سه مورد ذکر شده ) انجام بشه ؛ در این حالت نیازی به ایجاد توابع سا سخت افزار های اضافه نیست .