N76E003 APROM作为EEPROM使用的问题!
N76E003跟stm8s003相比没有内部的eeprom,有教程通过用APROM分区(0x3800~0x38FF)作为内部eeprom使用;bit BIT_TMP;
/* -------------------------------------------------------------------------*/
/*Dataflash use APROM area */
/* APROM 0x3800~0x38FF demo as dataflash */
/* Please use Memory window key in C:0x3800 to check earse result */
/* -------------------------------------------------------------------------*/
UINT8 read_APROM_BYTE(UINT16 code *u16_addr)
{
UINT8 rdata;
rdata = *u16_addr>>8;
return rdata;
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
/*****************************************************************************************************************
write_DATAFLASH_BYTE :
user can copy all this subroutine into project, then call this function in main.
******************************************************************************************************************/
void write_DATAFLASH_BYTE(UINT16 u16_addr,UINT8 u8_data)
{
UINT8 looptmp=0,u8_addrl_r;
unsigned char code *cd_longaddr;
unsigned char xdata *xd_tmp;
//Check page start address
u8_addrl_r = u16_addr;
if (u8_addrl_r<0x80)
{
u8_addrl_r = 0;
}
else
{
u8_addrl_r = 0x80;
}
//Save APROM data to XRAM
xd_tmp = 0x80;
cd_longaddr = (u16_addr&0xff00)+u8_addrl_r;
while (xd_tmp !=0x100)
{
*xd_tmp = *cd_longaddr;
looptmp++;
xd_tmp++;
cd_longaddr++;
}
// Modify customer data in XRAM
u8_addrl_r = u16_addr;
if (u8_addrl_r<0x80)
{
xd_tmp = u8_addrl_r+0x80;
}
else
{
xd_tmp = u8_addrl_r+0;
}
*xd_tmp = u8_data;
//Erase APROM DATAFLASH page
IAPAL = u16_addr;
IAPAH = u16_addr>>8;
IAPFD = 0xFF;
set_IAPEN;
set_APUEN;
IAPCN = 0x22;
set_IAPGO;
//Save changed RAM data to APROM DATAFLASH
u8_addrl_r = u16_addr;
if (u8_addrl_r<0x80)
{
u8_addrl_r =0;
}
else
{
u8_addrl_r = 0x80;
}
xd_tmp = 0x80;
IAPAL = u8_addrl_r;
IAPAH = u16_addr>>8;
set_IAPEN;
set_APUEN;
IAPCN = 0x21;
while (xd_tmp !=0xFF)
{
IAPFD = *xd_tmp;
set_IAPGO;
IAPAL++;
xd_tmp++;
}
clr_APUEN;
clr_IAPEN;
}
单独的读写验证已经通过,但是当定义如下结构体之后,就无法进行写操作了,
typedef_split3 DisMenu=
{
{13,0x81,0x01},/* 'P' '1.' '1'*/
{13,0x81,0x02},/* 'P' '1.' '2'*/
{13,0x81,0x03},/* 'P' '1.' '3'*/
{13,16,0x02},/* 'P' '-' '2'*/
{13,0x83,0x01},/* 'P' '3.' '1'*/
{13,0x83,0x02},/* 'P' '3.' '2'*/
{13,16,0x04},/* 'P' '-' '4'*/
}; 那就不用结构体吧。 我是最后放弃了这个DEMO的函数,自己根据手册里的程序按自己的需求写了几个API,现在没啥问题。 这个Demo是整页操作的,先把整页的数据保存在Xdata中,然后把要写的数据组合起来,再一次性写入Flash Ray______ 发表于 2017-10-22 15:12
我是最后放弃了这个DEMO的函数,自己根据手册里的程序按自己的需求写了几个API,现在没啥问题。 ...
前辈,弄否分享一下?感觉这个DEMO太吃内存了~ mandey 发表于 2017-10-22 19:17
这个Demo是整页操作的,先把整页的数据保存在Xdata中,然后把要写的数据组合起来,再一次性写入Flash ...
好像是你说的这种操作,Flash必须整页擦除? 90999 发表于 2017-10-22 11:19
那就不用结构体吧。
好像是DEMO Flash操作,太吃内存了,我这边一旦定义比较大的全局变量,就有问题,现在先用code修饰一下 涵潇舒雅 发表于 2017-10-23 09:14
好像是你说的这种操作,Flash必须整页擦除?
擦除肯定是要整页的,所以擦除前要把Flash的数据先保存起来,这样再写进去之前的数据就不会受影响。如果你只是固定位置擦写,不管其他的数据,那就不用那个保存的操作,这样就可以省下128字节的内存。 涵潇舒雅 发表于 2017-10-23 09:13
前辈,弄否分享一下?感觉这个DEMO太吃内存了~
#define PAGE_ERASE_AP 0x22
#define BYTE_PROGRAM_AP 0x21
#define BYTE_READ_AP 0X00
volatile uint8_t code Data_Flash _at_ 0x0200;
uint8_t saveTmp;
/************************************************************************************************************
* 判断是否新片,全FF为新片
* 1:新片 0:用过
************************************************************************************************************/
uint8_t CheckNewChip(void)
{
uint8_t datTmp;
datTmp = Data_Flash;
if(datTmp == 0xff)
return 1;
else
return 0;
return 1;
}
/************************************************************************************************************
* 写一个字节进APROM
************************************************************************************************************/
void APROM_WriteOneByte(uint16_t addr, uint8_t dat)
{
uint8_t offset;
uint8_t i;
offset = addr - START_EEPROM_ADD;
for( i = 0; i < USE_EEPROM_SIZE; i++){saveTmp = Data_Flash; }//Copy data to temp area
saveTmp = dat; //Write data into temp area
set_IAPEN; //Enable IAP mode
set_APUEN; //Enable APROM update
IAPCN = PAGE_ERASE_AP;//Erase page ,128byte of one page
IAPAH = EEPROM_HIGH_ADD;
IAPAL = 0x00;
IAPFD = 0xFF; //Erase
set_IAPGO; //Trigger IAP process
IAPCN = BYTE_PROGRAM_AP;//APROM Byte program
for( i = 0; i < USE_EEPROM_SIZE; i++)//Write data into APROM
{
IAPAH = EEPROM_HIGH_ADD;
IAPAL = i;
IAPFD = saveTmp;
set_IAPGO; //Trigger IAP process
}
clr_APUEN; //Disable APROM update
clr_IAPEN; //Disable IAP mode
}
/************************************************************************************************************
* 写一串数据进APROM
************************************************************************************************************/
void APROM_WriteBuf(uint16_t addr, uint8_t *in, uint8_t len)
{
uint8_t offset;
uint8_t i;
offset = addr - START_EEPROM_ADD;
cpybuf( saveTmp, Data_Flash, USE_EEPROM_SIZE);//Copy data to temp area
cpybuf( saveTmp + offset, in, len); //Copy buff into temp area
set_IAPEN; //Enable IAP mode
set_APUEN; //Enable APROM update
IAPCN = PAGE_ERASE_AP;//Erase page ,128byte of one page
IAPAH = EEPROM_HIGH_ADD;
IAPAL = 0x00;
IAPFD = 0xFF;
set_IAPGO; //Trigger IAP process
IAPCN = BYTE_PROGRAM_AP;//APROM Byte program
for( i = 0; i < USE_EEPROM_SIZE; i++)//Write data into APROM
{
IAPAH = EEPROM_HIGH_ADD;
IAPAL = i;
IAPFD = saveTmp;
set_IAPGO; //Trigger IAP process
}
clr_APUEN; //Disable APROM update
clr_IAPEN; //Disable IAP mode
}
/************************************************************************************************************
* 读APROM一个字节
************************************************************************************************************/
uint8_t Read_APROM_Byte(uint16_t addr)
{
uint8_t dataTmp;
dataTmp = Data_Flash;
return dataTmp;
}
/************************************************************************************************************
* 读APROM连续字节
************************************************************************************************************/
void Read_APROM_Buf(uint16_t addr, uint8_t *out, uint8_t len)
{
uint8_t offset;
offset = addr - START_EEPROM_ADD;
cpybuf( out, &Data_Flash, len);
} Ray______ 发表于 2017-10-23 20:13
有个问题就是按照手册的从0x200开始了,会对应按数据大小生成对应的区域当作EEP用,可以自己选其他的区域,不过读写函数内部有些地址得改下,因为没有用宏做。 记号,谢谢,学习了。 可能会用到,MARK! mark一下,谢谢分享
页:
[1]