
5.1實(shí)驗(yàn)內(nèi)容
通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
- FMC控制器原理;
- FMC擦寫(xiě)讀操作;
5.2實(shí)驗(yàn)原理
5.2.1FMC控制器原理
FMC即Flash控制器,其提供了片上Flash操作所需要的所有功能,在GD32F303系列MCU中,F(xiàn)lash前256K字節(jié)空間內(nèi),CPU執(zhí)行指令零等待,具有相同主頻下最快的代碼執(zhí)行效率。FMC也提供了頁(yè)擦除,整片擦除,以及32位整字/16位半字/位編程等閃存操作。GD32F303系列MCU支持最大3M Flash空間,可以提供業(yè)內(nèi)最大Flash的相關(guān)產(chǎn)品。
GD32F303系列MCU的Flash結(jié)構(gòu)如下圖所示。由該圖可知,GD32F303系列MCU可以支持最大3M的Flash空間,前256頁(yè)為2KB每頁(yè),共512KB空間,后面的空間為4KB每頁(yè),信息塊為存儲(chǔ)內(nèi)部出廠BOOTLOADER,中容量的GD32F303系列產(chǎn)品空間為2KB,大容量的GD32F303系列產(chǎn)品空間為6KB,互聯(lián)型的GD32F305/307系列產(chǎn)品空間為18KB,主要是由于不同的產(chǎn)品所支持的ISP燒錄接口不同,所需要的代碼空間也會(huì)有差別??蛇x字節(jié)塊存儲(chǔ)的是選項(xiàng)字節(jié),其空間大小為16個(gè)字節(jié),地址范圍為0x1FFFF800-0x1FFFF80F,本章主要講解FMC的操作,有關(guān)選項(xiàng)字節(jié)操作可以參考選項(xiàng)字節(jié)操作實(shí)驗(yàn)。

有關(guān)Flash擦寫(xiě)操作均需要先解鎖Flash,然后進(jìn)行擦寫(xiě)操作,擦寫(xiě)完成后再進(jìn)行鎖Flash,注意Flash特性只能由1寫(xiě)0,也就是Flash需要先擦除才能寫(xiě)入新的數(shù)據(jù),如果確保寫(xiě)入地址的數(shù)據(jù)為全0xFF,也可以直接寫(xiě)入。讀取Flash數(shù)據(jù)可以采取直接尋址的方式進(jìn)行讀取。 |
下面為各位讀者介紹Flash擦寫(xiě)讀的相關(guān)操作。
5.2.2Flash擦除操作原理
Flash擦除可分為頁(yè)擦除以及整片擦除,如下圖所示,頁(yè)擦除時(shí)間典型值為48ms,256KB Flash的塊擦除時(shí)間典型值為2S。

有關(guān)Flash的相關(guān)操作均在gd32f30x_fmc.c中實(shí)現(xiàn),下面介紹下擦除實(shí)現(xiàn)的函數(shù),如下表所示。

