12.1.FMC 基礎知識
閃存控制器(FMC),提供了片上閃存需要的所有功能。FMC 也提供了頁擦除,整片擦除,以及32 位整字或 16 位半字編程閃存等操作。 GD32 MCU 支持不同類型編程的具體說明如下表 GD32 MCU 不同系列編程區(qū)別所示。

12.2.FMC 功能
支持 32 位整字或 16 位半字編程,頁擦除和整片擦除操作;
支持 CPU 執(zhí)行指令零等待區(qū)域(code area)和非零等待區(qū)域(data area); 大小為 16 字節(jié)的可選字節(jié)塊可根據(jù)用戶需求配置;
具有安全保護狀態(tài),可阻止對代碼或數(shù)據(jù)的非法讀訪問;
相關術語說明
GD32F10x 和 F30x 分別有 MD(中容量) 、HD(大容量)、XD(超大容量) 、CL(互聯(lián)型)系列,不同的系列外設資源有差異,使用固件庫(Firmware)也要作相應的選擇和定義。 中容量產(chǎn)品指Flash 容量為小于 256K 字節(jié)的系列;
大容量產(chǎn)品指 Flash 容量為 256K 至 512K 字節(jié)之間的 系列; 超大容量產(chǎn)品指 Flash 容量為 768K 至 3072K 字節(jié)之間的系列。
GD32F10X/F30X 系列容量匯總

不同容量工程選擇說明,固件庫是通過宏定義來區(qū)分的。

不同的系列 MCU flash 架構不一樣,其中 GD32F 系列的 MCU flash 分 code area 和 data area, code area CPU 執(zhí)行指令是零等待, GD32E 系列 flash 不分 code area 和 data are,但都要插入等待周期。 GD32 系列 Code area&Data area 匯總

讀操作 閃存可以像普通存儲空間一樣直接尋址訪問。對閃存取指令和取數(shù)據(jù)分別使用 CPU 的 IBUS 或 DBUS總線。
代碼操作如:
uint32_t readflash[3] readflash [0] = *(__IO uint32_t*)(0x8004000); readflash [1] = *(__IO uint32_t*)((0x8004004); readflash [2] = *(__IO uint32_t*)((0x8004008);
頁擦除
FMC 的頁擦除功能使得主存儲閃存的頁內(nèi)容初始化為高電平。 每一頁都可以被獨立擦除,而不影響其他頁內(nèi)容。
FMC 擦除頁步驟如下:
? 確保 FMC_CTLx 寄存器不處于鎖定狀態(tài);
? 檢查 FMC_STATx 寄存器的 BUSY 位來判定閃存是否正處于擦寫訪問狀態(tài),若 BUSY 位為 1,則需等待該操作結(jié)束, BUSY 位變?yōu)?0;
? 置位 FMC_CTLx 寄存器的 PER 位;
? 將待擦除頁的絕對地址( 0x08XX XXXX)寫到 FMC_ADDRx 寄存器;
? 通過將 FMC_CTLx 寄存器的 START 位置 1 來發(fā)送頁擦除命令到 FMC;
? 等待擦除指令執(zhí)行完畢, FMC_STATx 寄存器的 BUSY 位清 0;
? 如果需要,使用 DBUS 讀并驗證該頁是否擦除成功。

整片擦除
FMC 提供了整片擦除功能可以初始化主存儲閃存塊的內(nèi)容。當設置 MER0 為 1 時,擦除過程僅作用于 Bank0,當設置 MER1 為 1 時,擦除過程僅作用于 Bank1,當設置 MER0 和 MER1 為 1 時,擦除過程作用于整片閃存。
整片擦除操作,寄存器設置具體步驟如下:
? 確保 FMC_CTLx 寄存器不處于鎖定狀態(tài);
? 等待 FMC_STATx 寄存器的 BUSY 位變?yōu)?0;
? 如果單獨擦除 Bank0,置位 FMC_CTL0 寄存器的 MER 位。如果單獨擦除 Bank1,置位 FMC_CTL1 寄存器的 MER 位。如果整片擦除閃存,同時置位 FMC_CTL0 和 FMC_CTL1 寄存器的 MER 位;
? 通過將 FMC_CTLx 寄存器的 START 位置 1 來發(fā)送整片擦除命令到 FMC;
? 等待擦除指令執(zhí)行完畢, FMC_STATx 寄存器的 BUSY 位清 0;
? 如果需要,使用 DBUS 讀并驗證是否擦除成功。

