1、概述
ME32x系列是內(nèi)嵌ARM Cortex? M0/M3核的32位微控制器。該系列控制器由敏矽微電子有限公司自主開發(fā),并具有自主知識(shí)產(chǎn)權(quán)。敏矽微電子的微控制器包括有通用MCU和專用SOC系列,具有非常高的性價(jià)比,是MCU產(chǎn)品升級(jí)換代和國(guó)外產(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 |
通過(guò)寄存器接口設(shè)置編程,讀Flash通過(guò)指針直接讀 |
10萬(wàn)次 |
|
EEPROM |
沒有單獨(dú)擦除功能 |
- |
Byte編程 |
- |
I2C接口 |
100萬(wàn)次 |
3、使用MCU Flash 存儲(chǔ)數(shù)據(jù)舉例
以ME32S003系列為例,下面說(shuō)明如何使用MCU Flash 存儲(chǔ)小量的數(shù)據(jù)(注意,本例重點(diǎn)在探討實(shí)現(xiàn)的一個(gè)思路,程序調(diào)試請(qǐng)用戶自行解決)。
ME32S003系列有32K Flash,我們拿出1K, 即兩個(gè)扇區(qū)來(lái)存儲(chǔ)數(shù)據(jù),在這里約定一個(gè)數(shù)據(jù)存儲(chǔ)單元為64 Bytes(包括標(biāo)志)。
兩個(gè)扇區(qū)有16個(gè)存儲(chǔ)單元,換句話說(shuō),可以存儲(chǔ)10萬(wàn)x 16 =160 次數(shù)據(jù),遠(yuǎn)遠(yuǎn)超過(guò)EEPROM的壽命。
所有需要存儲(chǔ)數(shù)據(jù)放在一個(gè)數(shù)據(jù)結(jié)構(gòu)中,方便存儲(chǔ)和提取數(shù)據(jù):
#defineDATA_AREA_ADDRESS 62*512 //數(shù)據(jù)扇區(qū)起始地址 #defineDATA_AREA_SIZE 2*512 //兩個(gè)扇區(qū)大小 #defineDATA_UINT_SIZE 64 //每一個(gè)存儲(chǔ)單元大小,一定要整除扇區(qū)大?。?12) #defineDATA_UINT_FLAG 0x5555AAAA typedef 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; //Triggerprogramming while ((FMC->CMD 0x100)!=0); startaddr+=512; } return; } uint8_t flash_word_program(uint32_taddr, uint32_t worddata) //返回一個(gè)非0的數(shù)據(jù)當(dāng)錯(cuò)誤發(fā)生時(shí) { //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)//返回一個(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; 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) ; }else return (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_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
系統(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ǔ)到Flash
data_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
來(lái)源:敏矽MCU
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理
審核編輯 黃宇
;n++)>)>
-
mcu
+關(guān)注
關(guān)注
147文章
18925瀏覽量
398108 -
控制器
+關(guān)注
關(guān)注
114文章
17791瀏覽量
193126 -
FlaSh
+關(guān)注
關(guān)注
10文章
1748瀏覽量
155514 -
存儲(chǔ)器
+關(guān)注
關(guān)注
39文章
7739瀏覽量
171662 -
EEPROM
+關(guān)注
關(guān)注
9文章
1137瀏覽量
86030
發(fā)布評(píng)論請(qǐng)先 登錄
如何使用Flash模擬EEPROM存儲(chǔ)參數(shù)
FLASH模擬EEPROM
FLASH模擬EEPROM入門指南
AN0002—AT32 MCU如何使用片上Flash來(lái)實(shí)現(xiàn)EEPROM功能
在AT32系列MCU上Flash模擬EEPRO的應(yīng)用原理和使用方法
STM32 FLASH模擬EEPROM資料
單片機(jī)上FLASH和EEPROM有什么不同?
N76E003的EEPROM問(wèn)題解決方案:使用Data Flash模擬EEPROM
AN0002—AT32 MCU如何使用片上Flash來(lái)實(shí)現(xiàn)EEPROM功能
STM32F103:內(nèi)部Flash模擬EEPROM
如何使用Flash模擬EEPROM存儲(chǔ)參數(shù)?
APM32F4 Flash模擬EEPROM介紹和代碼實(shí)現(xiàn)
使用MCU Flash模擬EEPROM
評(píng)論