概述
本例程主要講解如何對(duì)芯片自帶Flash進(jìn)行讀寫,用芯片內(nèi)部Flash可以對(duì)一些需要斷電保存的數(shù)據(jù)進(jìn)行保存,無(wú)需加外部得存儲(chǔ)芯片,本例程采用的是GD32F303ZET6主控,512K大小的Flash。 最近在弄ST和GD的課程,需要GD樣片的可以加群申請(qǐng):615061293 。
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位。
解鎖代碼。
/* unlock the flash program/erase controller */
fmc_unlock();//解鎖Flash操作
ob_unlock();//解鎖選項(xiàng)字節(jié),先決條件fmc_unlock
fmc_flag_clear(FMC_FLAG_BANK0_END);
fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
頁(yè)擦除
第二步進(jìn)行頁(yè)擦除。
其中第一步確保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è)步驟
- 置位FMC_CTLx寄存器的PER位;
- 將待擦除頁(yè)的絕對(duì)地址(0x08XX XXXX)寫到FMC_ADDRx寄存器;
- 通過將FMC_CTLx寄存器的START位置1來發(fā)送頁(yè)擦除命令到FMC;
- 等待擦除指令執(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)行讀取。
OutData=(*(__IO uint32_t*)(WriteAddr));
上鎖
上鎖可以使用fmc_lock()函數(shù)。
當(dāng)上鎖時(shí),對(duì)控制寄存器 0 (FMC_CTL0)的第7位寫1。
變量定義
/* USER CODE BEGIN 0 */
uint32_t WriteFlashData[3] = {0x11111111,0x22222222,0x33333333};//數(shù)據(jù)
uint32_t WriteFlashData1[3] = {0x44444444,0x55555555,0x66666666};//數(shù)據(jù)
uint32_t addr = 0x0807F800;//page 255
uint32_t addr1 = 0x0807FC00;//page 255+1k
void PrintFlashTest(uint32_t L,uint32_t addr);
void WriteFlashTest(uint32_t L,uint32_t Data[],uint32_t addr);
/* USER CODE END 0 */
如果要對(duì)FLASH進(jìn)行寫入數(shù)據(jù),需要執(zhí)行以下四步:
- 解鎖FLASH
- 擦除FLASH
- 寫入FLASH
- 鎖住FLASH
擦除只能是按頁(yè)或者整塊擦除。 GD32F103ZET6的Flash容量是512KB,所以只有255頁(yè),每頁(yè)2KB。 我們可以寫入到頁(yè)255中,即0x0807F800-0x0807FFFF中。 由于單片機(jī)是32位,故連續(xù)寫入多個(gè)uint32_t的數(shù)據(jù)時(shí),地址應(yīng)該依次增加4。
/*FLASH寫入程序*/
void WriteFlashTest(uint32_t L,uint32_t Data[],uint32_t addr)
{
uint32_t i=0;
/* 1/4解鎖FLASH*/
/* unlock the flash program/erase controller */
fmc_unlock();//解鎖Flash操作
ob_unlock();//解鎖選項(xiàng)字節(jié),先決條件fmc_unlock
//清除標(biāo)志位
fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
fmc_flag_clear(FMC_FLAG_BANK0_END);
fmc_flag_clear(FMC_FLAG_BANK1_PGERR);
fmc_flag_clear(FMC_FLAG_BANK1_WPERR);
fmc_flag_clear(FMC_FLAG_BANK1_END);
/* 2/4擦除FLASH*/
//擦除頁(yè)
fmc_page_erase(addr);
/* 3/4對(duì)FLASH燒寫*/
for(i=0;i< L;i++)
{
fmc_word_program(addr+4*i, Data[i]);
}
/* 4/4鎖住FLASH*/
fmc_lock();
}
/*FLASH讀取打印程序*/
void PrintFlashTest(uint32_t L,uint32_t addr)
{
uint32_t i=0;
for(i=0;i< L;i++)
{
printf("naddr is:0x%x, data is:0x%x", addr+i*4, *(__IO uint32_t*)(addr+i*4));
}
}
主程序
while (1){
WriteFlashTest(3,WriteFlashData,addr);
WriteFlashTest(3,WriteFlashData1,addr1);
PrintFlashTest(3,addr);
PrintFlashTest(3,addr1);
delay_1ms(5000);
}
演示效果
可以看見,對(duì)于高容量,頁(yè)的大小位2k,故寫入addr1時(shí)候,addr的數(shù)據(jù)就被擦除了。
-
FlaSh
+關(guān)注
關(guān)注
10文章
1662瀏覽量
150963 -
固件庫(kù)
+關(guān)注
關(guān)注
2文章
97瀏覽量
15188 -
GD32
+關(guān)注
關(guān)注
7文章
418瀏覽量
25142 -
gd32f303
+關(guān)注
關(guān)注
4文章
38瀏覽量
3892
發(fā)布評(píng)論請(qǐng)先 登錄
【GD32F303】星空派介紹
星空派GD32F303開發(fā)板的相關(guān)資料下載
GD32F30x系列固件庫(kù)
GD32F303固件庫(kù)開發(fā)(1)----前期準(zhǔn)備與燒錄

GD32F303固件庫(kù)開發(fā)(3)----使用固件庫(kù)點(diǎn)亮LED

GD32F303固件庫(kù)開發(fā)(5)----GPIO輸出模式,速率測(cè)試、開漏和輸出說明

AN029 GD32F103程序在GD32F303和GD32F403芯片上運(yùn)行DSP

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

STM32CUBEMX開發(fā)GD32F303

STM32CUBEMX開發(fā)GD32F303(17)----內(nèi)部Flash讀寫

GD32F303為什么啟動(dòng)慢?

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

【GD32 MCU 移植教程】2、從 GD32F303 移植到 GD32F503

評(píng)論