字編程操作
FMC 提供了一個 64 位、32 位整字/16 位半字編程功能,用來修改主存儲閃存塊內(nèi)容。
編程操作使用各寄存器流程如下。
? 確保 FMC_CTLx 寄存器不處于鎖定狀態(tài);
? 等待 FMC_STATx 寄存器的 BUSY 位變?yōu)?0;
? 置位 FMC_CTLx 寄存器的 PG 位;
? DBUS 寫一個 32 位整字/16 位半字到目的絕對地址(0x08XXXXXX);
? 等待編程指令執(zhí)行完畢, FMC_STATx 寄存器的 BUSY 位清 0;
? 如果需要,使用 DBUS 讀并驗證是否編程成功。

可選字節(jié)塊擦除
FMC 提供了一個擦除功能用來初始化閃存中的可選字節(jié)塊。
可選字節(jié)塊擦除過程如下所示。
? 確保 FMC_CTL0 寄存器不處于鎖定狀態(tài);
? 等待 FMC_STAT0 寄存器的 BUSY 位變?yōu)?0;
? 解鎖 FMC_CTL0 寄存器的可選字節(jié)操作位;
? 等待 FMC_CTL0 寄存器的 OBWEN 位置 1;
? 置位 FMC_CTL0 寄存器的 OBER 位;
? 通過將 FMC_CTL0 寄存器的 START 位置 1 來發(fā)送可選字節(jié)塊擦除命令到 FMC;
? 等待擦除指令執(zhí)行完畢, FMC_STAT 寄存器的 BUSY 位清 0;
? 如果需要,使用 DBUS 讀并驗證是否擦除成功。當可選字節(jié)塊擦除成功執(zhí)行, FMC_STAT 寄存器的 ENDF 位置位。若 FMC_CTL0 寄存器的 ENDIE 位被置 1, FMC 將觸發(fā)一個中斷。
可選字節(jié)塊編程
FMC 提供了一個 32 位整字/16 位半字編程功能,可用來修改可選字節(jié)塊內(nèi)容。可選字節(jié)塊共有8 對可選字節(jié)。每對可選字節(jié)的高字節(jié)是低字節(jié)的補。當?shù)妥止?jié)被修改時, FMC 自動生成該選項字節(jié)的高字節(jié)。
字節(jié)塊編程操作過程如下。
? 確保 FMC_CTL0 寄存器不處于鎖定狀態(tài);
? 等待 FMC_STAT0 寄存器的 BUSY 位變?yōu)?0;
? 解鎖 FMC_CTL0 寄存器的可選字節(jié)操作位;
? 等待 FMC_CTL0 寄存器的 OBWEN 位置 1;
? 置位 FMC_CTL0 寄存器的 OBPG 位;
? DBUS 寫一個 32 位整字/16 位半字到目的地址;
? 等待編程指令執(zhí)行完畢, FMC_STAT 寄存器的 BUSY 位清 0;
可選字節(jié)塊說明
每次系統(tǒng)復位后,閃存的可選字節(jié)塊被重加載到 FMC_OBSTAT 和 FMC_WP 寄存器,可選字節(jié)生效。可選字節(jié)的補字節(jié)具體為可選字節(jié)取反。當可選字節(jié)被重裝載時,如果可選字節(jié)的補字節(jié)和可選字節(jié)不匹配, FMC_OBSTAT 寄存器的 OBERR 位將被置 1,可選字節(jié)被強制設置為 0xFF。若可選字節(jié)和其補字節(jié)同為 0xFF,則 OBERR 位不置位。
頁擦除/編程保護
FMC 的頁擦除/編程保護功能可以阻止對閃存的意外操作。當 FMC 對被保護頁進行頁擦除或編程操作時,操作本身無效且 FMC_STAT 寄存器的 WPERR 位將被置 1。如果 WPERR 位被置 1 且 FMC_CTL 寄存器的 ERRIE 位也被置 1 來使能相應的中斷, FMC 將觸發(fā)閃存操作出錯中斷,等待 CPU 處理。配置可選字節(jié)塊的 WP [31:0]某位為 0 可以單獨使能某幾頁的保護功能。如果在可選字節(jié)塊執(zhí)行了擦除操作,所有的閃存頁擦除和編程保護功能都將失效。當可選字節(jié)的 WP 被改變時,需要系統(tǒng)復位使之生效。
12.3.軟件配置說明
FMC 以 Program 配置為例來說明
Demo 一 (flash 編程)
demo 功能說明: MCU 上電啟動后,對 MCU flash 的 0x8004000~ 0x08004800 的 2K 的區(qū)域?qū)?0x01234567 數(shù)據(jù),當編寫錯誤的時候,LED 會亮。
軟件配置步驟如下:
1)配置 led 指示燈;
gd_eval_led_init(LED2); gd_eval_led_init(LED3);
2)進行 page erase
void fmc_erase_pages(void) { uint32_t EraseCounter; fmc_unlock(); //FMC 解鎖 fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR ); //清除標志 for(EraseCounter = 0; EraseCounter < PageNum; EraseCounter++){ fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * EraseCounter)); //page 擦除 fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR ); //清除標志 } fmc_lock(); //FMC 加鎖 }
- page erase 檢查
void fmc_erase_pages_check(void) { uint32_t i; ptrd = (uint32_t *)FMC_WRITE_START_ADDR;//將寫地址賦值指針 for(i = 0; i < WordNum; i++) { if(0xFFFFFFFF != (*ptrd)) //判斷地址是否擦除成功 { lednum = LED2; gd_eval_led_on(lednum); //不成功的時候 LED2 會亮 break; }else { ptrd++; // 指針地址++ 再進行下一個地址判斷 } } }
- flash 編程
void fmc_program(void) { fmc_unlock(); //FMC 解鎖 address = FMC_WRITE_START_ADDR; while(address < FMC_WRITE_END_ADDR){ fmc_word_program(address, data0); //word 編程 address += 4; fmc_flag_clear(FMC_FLAG_BANK0_END | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_PGERR );//清除標志 } fmc_lock(); //FMC 加鎖 }
- 字編程檢查
void fmc_program_check(void) { uint32_t i; ptrd = (uint32_t *)FMC_WRITE_START_ADDR; //將寫地址賦值指針 for(i = 0; i < WordNum; i++) { if((*ptrd) != data0) //判斷寫入的數(shù)據(jù)是否一致 { lednum = LED3; gd_eval_led_on(lednum); //不相等的時候 LED3 會亮 break; }else { ptrd++; // 指針地址++ 再進行下一個地址判斷 } } }
12.4.FMC 使用注意事項
(1)操作 flash 之前需要 fmc_unlock();
(2)flash 編程之前需要 page 擦除;
(3)Page erase 和 program 之前需要先清空標志位;
(4)避免在 erase 或者 program 過程中出現(xiàn)掉電情況,用 flash 作為 eeprom 來用時,需要做好數(shù)據(jù)備份;
(5)在擦除 code data flash 過程中,擦除的優(yōu)先級最高,此時任何中斷都不響應。這時需要注意 MCU 與外界通訊時,數(shù)據(jù)丟失情況。
本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關注聚沃科技官網(wǎng)
-
單片機
+關注
關注
6057文章
44813瀏覽量
644372 -
mcu
+關注
關注
146文章
17699瀏覽量
357857 -
嵌入式
+關注
關注
5122文章
19427瀏覽量
312860 -
FMC
+關注
關注
0文章
98瀏覽量
19944 -
開發(fā)板
+關注
關注
25文章
5379瀏覽量
100699
發(fā)布評論請先 登錄
相關推薦
GD32 MCU移植
GD32的MCU介紹
《GD32 MCU原理及固件庫開發(fā)指南》 + 初讀感悟
《GD32 MCU原理及固件庫開發(fā)指南》+讀后感
兆易創(chuàng)新GD32 MCU選型手冊,適用于GD32全系列MCU
不同型號的GD32 MCU如何區(qū)分?

【GD32 MCU 入門教程】一、GD32 MCU 開發(fā)環(huán)境搭建(1)使用Keil開發(fā)GD32

【GD32 MCU 入門教程】一、GD32 MCU 開發(fā)環(huán)境搭建(2)使用 IAR 開發(fā) GD32

【GD32 MCU 入門教程】一、GD32 MCU 開發(fā)環(huán)境搭建(3)使用 Embedded Builder 開發(fā) GD32

【GD32 MCU 入門教程】二、GD32 MCU 燒錄說明(1)ISP 燒錄

【GD32 MCU 入門教程】GD32 MCU 常見外設介紹(14)RTC 模塊介紹

【GD32 MCU入門教程】GD32 MCU GPIO 結(jié)構與使用注意事項

評論