这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » MCUFlash与EEPROM使用比较

共2条 1/1 1 跳转至

MCUFlash与EEPROM使用比较

工程师
2022-10-15 23:17:38     打赏

1、概述

ME32x系列是内嵌ARM Cortex M0/M3核的32位微控制器。该系列控制器由敏矽微电子有限公司自主开发,并具有自主知识产权。敏矽微电子的微控制器包括有通用MCU和专用SOC系列,具有非常高的性价比,是MCU产品升级换代和国外产品替代的最佳选择。通用功能有高精度ADCCAN接口,I2S音频接口UART串口,SPI接口,I2C总线接口,看门狗定时器(WDT),通用计数器/定时器。特殊接口包括人机界面控制器(LCD驱动,电容触摸按键)和马达控制功能模块。

EEPROM作为比较廉价和方便数据存储器,被广泛使用并且习惯思维。而MCU Flash与EEPROM相比,除使用方法略有差异外,作为数据存储器,所起的效果是一样的。

2、MCU Flash与EEPROM使用比较


擦除 擦除时间 编程 编程时间 硬件接口 擦写寿命
MCU Flash 扇区为单位擦除,擦除后数据为0xFF 5ms 32位word 编程 7us 通过寄存器接口设置编程,读Flash通过指针直接读 10万次
EEPROM 没有单独擦除功能 - Byte编程 - I2C接口 100万次

3、使用MCU Flash 存储数据举例

以ME32S003系列为例,下面说明如何使用MCU Flash 存储小量的数据(注意,本例重点在探讨实现的一个思路,程序调试请用户自行解决)。

ME32S003系列有32K Flash,我们拿出1K, 即两个扇区来存储数据,在这里约定一个数据存储单元为64 Bytes(包括标志)。

两个扇区有16个存储单元,换句话说,可以存储10万x 16 =160 次数据,远远超过EEPROM的寿命。

所有需要存储数据放在一个数据结构中,方便存储和提取数据:

#defineDATA_AREA_DRESS 62*512 //数据扇区起始地址
#defineDATA_AREA_SIZE 2*512 //两个扇区大小
#defineDATA_UINT_SIZE 64 //每一个存储单元大小,一定要整除扇区大小(512)
#defineDATA_UINT_FLAG
 0x5555AAAAtypedef
 struct {uint32_t flag;uint32_t data1;…}
 data_uint_type;voidflash_erase(uint32_t
 startaddr, uint32_t size){uint32_t 
endaddr;endaddr=startaddr+size;  
   //erase sector    
 while(startaddrADDR = startaddr; // setup addr  
            FMC->CMD = 0x04; //Triggerprogming         

     while ((FMC->CMD &0x100)!=0);        
      startaddr+=512;  

   }return;  }uint8_t flash_word_program(uint32_taddr, uint32_t worddata) //返回一个非0的数据当错误发生时{   
  //program word          
    FMC->ADDR = addr; // set upaddr                 
  FMC->DATA =worddata;           
   FMC->CMD = 0x02; //Triggerprogramming            
  while ((FMC->CMD &0x100)!=0);         
     if (*(uint32_t *)addr== worddata)   
   return 0;else    
  return 1;}data_uint_type* data_area_init(void)//返回一个指向数据单元的指针,空指针表示没有数据
{data_uint_type* ptr;ptr=get_last_data_uint_ptr();if
 (((uint32_t) ptr==DATA_AREA_ADDRESS)&&(ptr->flag!==DATA_UINT_FLAG))
{flash_erase(DATA_AREA_ADDRESS,DATA_AREA_SIZE);ptr= 
null;}}data_uint_type* get_last_data_uint_ptr(void)//返回一个指向数据单元的指针
{uint32_tstartuintaddr,enduintaddr,temp;startuintaddr=
 DATA_AREA_ADDRESS/DATA_UINT_SIZE;enduintaddr= startuintaddr+DATA_AREA_SIZE/
 DATA_UINT_SIZE-1;while(startuintaddr!=enduintaddr){            
  temp= (startuintaddr+ enduintaddr)>1;              
if ((data_uint_type*)(temp* DATA_UINT_SIZE)->flag==DATA_UINT_FLAG)  
                     startuintaddr= temp;     
     else                
enduintaddr= temp}startuintaddr =startuintaddr * DATA_UINT_SIZE;if
 (((data_uint_type*)startuintaddr)->flag!=DATA_UINT_FLAG)return (data_uint_type*) 0;else   
             {                        If (startuintaddr< (DATA_AREA_ADDRESS+DATA_AREA_SIZE))  
                               {                                       
   If  (((data_uint_type*)(startuintaddr+ DATA_UINT_SIZE)->flag==DATA_UINT_FLAG)                                          
return(data_uint_type*)(startuintaddr+ DATA_UINT_SIZE) 
;}elsereturn (data_uint_type*)(startuintaddr) ;}}uint8_tstore_data_uint(data_uint_type* 
sur_data_ptr, data_uint_type* dst_data_ptr) //返回一个非0的数据当错误发生时{   
  uint32_t n,temp0,temp1,temp2,*dataptr;   
  temp1= sizeof(data_uint_type) >>2;if((temp1<<2)!= sizeof(data_uint_type))  
   temp1++;  
   temp2=(uint32_t) dst_data_ptr; 
    dataptr=(uint32_t *) sur_data_ptr;  
   //erase sector  
   if ((DATA_AREA_ADDRESS==temp2)&&(dst_data_ptr->flag==DATA_UINT_FLAG))  
   {              flash_erase(DATA_AREA_ADDRESS, DATA_AREA_SIZE);//erase whole data sectors   
  }     for (n=0;n
系统启动时,先调用data_area_init()函数,返回当前数据单元指针,你可以使用memory copy 复制数据到你的程序中。如果是空指针,你需要对你的数据赋予初值,并把它存储到数据区。




高工
2022-10-16 13:27:23     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]