本帖最后由 liuje 于 2020-11-7 13:00 编辑
如題, 這兩天測ˋ試模擬EEPROM, 官方範例以及網頁找的資料, 大多都是一整頁(128bytes)讀寫緩存方式.
對於003以及616兩款小內存MCU來說, 極端浪費RAM. 又自己只需要10bytes記憶就足夠了.
就拿先人的代碼做了點小修改. 最多可使用16bytes的記憶. 然後使用16bytes xdata做為緩存(使用xdata最上層的地址空間0xf0~0xff).
只要代碼使用的xdata區不超過240個地址(指N76E616). 應該都可以正常使用. 參考如下 :
叫用方式:
// 使用APROM 18K最上層128bytes(0x4780~0x47ff)
// 地址必須對齊128bytes, 否則無法正常使用, 合法地址如 : 0x4600, 0x4680, 0x4700, 0x4780.....
#define ADDR_BASE 0x4780
#define XDATA_TOP 0xf0 // N76E616 xdata空間為256bytes, 最後16個地址為0xf0~0xff
//#define XDATA_TOP 0x2f0 // N76E003 xdata空間為768bytes, 最後16個地址為0x2f0~0x2ff
uint8_t data;
data = read_APROM_BYTE(ADDR_BASE); // 讀取1個地址
write_DATAFLASH_BYTE(ADDR_BASE, 01); // 寫入特定地址
write_DATAFLASH_BYTE(ADDR_BASE+1, 01); // 寫入特定地址
write_DATAFLASH_BYTE(ADDR_BASE+2, 02); // 寫入特定地址
---------------------------------------------------------------------------------------------------------------------------
另外,在Keil C51的程序優化設置, 必須使用 "等級8" (官方範例代碼也是等級8), 如使用等級9, 則無法使用. 請注意 !
(另附上N76E003可用的Project, 使用xdata最高地址0x2f0~0x2ff共16bytes做為寫入緩存)
/**
* 讀取存儲到APROM的數據
* 模擬EEPROM使用
*/
uint8_t read_APROM_BYTE(uint16_t code *u16_addr)
{
uint8_t rdata;
rdata = *u16_addr>>8;
return rdata;
}
/**
* 寫數據到APROM
* 模擬EEPROM使用
*/
void write_DATAFLASH_BYTE(uint16_t u16_addr,uint8_t u8_data)
{
uint8_t looptmp=0,u8_addrl_r;
uint8_t code *cd_longaddr;
uint8_t xdata *xd_tmp;
//檢查頁起始地址
u8_addrl_r = u16_addr;
if (u8_addrl_r<0x80)
{
u8_addrl_r = 0;
}
else
{
u8_addrl_r = 0x80;
}
// 保存 APROM 數據到 XRAM
// 如是 N76E616, 將佔用xdata 256bytes的最高層16個地址, 即 0xf0 ~ 0xff.
// 如果是76E003, 可修改 : "#define XDATA_TOP 0x2f0" , 將使用xdata 768bytes的最上層16個地址, 即0x2f0 ~ 0x2ff.
xd_tmp = XDATA_TOP;
cd_longaddr = (u16_addr&0xff00)+u8_addrl_r;
while (xd_tmp <= (XDATA_TOP+0x10) ) // 備份原來APROM的資料(16bytes)到xdata緩存
{
*xd_tmp = *cd_longaddr;
looptmp++;
xd_tmp++;
cd_longaddr++;
}
//在 XRAM 中修改數據
u8_addrl_r = u16_addr;
xd_tmp = (u8_addrl_r&0x7f)+XDATA_TOP;
*xd_tmp = u8_data;
//擦除 APROM DATAFLASH 頁(擦除128bytes)
IAPAL = u16_addr;
IAPAH = u16_addr>>8;
IAPFD = 0xFF;
set_IAPEN;
set_APUEN;
IAPCN = 0x22;
set_IAPGO;
//保存修改的 RAM 數據到 APROM DATAFLASH
u8_addrl_r = u16_addr; // 取APROM寫入起始地址低8位
if (u8_addrl_r<0x80)
{
u8_addrl_r =0;
}
else
{
u8_addrl_r = 0x80;
}
xd_tmp = XDATA_TOP;
IAPAL = u8_addrl_r;
IAPAH = u16_addr>>8;
set_IAPEN;
set_APUEN;
IAPCN = 0x21;
while (xd_tmp <= (XDATA_TOP+0x10) ) // 從備份的xdata資料中寫入16bytes到APROM
{
IAPFD = *xd_tmp; //寫數據到IAPFD
set_IAPGO;
IAPAL++;
xd_tmp++;
}
clr_APUEN;
clr_IAPEN;
}
|