N76E003模拟EEPROM读取和保存应用配置

N76E003模拟EEPROM读取和保存应用配置

N76E003模拟EEPROM读取和保存应用配置的代码参考了文章:

https://blog.csdn.net/u014798590/article/details/89268198

我在这个文章代码的基础上优化了下空间,同时更方便配置保存。
用法:在结构体store_config_t内添加想要保存的配置即可,由于是整页擦除,为了不丢失其他配置,保存前需要同步整个store_config_t内容,然后再整体保存。
注意STORE_DATA_SIZE的值要大于store_config_t的大小。
读写配置参考test_flash调用方式。


#define DEF_CFG_VAL_U8 0xFF
#define DEF_CFG_VAL_U16 0xFFFF

typedef struct store_config_struct
{
	uint8_t enable;
	uint8_t val_u8;
	int val_s16;
	uint16_t val_u16;
} store_config_t;

int load_config(store_config_t *p_store_cfg);
int save_config(store_config_t *p_store_cfg);

void test_flash(void);
#define FLASH_STORE_ADDR_BASE 0x4700//位于地址末端.4700~47FF共256字节
#define PER_PAGE_SIZE 128

#define EN_OPTIMIZE_XDATA_BUFFER_SIZE
#ifndef EN_OPTIMIZE_XDATA_BUFFER_SIZE
#define STORE_DATA_SIZE 128
#else
#define STORE_DATA_SIZE 16	/*set to sizeof(store_config_t) */
#endif
volatile uint8_t xdata page_buffer[STORE_DATA_SIZE];

uint16_t Read_APROM_WORD(uint16_t *read_addr)
{
	uint16_t rdata;
	uint16_t code *u16_addr = (uint16_t code *)read_addr;
	rdata = *u16_addr;

	return rdata;
}

#ifndef EN_OPTIMIZE_XDATA_BUFFER_SIZE
void Write_DATAFLASH_DATA(uint16_t u16EPAddr,
	uint8_t *src_data_ptr,
	int src_data_len)
{
	uint8_t looptmp=0;
	uint16_t u16_addrl_r;
	uint16_t RAMtmp;

	if (src_data_ptr == NULL || src_data_len <= 0)
	{
#ifdef ERR_MSG
		printf("Write_DATAFLASH_DATA: input error!"CRLF);
#endif
		return;
	}
	if (src_data_len > STORE_DATA_SIZE)
	{
#ifdef ERR_MSG
		printf("Write_DATAFLASH_DATA: input error! data len=%u is too big to save!"CRLF, src_data_len);
#endif
		return;
	}

	//Check page start address
	u16_addrl_r=(u16EPAddr/128)*128;
	//Save APROM data to XRAM0
	#if 0
	for(looptmp=0;looptmp<0x80;looptmp++)
	{
		RAMtmp = Read_APROM_BYTE((uint16_t *)(u16_addrl_r+looptmp));
		page_buffer[looptmp] = RAMtmp & 0xFF;
	}
	#else
	for(looptmp=0; looptmp<PER_PAGE_SIZE; looptmp+=2)
	{
		RAMtmp = Read_APROM_WORD((uint16_t *)(u16_addrl_r+looptmp));
		page_buffer[looptmp] = (RAMtmp >> 8) & 0xFF;
		page_buffer[looptmp+1] = RAMtmp & 0xFF;
	}
	#endif
	// Modify customer data in XRAM
	//page_buffer[u16EPAddr&0x7f] = u8EPData;
	memcpy((page_buffer + (u16EPAddr&0x7f)), (uint8_t *)src_data_ptr, src_data_len);

	//Erase APROM DATAFLASH page
	IAPAL = u16_addrl_r&0xff;
	IAPAH = (u16_addrl_r>>8)&0xff;
	IAPFD = 0xFF;
	set_IAPEN;
	set_APUEN;
	IAPCN = 0x22;
	set_IAPGO;

	//Save changed RAM data to APROM DATAFLASH
	set_IAPEN;
	set_APUEN;
	IAPCN = 0x21;
	for(looptmp=0;looptmp<PER_PAGE_SIZE;looptmp++)
	{
		IAPAL = (u16_addrl_r&0xff)+looptmp;
		IAPAH = (u16_addrl_r>>8)&0xff;
		IAPFD = page_buffer[looptmp];
		set_IAPGO;
	}
	clr_APUEN;
	clr_IAPEN;

}
#else
void Write_DATAFLASH_DATA(uint16_t u16EPAddr,
	uint8_t *src_data_ptr,
	int src_data_len)
{
	uint8_t looptmp=0;
	uint16_t u16_addrl_r;
	uint16_t RAMtmp;

	if (src_data_ptr == NULL || src_data_len <= 0)
	{
#ifdef ERR_MSG
		printf("flashw: input error!"CRLF);
#endif
		return;
	}
	if ((u16EPAddr&0x7f != 0) || (src_data_len > STORE_DATA_SIZE))
	{
#ifdef ERR_MSG
		/*u16EPAddr must start of this page */
		printf("flashw: input error! data len=%u, target addr=0x%X!"CRLF,
			src_data_len, u16EPAddr);
#endif
		return;
	}

	//Check page start address
	u16_addrl_r=(u16EPAddr/128)*128;
	//Save APROM data to XRAM0
	for(looptmp=0; looptmp<STORE_DATA_SIZE; looptmp+=2)
	{
		RAMtmp = Read_APROM_WORD((uint16_t *)(u16_addrl_r+looptmp));
		page_buffer[looptmp] = (RAMtmp >> 8) & 0xFF;
		if ((STORE_DATA_SIZE - 1) != looptmp)
		{
			page_buffer[looptmp+1] = RAMtmp & 0xFF;
		}
	}
	// Modify customer data in XRAM
	memcpy((page_buffer), (uint8_t *)src_data_ptr, src_data_len);

	//Erase APROM DATAFLASH page
	IAPAL = u16_addrl_r&0xff;
	IAPAH = (u16_addrl_r>>8)&0xff;
	IAPFD = 0xFF;
	set_IAPEN;
	set_APUEN;
	IAPCN = 0x22;
	set_IAPGO;

	//Save changed RAM data to APROM DATAFLASH
	set_IAPEN;
	set_APUEN;
	IAPCN = 0x21;
	for(looptmp=0;looptmp<PER_PAGE_SIZE;looptmp++)
	{
		IAPAL = (u16_addrl_r&0xff)+looptmp;
		IAPAH = (u16_addrl_r>>8)&0xff;
		IAPFD = (looptmp < STORE_DATA_SIZE) ? page_buffer[looptmp] : 0xFF;
		set_IAPGO;
	}
	clr_APUEN;
	clr_IAPEN;

}
#endif

