天天看點

GD32的flash讀、擦除、寫操作GD32的flash特征GD32的flash結構GD32的flash讀操作GD32的flash擦除操作GD32的flash寫操作

GD32的flash特征

1、在flash的前256K位元組空間内,CPU執行指令零等待;在此範圍外,CPU讀取指令存在較長延時;

2、對于flash大于512KB(不包括等于512KB)的GD32F10x_CL和GD32F10x_XD,使用了兩片閃存;前512KB容量在第一片閃存(bank0)中,後續的容量在第二片閃存(bank1)中;

3、對于flash容量小于等于512KB的GD32F10x_CL和GD32F10x_HD,隻使用了bank0;

4、對 于 GD32F10x_MD , 閃 存 頁 大 小 為 1KB 。 GD32F10x_CL 和 GD32F10x_HD ,GD32F10x_XD,bank0的閃存頁大小為2KB,bank1的閃存頁大小為4KB;

5、支援32位整字或16位半字程式設計,頁擦除和整片擦除操作;

GD32的flash結構

GD32F10x_MD

GD32的flash讀、擦除、寫操作GD32的flash特征GD32的flash結構GD32的flash讀操作GD32的flash擦除操作GD32的flash寫操作

GD32F10x_CL,GD32F10x_HD 和 GD32F10x_XD

GD32的flash讀、擦除、寫操作GD32的flash特征GD32的flash結構GD32的flash讀操作GD32的flash擦除操作GD32的flash寫操作

GD32的flash讀操作

flash可以像普通存儲空間一樣直接尋址通路。

uint16_t IAP_ReadFlag(void)
{
	return *(volatile uint16_t*)(FLASH_ADDR);  
}
           

GD32的flash擦除操作

頁擦除

每一頁可以被獨立擦除,步驟如下:

  1. 確定FMC_CTLx寄存器不處于鎖定狀态;
  2. 檢查FMC_STATx寄存器的BUSY位來判定閃存是否正處于擦寫通路狀态,若BUSY位為1,則需等待該操作結束,BUSY位變為0;
  3. 置位FMC_CTLx寄存器的PER位;
  4. 将待擦除頁的絕對位址(0x08XX XXXX)寫到FMC_ADDRx寄存器;
  5. 通過将FMC_CTLx寄存器的START位置1來發送頁擦除指令到FMC;
  6. 等待擦除指令執行完畢,FMC_STATx寄存器的BUSY位清0;
  7. 如果需要,使用DBUS讀并驗證該頁是否擦除成功。

代碼上直接調用GD的庫函數即可:

void fmc_erase_page(uint32_t Page_Address)
{
	fmc_unlock();  //fmc解鎖
    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    
    /* erase the flash pages */
	fmc_page_erase(Page_Address);
	
	/* clear all pending flags */
	fmc_flag_clear(FMC_FLAG_BANK0_END);
	fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
	fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
	
	fmc_lock();  //fmc上鎖
}
           

要擦除連續的幾頁:

void fmc_erase_pages(void)
{
    uint32_t erase_counter;

    /* unlock the flash program/erase controller */
    fmc_unlock();

    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    
    /* erase the flash pages */
    for(erase_counter = 0; erase_counter < page_num; erase_counter++){
        fmc_page_erase(FMC_WRITE_START_ADDR + (FMC_PAGE_SIZE * erase_counter));
        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    }

    /* lock the main FMC after the erase operation */
    fmc_lock();
}
           

整片擦除

void fmc_erase_page(uint32_t Page_Address)
{
	fmc_unlock();  //fmc解鎖
    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
    
    /* erase whole chip */
	fmc_mass_erase();
	
	/* clear all pending flags */
	fmc_flag_clear(FMC_FLAG_BANK0_END);
	fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
	fmc_flag_clear(FMC_FLAG_BANK0_PGERR);
	
	fmc_lock();  //fmc上鎖
}
           

GD32的flash寫操作

往flash的某個位址寫入資料前,一般要先擦除該位址。

16位半字程式設計:

void IAP_WriteFlag(uint16_t flag)
{
	fmc_unlock();
	fmc_page_erase(IAP_FLAG_ADDR); 
	fmc_halfword_program(IAP_FLAG_ADDR,flag);
	fmc_lock();
}
           

32位整字程式設計:

void fmc_program(void)
{
    /* unlock the flash program/erase controller */
    fmc_unlock();

    address = FMC_WRITE_START_ADDR;

    /* program flash */
    while(address < FMC_WRITE_END_ADDR){
        fmc_word_program(address, data0);
        address += 4;
        fmc_flag_clear(FMC_FLAG_BANK0_END);
        fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
        fmc_flag_clear(FMC_FLAG_BANK0_PGERR); 
    }

    /* lock the main FMC after the program operation */
    fmc_lock();
}
           

繼續閱讀