1、概述
ME32x系列是內(nèi)嵌ARM Cortex M0/M3核的32位微控制器。該系列控制器由敏矽微電子有限公司自主開發(fā),并具有自主知識(shí)產(chǎn)權(quán)。敏矽微電子的微控制器包括有通用MCU和專用SOC系列,具有非常高的性價(jià)比,是MCU產(chǎn)品升級(jí)換代和國外產(chǎn)品替代的最佳選擇。通用功能有高精度ADC,CAN接口,I2S音頻接口,UART串口,SPI接口,I2C總線接口,看門狗定時(shí)器(WDT),通用計(jì)數(shù)器/定時(shí)器。特殊接口包括人機(jī)界面控制器(LCD驅(qū)動(dòng),電容觸摸按鍵)和馬達(dá)控制功能模塊。
EEPROM作為比較廉價(jià)和方便數(shù)據(jù)存儲(chǔ)器,被廣泛使用并且習(xí)慣思維。而MCU Flash與EEPROM相比,除使用方法略有差異外,作為數(shù)據(jù)存儲(chǔ)器,所起的效果是一樣的。
2、MCU Flash與EEPROM使用比較
擦除 | 擦除時(shí)間 | 編程 | 編程時(shí)間 | 硬件接口 | 擦寫壽命 | |
MCU Flash | 扇區(qū)為單位擦除,擦除后數(shù)據(jù)為0xFF | 5ms | 32位word編程 | 7us | 通過寄存器接口設(shè)置編程,讀Flash通過指針直接讀 | 10萬次 |
EEPROM | 沒有單獨(dú)擦除功能 | - | Byte編程 | - | I2C接口 | 100萬次 |
3、使用MCU Flash存儲(chǔ)數(shù)據(jù)舉例
以ME32S003系列為例,下面說明如何使用MCU Flash 存儲(chǔ)小量的數(shù)據(jù)(注意,本例重點(diǎn)在探討實(shí)現(xiàn)的一個(gè)思路,程序調(diào)試請(qǐng)用戶自行解決)。
ME32S003系列有32K Flash,我們拿出1K, 即兩個(gè)扇區(qū)來存儲(chǔ)數(shù)據(jù),在這里約定一個(gè)數(shù)據(jù)存儲(chǔ)單元為64 Bytes(包括標(biāo)志)。
兩個(gè)扇區(qū)有16個(gè)存儲(chǔ)單元,換句話說,可以存儲(chǔ)10萬x 16 =160次數(shù)據(jù),遠(yuǎn)遠(yuǎn)超過EEPROM的壽命。
所有需要存儲(chǔ)數(shù)據(jù)放在一個(gè)數(shù)據(jù)結(jié)構(gòu)中,方便存儲(chǔ)和提取數(shù)據(jù):
#defineDATA_AREA_ADDRESS62*512//數(shù)據(jù)扇區(qū)起始地址#defineDATA_AREA_SIZE2*512//兩個(gè)扇區(qū)大小#defineDATA_UINT_SIZE64//每一個(gè)存儲(chǔ)單元大小,一定要整除扇區(qū)大?。?12)#defineDATA_UINT_FLAG0x5555AAAAtypedefstruct{uint32_tflag;uint32_tdata1;…}data_uint_type;voidflash_erase(uint32_tstartaddr,uint32_tsize){uint32_tendaddr;endaddr=startaddr+size;//erasesectorwhile(startaddrADDR=startaddr;//setupaddrFMC->CMD=0x04;//Triggerprogrammingwhile((FMC->CMD&0x100)!=0);startaddr+=512;}return; }uint8_tflash_word_program(uint32_taddr,uint32_tworddata)//返回一個(gè)非0的數(shù)據(jù)當(dāng)錯(cuò)誤發(fā)生時(shí){//programwordFMC->ADDR=addr;//setupaddrFMC->DATA=worddata;FMC->CMD=0x02;//Triggerprogrammingwhile((FMC->CMD&0x100)!=0);if(*(uint32_t*)addr==worddata)return0;elsereturn1;}data_uint_type* data_area_init(void)//返回一個(gè)指向數(shù)據(jù)單元的指針,空指針表示沒有數(shù)據(jù){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)//返回一個(gè)指向數(shù)據(jù)單元的指針{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;elseenduintaddr=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)//返回一個(gè)非0的數(shù)據(jù)當(dāng)錯(cuò)誤發(fā)生時(shí){uint32_tn,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);//erasewholedatasectors}for(n=0;n 系統(tǒng)啟動(dòng)時(shí),先調(diào)用data_area_init()函數(shù),返回當(dāng)前數(shù)據(jù)單元指針,你可以使用memory copy 復(fù)制數(shù)據(jù)到你的程序中。如果是空指針,你需要對(duì)你的數(shù)據(jù)賦予初值,并把它存儲(chǔ)到數(shù)據(jù)區(qū)。
全局變量:
data_uint_typemydata;data_uint_type*dataptr;main(void){…dataptr=data_area_init();//初始化if((uint32_t)dataptr==0)//空指針{//對(duì)mydata賦予初值…//存儲(chǔ)數(shù)據(jù)到Flash 數(shù)據(jù)區(qū)data_ptr=(data_uint_type*)DATA_AREA_ADDRESS;store_data_uint(&mydata,data_ptr);}…//任何時(shí)候,調(diào)用store_data_uint()把mydata數(shù)據(jù)存儲(chǔ)到Flashdata_ptr++;if((uint32_t)data_ptr==DATA_AREA_ADDRESS)data_ptr =(data_uint_type *) DATA_AREA_ADDRESS;store_data_uint(&mydata,data_ptr);…//data_ptr永遠(yuǎn)指向當(dāng)前Flash數(shù)據(jù)…}注意事項(xiàng):
由于mydata的地址是編譯器自動(dòng)設(shè)定的,如果發(fā)生mydata地址不是word對(duì)齊地址,需要手動(dòng)設(shè)置??傊_保mydata地址是word對(duì)齊的。
4、Revision History
Revision Description Date 1.0 Initial Release. July 2019 審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17269瀏覽量
352058 -
FlaSh
+關(guān)注
關(guān)注
10文章
1641瀏覽量
148367 -
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7522瀏覽量
164127 -
EEPROM
+關(guān)注
關(guān)注
9文章
1028瀏覽量
81804
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論