void Read_DATAFLASH_DATA(uint16_t u16EPAddr,
	uint8_t *ptr,
	int len)
{
	uint16_t i;
	uint16_t value;

	for (i = 0; i < len; i += 2)
	{
		value = Read_APROM_WORD((uint16_t *)(u16EPAddr + i));
		*(ptr + i) = (value >> 8) & 0xFF;
		if ((len - 1) != i)
		{
			*(ptr + i + 1) = (value) & 0xFF;
		}
	}
}

int load_config(store_config_t *p_store_cfg)
{
	if (!p_store_cfg)
	{
		return -1;
	}

	Read_DATAFLASH_DATA((uint16_t)(FLASH_STORE_ADDR_BASE), (uint8_t *)p_store_cfg, sizeof(store_config_t));
	return 0;
}

int save_config(store_config_t *p_store_cfg)
{
	if (!p_store_cfg)
	{
		return -1;
	}

	Write_DATAFLASH_DATA((uint16_t)(FLASH_STORE_ADDR_BASE), (uint8_t *)p_store_cfg, sizeof(store_config_t));
	return 0;
}

void test_flash(void) 
{
	store_config_t tmp_store_cfg;

	tmp_store_cfg.enable = 89;
	tmp_store_cfg.val_u8 = 0xf1;
	tmp_store_cfg.val_s16 = -1612;
	tmp_store_cfg.val_u16 = 0x2F92;
	save_config(&tmp_store_cfg);
	memset(&tmp_store_cfg, 0, sizeof(store_config_t));
	load_config(&tmp_store_cfg);
	printf("test_flash: 1 the store config EN=%bu, val_u8=0x%bX, temp=(%d, %X)"CRLF,
		tmp_store_cfg.enable, tmp_store_cfg.val_u8,
		tmp_store_cfg.val_s16, tmp_store_cfg.val_u16);

	tmp_store_cfg.enable = 0;
	tmp_store_cfg.val_u8 = 0x12;
	tmp_store_cfg.val_s16 = 0x3789;
	tmp_store_cfg.val_u16 = 0xE2;
	save_config(&tmp_store_cfg);
	memset(&tmp_store_cfg, 0, sizeof(store_config_t));
	load_config(&tmp_store_cfg);
	printf("test_flash: 2 the store config EN=%bu, val_u8=0x%bX, temp=(%X, %X)"CRLF,
		tmp_store_cfg.enable, tmp_store_cfg.val_u8,
		tmp_store_cfg.val_s16, tmp_store_cfg.val_u16);

	tmp_store_cfg.enable = 6;
	tmp_store_cfg.val_u8 = 0xC3;
	tmp_store_cfg.val_s16 = 0xFFFF;
	tmp_store_cfg.val_u16 = 0x3F92;
	save_config(&tmp_store_cfg);
	memset(&tmp_store_cfg, 0, sizeof(store_config_t));
	load_config(&tmp_store_cfg);
	printf("test_flash: 3 the store config EN=%bu, val_u8=0x%bX, temp=(%X, %X)"CRLF,
		tmp_store_cfg.enable, tmp_store_cfg.val_u8,
		tmp_store_cfg.val_s16, tmp_store_cfg.val_u16);

	// reset to default
	tmp_store_cfg.enable = 0;
	tmp_store_cfg.val_u8 = DEF_CFG_VAL_U8;
	tmp_store_cfg.val_s16 = DEF_CFG_VAL_U16;
	tmp_store_cfg.val_u16 = DEF_CFG_VAL_U16;
	save_config(&tmp_store_cfg);

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值