flash讀寫簡(jiǎn)析(以stm32f107vct6為例)
flash作為stm32中的存儲(chǔ)物質(zhì),使用非常廣泛。關(guān)于flash的概念什么的網(wǎng)上已經(jīng)有很多介紹,筆者便不再贅述,分享一篇stm32的閃存中文編程手冊(cè)。
相對(duì)于很多操作寄存器的例子,筆者這篇著重于用庫(kù)函數(shù)處理。
編寫代碼的時(shí)候?qū)嶋H上非常簡(jiǎn)單。只需要幾個(gè)步驟就可以完成寫入。
解鎖
FLASH_Unlock();
這一步非常簡(jiǎn)單。只需要調(diào)用上面的解鎖函數(shù)即可。雖然簡(jiǎn)單,但是不能省略~清除相應(yīng)的標(biāo)志位
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_BSY | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
筆者于頭文件中找到了這幾個(gè)標(biāo)志位于是全部清除。同樣也是不能省略。擦除扇區(qū)
這一步是整個(gè)寫入過程中最為讓人不解的。但是只要搞懂了原理。其實(shí)也不是那么難懂。
flash中有一個(gè)叫扇區(qū)的概念,有的教材也稱為頁(yè)。按照不同容量,flash存儲(chǔ)器組織成32個(gè)1K字節(jié)/頁(yè)(小容量)、 128個(gè)1K字節(jié)/頁(yè)(中容量)、 256個(gè)2K字節(jié)/頁(yè)(大容量)的主存儲(chǔ)器塊和一個(gè)信息塊。
st公司提供的擦除flash扇區(qū)庫(kù)函數(shù),一次至少要擦除一個(gè)扇區(qū)。
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
其中Page_Address是要擦除扇區(qū)的地址,若傳入的不是首地址也會(huì)對(duì)齊到首地址擦除相應(yīng)的一個(gè)扇區(qū)。也就是說我們存在這個(gè)扇區(qū)上的所有東西都會(huì)被清除。如果不清除該扇區(qū),我們是沒有辦法在該扇區(qū)上寫東西的。據(jù)說這樣是因?yàn)橛布O(shè)計(jì)的原因(筆者不是很確定)。
這里就涉及到了一個(gè)可擦除范圍的問題。flash的地址范圍那么大,會(huì)不會(huì)有什么地方是不能擦除的呢。答案是有的。經(jīng)過筆者的實(shí)驗(yàn),筆者的stm32f107vct6的地址范圍是0x08032000~0x0803FFC4。至于為什么不是從flash的起始地址0x08000000開始呢。根據(jù)筆者的查詢,是因?yàn)楸荛_rom開始的位置,不能把正在運(yùn)行的程序給擦除了,至于為什么是在0x0803FFC4結(jié)束,這個(gè)筆者就不是特別明白了,但是總的來說不影響我們的使用。
寫入數(shù)據(jù)
這也是最關(guān)鍵的一步,前面說了半天,都是為這個(gè)做鋪墊。
先介紹一個(gè)字和半字的概念
字(Word): 32位長(zhǎng)的數(shù)據(jù)或指令
半字(Half Word): 16位長(zhǎng)的數(shù)據(jù)或指令
flash的寫入是分字和半字的。
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
根據(jù)所指定的地址,一次只能寫進(jìn)一個(gè)數(shù)據(jù)。
上鎖
最后一步,重新鎖定
FLASH_Lock();
流程圖
解鎖清楚標(biāo)志位擦除寫入上鎖
讀取讀取就更為簡(jiǎn)單了,只需要根據(jù)地址轉(zhuǎn)為指針在轉(zhuǎn)為數(shù)據(jù)即可
pBuf[i] = *((u16*)startAddr + i);