一、介紹
首先我們需要了解一個內存映射:
stm32的flash地址起始于0x0800 0000,結束地址是0x0800 0000加上芯片實際的flash大小,不同的芯片flash大小不同。
RAM起始地址是0x2000 0000,結束地址是0x2000 0000加上芯片的RAM大小。不同的芯片RAM也不同。
Flash中的內容一般用來存儲代碼和一些定義為const的數據,斷電不丟失,
RAM可以理解為內存,用來存儲代碼運行時的數據,變量等等。掉電數據丟失。
STM32將外設等都映射為地址的形式,對地址的操作就是對外設的操作。
stm32的外設地址從0x4000 0000開始,可以看到在庫文件中,是通過基于0x4000 0000地址的偏移量來操作寄存器以及外設的。
一般情況下,程序文件是從 0x0800 0000 地址寫入,這個是STM32開始執行的地方,0x0800 0004是STM32的中斷向量表的起始地址。
在使用keil進行編寫程序時,其編程地址的設置一般是這樣的:
程序的寫入地址從0x08000000(數好零的個數)開始的,其大小為0x80000也就是512K的空間,換句話說就是告訴編譯器flash的空間是從0x08000000-0x08080000,RAM的地址從0x20000000開始,大小為0x10000也就是64K的RAM。這與STM32的內存地址映射關系是對應的。
M3復位后,從0x08000004取出復位中斷的地址,并且跳轉到復位中斷程序,中斷執行完之后會跳到我們的main函數,main函數里邊一般是一個死循環,進去后就不會再退出,當有中斷發生的時候,M3將PC指針強制跳轉回中斷向量表,然后根據中斷源進入對應的中斷函數,執行完中斷函數之后,再次返回main函數中。大致的流程就是這樣。
1.1、內部Flash的構成:
STM32F429 的內部 FLASH 包含主存儲器、系統存儲器、 OTP 區域以及選項字節區域,它們的地址分布及大小如下:
STM32F103的中容量內部 FLASH 包含主存儲器、系統存儲器、 OTP 區域以及選項字節區域,它們的地址分布及大小如下:
注意STM32F105VC的是有64K或128頁x2K=256k字節的內置閃存存儲器,用于存放程序和數據。
主存儲器:一般我們說 STM32 內部 FLASH 的時候,都是指這個主存儲器區域它是存儲用戶應用程序的空間,芯片型號說明中的 1M FLASH、 2M FLASH 都是指這個區域的大小。與其它 FLASH 一樣,在寫入數據前,要先按扇區擦除,
系統存儲區:系統存儲區是用戶不能訪問的區域,它在芯片出廠時已經固化了啟動代碼,它負責實現串口、 USB 以及 CAN 等 ISP 燒錄功能。
OTP 區域:OTP(One Time Program),指的是只能寫入一次的存儲區域,容量為 512 字節,寫入后數據就無法再更改, OTP 常用于存儲應用程序的加密密鑰。
選項字節:選項字節用于配置 FLASH 的讀寫保護、電源管理中的 BOR 級別、軟件/硬件看門狗等功能,這部分共 32 字節。可以通過修改 FLASH 的選項控制寄存器修改。
1.2、對內部Flash的寫入過程:
1. 解鎖 (固定的KEY值)
(1) 往 Flash 密鑰寄存器 FLASH_KEYR 中寫入 KEY1 = 0x45670123
(2) 再往 Flash 密鑰寄存器 FLASH_KEYR 中寫入 KEY2 = 0xCDEF89AB
2. 數據操作位數
最大操作位數會影響擦除和寫入的速度,其中 64 位寬度的操作除了配置寄存器位外,還需要在 Vpp 引腳外加一個 8-9V 的電壓源,且其供電間不得超過一小時,否則 FLASH可能損壞,所以 64 位寬度的操作一般是在量產時對 FLASH 寫入應用程序時才使用,大部分應用場合都是用 32 位的寬度。
3. 擦除扇區
在寫入新的數據前,需要先擦除存儲區域, STM32 提供了扇區擦除指令和整個FLASH 擦除(批量擦除)的指令,批量擦除指令僅針對主存儲區。
扇區擦除的過程如下:
(1) 檢查 FLASH_SR 寄存器中的“忙碌寄存器位 BSY”,以確認當前未執行任何
Flash 操作;
(2) 在 FLASH_CR 寄存器中,將“激活扇區擦除寄存器位 SER ”置 1,并設置“扇
區編號寄存器位 SNB”,選擇要擦除的扇區;
(3) 將 FLASH_CR 寄存器中的“開始擦除寄存器位 STRT ”置 1,開始擦除;
(4) 等待 BSY 位被清零時,表示擦除完成。
4. 寫入數據
擦除完畢后即可寫入數據,寫入數據的過程并不是僅僅使用指針向地址賦值,賦值前還還需要配置一系列的寄存器,步驟如下:
(1) 檢查 FLASH_SR 中的 BSY 位,以確認當前未執行任何其它的內部 Flash 操作;
(2) 將 FLASH_CR 寄存器中的 “激活編程寄存器位 PG” 置 1;
(3) 針對所需存儲器地址(主存儲器塊或 OTP 區域內)執行數據寫入操作;
(4) 等待 BSY 位被清零時,表示寫入完成。
1.3、查看工程內存的分布:
由于內部 FLASH 本身存儲有程序數據,若不是有意刪除某段程序代碼,一般不應修改程序空間的內容,所以在使用內部 FLASH 存儲其它數據前需要了解哪一些空間已經寫入了程序代碼,存儲了程序代碼的扇區都不應作任何修改。通過查詢應用程序編譯時產生的“ *.map”后綴文件,
打開 map 文件后,查看文件最后部分的區域,可以看到一段以“ Memory Map of the
image”開頭的記錄(若找不到可用查找功能定位),
【注】ROM加載空間
這一段是某工程的 ROM 存儲器分布映像,在 STM32 芯片中, ROM 區域的內容就是 指存儲到內部 FLASH 的代碼。
在上面 map 文件的描述中,我們了解到加載及執行空間的基地址(Base)都是0x08000000,它正好是 STM32 內部 FLASH 的首地址,即 STM32 的程序存儲空間就直接是執行空間;它們的大小(Size)分別為 0x00000b50 及 0x00000b3c,執行空間的 ROM 比較小的原因就是因為部分 RW-data 類型的變量被拷貝到 RAM 空間了;它們的最大空間(Max)均為 0x00100000,即 1M 字節,它指的是內部 FLASH 的最大空間。
計算程序占用的空間時,需要使用加載區域的大小進行計算,本例子中應用程序使用
的內部 FLASH 是從 0x08000000 至(0x08000000+0x00000b50)地址的空間區域。
所以從扇區 1(地址 0x08004000)后的存儲空間都可以作其它用途,使用這些存儲空間時不會篡改應用程序空間的數據。
具體可參考原子的例程:實驗四十一:FLASH 模擬 EEPROM 實驗
文章引用地址:https://blog.csdn.net/qq_33559992/article/details/77676716
感謝原文作者
二、代碼拆分介紹(以STM32F105系列為例,如上圖表5所示)
2.1 讀/寫入數據流程
寫數據流程
2.1.1、Flash 解鎖,直接調用#include "stm32f10x_flash.h"中的void FLASH_Unlock(void)函數,這個函數是官方提供的
-
寄存器
+關注
關注
31文章
5357瀏覽量
120621 -
FlaSh
+關注
關注
10文章
1638瀏覽量
148178 -
STM32
+關注
關注
2270文章
10906瀏覽量
356530
原文標題:STM32學習筆記:讀寫內部Flash(附代碼)
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論