使用STM32內部Flash額外的空間來存儲數據

本次分享關於STM32內部FLASH的筆記。

STM32 芯片內部的 FLASH 存儲器,主要用於存儲我們代碼。如果內部FLASH存儲完我們的代碼還有剩餘的空間,那麼這些剩餘的空間我們就可以利用起來,存儲一些需要掉電保存的數據。

本文以STM32103ZET6為例。STM32103ZET6屬於大容量產品,其閃存模塊組織如下:

使用STM32內部Flash額外的空間來存儲數據

其主存儲器大小為512KB,分為256頁,每頁大小都為2KB。我們的程序一般默認燒寫到第0頁的起始地址(0x08000000)處。當BOOT0引腳和BOOT1引腳都接GND時,就是從這個地址開始運行代碼的。這個地址在keil中可以看到:

使用STM32內部Flash額外的空間來存儲數據

假如我們要下載的程序大小為4.05KB,則第0、1、2頁用於保存我們的程序,我們需要掉電保存的數據只能保存在第3頁至第255頁這一部分空間內。我們最終要下載的程序大小可在工程對應的.map文件中看到。.map文件可以雙擊工程的Target的名字快速打開,如:

使用STM32內部Flash額外的空間來存儲數據

下面對STM32的內部FLASH進行簡單的讀寫測試:

STM32的內部FLASH讀寫測試

過程圖如下(省略異常情況,只考慮成功的情況):

使用STM32內部Flash額外的空間來存儲數據


示例代碼:

本例的關鍵代碼如下:

使用STM32內部Flash額外的空間來存儲數據

(1)進行解鎖操作

STM32 的閃存編程是由內嵌的閃存編程/擦除控制器(FPEC)管理 ,這個模塊包含的寄存器如下:

使用STM32內部Flash額外的空間來存儲數據

STM32 復位後, FPEC 模塊是被保護的, 不能寫入 FLASH_CR 寄存器; 通過寫入特定的序列到 FLASH_KEYR 寄存器可以打開 FPEC 模塊(即寫入 KEY1 和KEY2) , 只有在寫保護被解除後, 我們才能操作相關寄存器。 固件庫中的函數為:

void FLASH_Unlock(void);


(2)擦除將要寫的頁

STM32 的 FLASH 在編程的時候,也必須要求其寫入地址的 FLASH 是被擦除了的(也就是其值必須是 0XFFFF),否則無法寫入,在 FLASH_SR 寄存器的 PGERR 位將得到一個警告。 STM32 的閃存擦除分為兩種:頁擦除和整片擦除。 也就是其最小擦除單位為1頁,儘管你只需往某頁裡寫10個字節數據或者更少的數據,你也必須先擦除該頁(2*1024個字節)。我們這裡使用按頁擦除,固件庫中按頁擦除的函數為:

FLASH_Status FLASH_ErasePage(uint32_t Page_Address);

其返回值為枚舉:

使用STM32內部Flash額外的空間來存儲數據

(3)往上一步擦寫成功的頁寫入數據

STM32 閃存的編程每次必須寫入16 位。雖然固件庫中有如下三個寫操作的函數:

使用STM32內部Flash額外的空間來存儲數據

分別為按字(32bit)寫入、按半字(16bit)寫入、按字節(8bit)寫入函數。32 位字節寫入實際上是寫入的兩次 16 位數據,寫完第一次後地址+2,這與我們前面講解的 STM32 閃存的編程每次必須寫入 16 位並不矛盾。 寫入 8 位實際也是佔用的兩個地址了,跟寫入 16 位基本上沒啥區別。


(4)寫入操作完成後進行上鎖操作

對FLASH進行寫操作完成後要進行上鎖操作,對應的固件庫中函數為:

void FLASH_Lock(void);


(5)讀出數據

固件庫中並沒有與讀操作的函數。讀操作其實就是讀取FLASH某個地址的數據。


(6)對比寫入的數據與讀出的數據是否相等

最後對比我們寫入的數據與讀出的數據是否完全一致,若一致則表明讀寫測試成功,否則失敗。


程序執行結果:

使用STM32內部Flash額外的空間來存儲數據

可見,讀出的數據與寫入的數據一致,表明讀寫測試成功。


最後

STM32的內部FLASH讀寫步驟大致如上,有時候我們還需要封裝一些讀寫函數,但步驟大都如上。寫入數據之前需要先進行擦除操作。以上就是本次的筆記分享,如有錯誤,歡迎指出!




分享到:


相關文章: