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 0xFFFFtypedef 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_MSGprintf("Write_DATAFLASH_DATA: input error!"CRLF);
#endifreturn;}if (src_data_len > STORE_DATA_SIZE){
#ifdef ERR_MSGprintf("Write_DATAFLASH_DATA: input error! data len=%u is too big to save!"CRLF, src_data_len);
#endifreturn;}//Check page start addressu16_addrl_r=(u16EPAddr/128)*128;//Save APROM data to XRAM0#if 0for(looptmp=0;looptmp<0x80;looptmp++){RAMtmp = Read_APROM_BYTE((uint16_t *)(u16_addrl_r+looptmp));page_buffer[looptmp] = RAMtmp & 0xFF;}#elsefor(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 pageIAPAL = 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 DATAFLASHset_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_MSGprintf("flashw: input error!"CRLF);
#endifreturn;}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);
#endifreturn;}//Check page start addressu16_addrl_r=(u16EPAddr/128)*128;//Save APROM data to XRAM0for(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 XRAMmemcpy((page_buffer), (uint8_t *)src_data_ptr, src_data_len);//Erase APROM DATAFLASH pageIAPAL = 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 DATAFLASHset_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;}
#endifvoid 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 defaulttmp_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);}

N76E003模拟EEPROM读取和保存应用配置相关推荐

  1. I2C软件模拟EEPROM通讯实验

    I2C是一种串行通讯总线,由于只有串行数据线SDA和串行时钟线SCL两个总线而被广泛使用. I2C软件模拟通信的本质是用芯片上任意两个引脚模拟I2C通信,也就是说通过控制任意两个引脚电平的高低变化来模 ...

  2. 单片机成长之路(51基础篇) - 022 N76e003 APROM模拟EEPROM驱动

    N76e003单片机内部没有EEPROM,但是可以使用 APROM模拟EEPROM功能,代码如下: eeprom.h 1 #ifndef _EEPROM_H_ 2 #define _EEPROM_H_ ...

  3. STM32F103C8T6通过内部Flash写入读取数据,模拟EEPROM(附代码)

    STM32F103C8T6通过内部Flash写入读取数据,模拟EEPROM(附代码) 优点: 1. 模块化编程,方便移植,集成度高: 2. 拿来直接用 Flash空间定定义 主函数初始化已经Flash ...

  4. 【正点原子STM32连载】 第四十五章 FLASH模拟EEPROM实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    第四十五章 FLASH模拟EEPROM实验 STM32本身没有自带EEPROM,但是STM32具有IAP(在应用编程)功能,所以我们可以把它的FLASH当成EEPROM来使用.本章,我们将利用STM3 ...

  5. 【正点原子STM32连载】第四十二章 FLASH模拟EEPROM实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  6. freescale S12X微控制器 模拟EEPROM 快速上手指南

    嵌入式开发中常有存储一些下电后不丢失的数据的需求,RAM访问起来很方便,但是下电后数据会丢失,而MC9S12XE提供了D-Flash和EEPROM用于存储非易失性数据.之前一直只是知道这个东西,但是一 ...

  7. STM32使用模拟I2C读取硒翔30mL流量传感器

    使用模拟I2C读取硒翔30mL/min流量传感器 该工程使用某些采样次数和时间不同会采集到的报文有问题. 我建议是可以换个次数和时间调下. 如果报文有问题的话 就修改延时就好了,延时指的是I2C每发送 ...

  8. STM32F10x Flash 模拟 EEPROM

    STM32F10x芯片本身没有集成EEPROM,替代方案是用片上Flash来模拟EEPROM.Flash与EEPROM的区别主要是:一.EEPROM可以按位擦写,而Flash只能按块(页)擦除:二.F ...

  9. FLASH模拟EEPROM编程

    单片机内存FLASH模拟EEPROM编程 一,简述 很多单片机本身是没有自带EEPROM,但是一般具有在应用编程(IAP:In Application Programming)功能,可以把它的内存FL ...

最新文章

  1. 龙俊:活用搜索引擎的搜索指令分析网站
  2. 视野逐渐变暗之跳转场景
  3. 博客园计划增加的功能
  4. 聊聊那些令人惋惜的车模
  5. 原来matplotlib 散点图可以这样
  6. ARM裸机开发环境搭建
  7. C语言删除单链列表中间的节点的算法(附完整源码)
  8. (转)Linux服务器磁盘空间占满问题
  9. C++11并发实战(专栏)
  10. Java Web整合开发(13) -- XML
  11. 如何对第三方数据进行大数据分析
  12. 全局变量的声明和定义 以及dll中全局变量的导出
  13. qt的信号和槽通信机制(当多个窗口之间来回通信[父窗口和子窗口])
  14. excel求回归直线方程的公式_“如何在excel中求解任意直线的方程“excel绘制线性回归方程...
  15. Mac安装brew,安装wget
  16. Linux:使用libgen.h:basename,dirname
  17. 关于企业数字化转型的建议
  18. 解决安装Chrome翻译插件总是报CRX_HEADER_INVALID
  19. 大华技术股份有限公司测开笔试题分享
  20. UVa 10148 - Advertisement

热门文章

  1. 历届NBA总决赛结果
  2. 2021暑假集训-个人赛11
  3. 软件著作权(含源码、说明书、合作协议、以及提交软著的相关注意事项)
  4. 《解忧杂货店》 第一章 回答在牛奶箱里 -- 读后感
  5. 从视频中获取关键帧(I帧)
  6. linux—jock
  7. uniapp 微信小程序实现走势图生成图片分享
  8. IDEA配置SFTP,SSH非常方便的部署以及定位错误日志
  9. QPS和TPS是什么
  10. 十二要素应用宣言(The Twelve-Factor App)