|
5.2.4Flash讀取操作原理
Flash讀取可以采用直接尋址的方式進(jìn)行操作,具體可參考以下示例代碼。
C uint32_t read_data; read_data = *(uint32_t *)0x08001000;
|
5.3硬件設(shè)計(jì)
本例程不涉及硬件電路。
5.4代碼解析
5.4.1Flash寫(xiě)入16bit雙字節(jié)函數(shù)
Flash寫(xiě)入雙字節(jié)操作函數(shù)如下所示,寫(xiě)入的過(guò)程主要分為擦寫(xiě)兩個(gè)操作,由于Flash特有特性,需要先擦除才可以寫(xiě)入,因而需要確保寫(xiě)入地址的初識(shí)數(shù)據(jù)為0xFF。另外GD32F303具有雙bank,且不同bank的頁(yè)大小具有差異,本函數(shù)可以實(shí)現(xiàn)根據(jù)地址識(shí)別對(duì)應(yīng)頁(yè)并進(jìn)行擦除的功能,使用上非常方便,使用者只需要關(guān)心擦寫(xiě)的起始地址以及數(shù)據(jù)和長(zhǎng)度即可,擦寫(xiě)的位置函數(shù)中會(huì)進(jìn)行實(shí)現(xiàn)。
C void fmc_write_data_16b(uint32_t write_start_addr, uint16_t *data_buf, uint16_t data_lengh) { uint32_t write_addr,erase_addr; uint16_t data_write_num=0; int16_t data_earse_num; /* 解鎖FMC */ fmc_unlock(); /* 清除BANK0和BANK1的錯(cuò)誤標(biāo)志 */ fmc_flag_clear(FMC_FLAG_BANK0_PGERR|FMC_FLAG_BANK0_WPERR|FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK1_PGERR|FMC_FLAG_BANK1_WPERR|FMC_FLAG_BANK1_END); erase_addr = write_start_addr; data_earse_num = data_lengh; /* 若寫(xiě)入起始地址加上總長(zhǎng)*2小于0x08080000,說(shuō)明需要擦寫(xiě)的數(shù)據(jù)均在BANK0,頁(yè)大小為2K/頁(yè) */ if((write_start_addr+data_lengh*2)<0x08080000) { /* 若寫(xiě)入地址為頁(yè)起始地址 */ if(write_start_addr%2048 == 0) { for(;data_earse_num>0;) { fmc_page_erase(erase_addr); erase_addr+=2048; data_earse_num-=1024; } /*若寫(xiě)入地址不是頁(yè)起始地址*/ }else{ for(;(data_earse_num>0||erase_addr>=write_start_addr+data_lengh*2);) { fmc_page_erase(erase_addr); erase_addr+=2048; data_earse_num-=1024; } } /* 若寫(xiě)入地址加上寫(xiě)入長(zhǎng)度*2大于0x08080000,說(shuō)明擦寫(xiě)的數(shù)據(jù)可能跨BANK或者均在BANK1,頁(yè)大小有差別 */ }else{ /* 如果起始地址小于0x08080000,說(shuō)明跨BANK */ if(write_start_addr<0x08080000) { /* 首先擦除BANK0部分所需頁(yè) */ for(;erase_addr<0x08080000;) { fmc_page_erase(erase_addr); erase_addr+=2048; } /* 然后擦除BANK1部分所需頁(yè) */ erase_addr = 0x08080000; for(;erase_addr<=write_start_addr+data_lengh*2;) { fmc_page_erase(erase_addr); erase_addr+=4096; } }else{ /*若寫(xiě)入地址大于等于0x08080000,說(shuō)明均在BANK1,頁(yè)大小為4K/頁(yè)*/ if(write_start_addr%4096 == 0) /* 若寫(xiě)入地址為頁(yè)起始地址 */ { for(;data_earse_num>0;) { fmc_page_erase(erase_addr); erase_addr+=4096; data_earse_num-=2048; } }else{ /*若寫(xiě)入地址不是頁(yè)起始地址*/ for(;(data_earse_num>0||erase_addr>=write_start_addr+data_lengh*2);) { fmc_page_erase(erase_addr); erase_addr+=4096; data_earse_num-=2048; } } } } /* 寫(xiě)入數(shù)據(jù) */ write_addr = write_start_addr; for(data_write_num = 0; data_write_num
5.4.2Flash讀取數(shù)據(jù)函數(shù)
Flash讀取數(shù)據(jù)函數(shù)如下所示,采用直接尋址的方式,讀取雙字節(jié)數(shù)據(jù)。
C uint16_t fmc_read_data_16b(uint32_t write_read_addr) { return *(uint16_t *)write_read_addr; }
5.4.3主函數(shù)
主函數(shù)如下所示,通過(guò)該函數(shù)實(shí)現(xiàn)對(duì)flash起始地址為0x08001000的前20個(gè)字節(jié)擦寫(xiě)以及讀取的驗(yàn)證。
C int main(void) { uint16_t read_num =0; uint8_t i_num; bsp_led_group_init(); fmc_write_data_16b(WRITE_START_ADDR,write_data,10); for(read_num=0;read_num<10;read_num++) { read_data[read_num] = fmc_read_data_16b(WRITE_START_ADDR+read_num*2); } for(i_num=0;i_num<10;i_num++) { if(read_data[i_num]!=write_data[i_num]) { bsp_led_on(&LED0); }else{ bsp_led_on(&LED1); } } while (1) { } }
5.5實(shí)驗(yàn)結(jié)果
將本實(shí)驗(yàn)燒錄到紅楓派實(shí)驗(yàn)板中,運(yùn)行后可以觀察到LED1常亮,表明擦寫(xiě)以及讀取實(shí)驗(yàn)正常。

本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)
-
單片機(jī)
+關(guān)注
關(guān)注
6058文章
44822瀏覽量
644726 -
mcu
+關(guān)注
關(guān)注
146文章
17718瀏覽量
358224 -
FMC
+關(guān)注
關(guān)注
0文章
98瀏覽量
19953 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
5389瀏覽量
100901 -
GD32F3
+關(guān)注
關(guān)注
0文章
12瀏覽量
3918
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
STM32CUBEMX開(kāi)發(fā)GD32F303(6)----GPIO輸入函數(shù)說(shuō)明

STM32CUBEMX開(kāi)發(fā)GD32F303(8)----USART收發(fā)配置

【GD32H757Z海棠派開(kāi)發(fā)板使用手冊(cè)】第四講 FMC-片內(nèi)Flash擦寫(xiě)讀實(shí)驗(yàn)

【GD32F303】星空派介紹
【星空派GD32F303開(kāi)發(fā)板試用體驗(yàn)】開(kāi)發(fā)記錄匯總
【星空派GD32F303開(kāi)發(fā)板試用體驗(yàn)】開(kāi)箱+環(huán)境搭建
【星空派GD32F303開(kāi)發(fā)板試用體驗(yàn)】開(kāi)箱+環(huán)境搭建
【星空派GD32F303開(kāi)發(fā)板試用體驗(yàn)】+板卡概覽
星空派GD32F303開(kāi)發(fā)板的相關(guān)資料下載
STM32CUBEMX開(kāi)發(fā)GD32F303(14)----IIC之配置OLED

GD32F303固件庫(kù)開(kāi)發(fā)

【GD32F470紫藤派開(kāi)發(fā)板使用手冊(cè)】第四講 FMC-片內(nèi)Flash擦寫(xiě)讀實(shí)驗(yàn)

【GD32F303紅楓派開(kāi)發(fā)板使用手冊(cè)】第二講 GPIO-流水燈實(shí)驗(yàn)

【GD32F303紅楓派開(kāi)發(fā)板使用手冊(cè)】第十六講 USART-DMA串口收發(fā)實(shí)驗(yàn)

【GD32F303紅楓派開(kāi)發(fā)板使用手冊(cè)】第二十講 SPI-SPI NAND FLASH讀寫(xiě)實(shí)驗(yàn)

評(píng)論