GD32F303固件庫開發(fā)(17)----內(nèi)部Flash讀寫
概述
本例程主要講解如何對(duì)芯片自帶Flash進(jìn)行讀寫,用芯片內(nèi)部Flash可以對(duì)一些需要斷電保存的數(shù)據(jù)進(jìn)行保存,無需加外部得存儲(chǔ)芯片,本例程采用的是GD32F303ZET6主控,512K大小的Flash。 最近在弄ST和GD的課程,需要GD樣片的可以加群申請(qǐng):6_15061293 。
csdn課程
課程更加詳細(xì)。?https://download.csdn.net/course/detail/37144
樣品申請(qǐng)
https://www.wjx.top/vm/wFGhGPF.aspx#
生成例程
這里準(zhǔn)備了自己繪制的開發(fā)板進(jìn)行驗(yàn)證。?

系統(tǒng)架構(gòu)示意圖
Flash的操作可以通過FMC控制器進(jìn)行操作。?

FLASH分配
要注意的是,將數(shù)據(jù)存在flash不同的地方,速度可能不一樣。 在閃存的前256K字節(jié)空間內(nèi),CPU執(zhí)行指令零等待,在此范圍外,CPU讀取指令存在較長(zhǎng)延時(shí)。 同時(shí)FLASH有2大塊,對(duì)于GD32F30x_CL和GD32F30x_XD,使用了兩片閃存,前512KB容量在第一片閃存(bank0)中,后續(xù)的容量在第二片閃存(bank1)中;?

?

操作流程
如果要對(duì)FLASH進(jìn)行寫入數(shù)據(jù),需要執(zhí)行以下四步:
解鎖FLASH
擦除FLASH
寫入FLASH
鎖住FLASH

FMC_CTLx 寄存器解鎖
首先第一步是確保FMC_CTLx寄存器不處于鎖定狀態(tài)。?

?解鎖用fmc_unlock()函數(shù),UNLOCK_KEY0和UNLOCK_KEY1分別是0x45670123和0xCDEF89AB,向FMC_KEY0分別寫入著2個(gè)參數(shù)。?

?

?對(duì)于第二層解鎖,需要使用ob_unlock()函數(shù),向FMC_OBKEY寫入U(xiǎn)NLOCK_KEY0和UNLOCK_KEY1。 同時(shí)通過軟件將FMC_CTL0的OBWEN位清0來鎖定FMC_CTL0的OBPG位和OBER位。?

?解鎖代碼。
頁擦除
第二步進(jìn)行頁擦除。


其中第一步確保FMC_CTLx寄存器不處于鎖定狀態(tài)已在上面解鎖了,所以直接進(jìn)行第二步,檢查FMC_STATx寄存器的BUSY位來判定閃存是否正處于擦寫訪問狀態(tài),若BUSY位為1,則需等待該操作結(jié)束,BUSY位變?yōu)?; 對(duì)于擦除函數(shù),使用fmc_page_erase();

對(duì)于if(FMC_BANK0_SIZE < FMC_SIZE)?

?FMC_BANK0_SIZE 和 FMC_SIZE 是兩個(gè)定義的常量,它們表示 FMC 控制器的兩個(gè)不同的地址空間。FMC_BANK0_SIZE 指的是 FMC 控制器的 BANK0 地址空間的大小,而 FMC_SIZE 則指的是整個(gè) FMC 控制器的地址空間的大小。因此,如果 FMC_BANK0_SIZE 小于 FMC_SIZE,則說明 FMC 控制器的 BANK0 地址空間不能完全覆蓋整個(gè) FMC 控制器的地址空間,此時(shí)可能需要使用其他的地址空間來存儲(chǔ)數(shù)據(jù)。
上述說到的檢查FMC_STATx寄存器的BUSY位,使用fmc_bank0_ready_wait()函數(shù)。

對(duì)于以下幾個(gè)步驟 3. 置位FMC_CTLx寄存器的PER位; 4. 將待擦除頁的絕對(duì)地址(0x08XX XXXX)寫到FMC_ADDRx寄存器; 5. 通過將FMC_CTLx寄存器的START位置1來發(fā)送頁擦除命令到FMC; 6. 等待擦除指令執(zhí)行完畢,F(xiàn)MC_STATx寄存器的BUSY位清0;
在fmc_page_erase()都有對(duì)應(yīng)操作。

寫數(shù)據(jù)
解鎖和擦除之后,就可以對(duì)flash進(jìn)行寫數(shù)據(jù)的操作。

其中第一步確保FMC_CTLx寄存器不處于鎖定狀態(tài)已在上面解鎖了,所以直接進(jìn)行第二步,檢查FMC_STATx寄存器的BUSY位來判定閃存是否正處于擦寫訪問狀態(tài),若BUSY位為1,則需等待該操作結(jié)束,BUSY位變?yōu)?; 對(duì)于寫函數(shù),使用fmc_word_program();

?解鎖FMC_CTL0寄存器的可選字節(jié)操作位和等待FMC_CTL0寄存器的OBWEN位置1在解鎖時(shí)候已經(jīng)操作了,故進(jìn)入第五步。

讀數(shù)據(jù)

對(duì)于讀數(shù)據(jù),可以直接訪問地址進(jìn)行讀取。
上鎖
上鎖可以使用fmc_lock()函數(shù)。?

當(dāng)上鎖時(shí),對(duì)控制寄存器 0 (FMC_CTL0)的第7位寫1。

?

變量定義
如果要對(duì)FLASH進(jìn)行寫入數(shù)據(jù),需要執(zhí)行以下四步:
解鎖FLASH
擦除FLASH
寫入FLASH
鎖住FLASH
擦除只能是按頁或者整塊擦除。 GD32F103ZET6的Flash容量是512KB,所以只有255頁,每頁2KB。 我們可以寫入到頁255中,即0x0807F800-0x0807FFFF中。 由于單片機(jī)是32位,故連續(xù)寫入多個(gè)uint32_t的數(shù)據(jù)時(shí),地址應(yīng)該依次增加4。
主程序
演示效果
可以看見,對(duì)于高容量,頁的大小位2k,故寫入addr1時(shí)候,addr的數(shù)據(jù)就被擦除了。
