天天看點

立創梁山派GD32F450ZGT6--内部FLASH的讀寫flash.cflash.h main.c實驗結果

關于flash的介紹

立創梁山派GD32F450ZGT6--内部FLASH的讀寫flash.cflash.h main.c實驗結果
立創梁山派GD32F450ZGT6--内部FLASH的讀寫flash.cflash.h main.c實驗結果
立創梁山派GD32F450ZGT6--内部FLASH的讀寫flash.cflash.h main.c實驗結果

詳情見資料手冊的第53頁開始。

代碼是從正點原子的【探索者STM32F407開發闆資料】  修改而來。

而GD32的flash的相關庫函數檔案是【GD32F4xx_fmc.c】。

使用flash 的話,一定要導入這個檔案

上代碼

flash.c

#include "flash.h"


//讀取指定位址的半字(16位資料) 
//faddr:讀位址 
//傳回值:對應資料.
unsigned int GDFLASH_ReadWord(unsigned int faddr)
{
	return *(volatile unsigned int*)faddr; 
}  


//擷取某個位址所在的flash扇區
//addr:flash位址
//傳回值:0~11,即addr所在的扇區
uint16_t GDFLASH_GetFlashSector(unsigned int addr)
{
	if(addr<ADDR_FLASH_SECTOR_1)			    return FLASH_Sector_0;
	else if(addr<ADDR_FLASH_SECTOR_2)			return FLASH_Sector_1;
	else if(addr<ADDR_FLASH_SECTOR_3)			return FLASH_Sector_2;
	else if(addr<ADDR_FLASH_SECTOR_4)			return FLASH_Sector_3;
	else if(addr<ADDR_FLASH_SECTOR_5)			return FLASH_Sector_4;
	else if(addr<ADDR_FLASH_SECTOR_6)			return FLASH_Sector_5;
	else if(addr<ADDR_FLASH_SECTOR_7)			return FLASH_Sector_6;
	else if(addr<ADDR_FLASH_SECTOR_8)			return FLASH_Sector_7;
	else if(addr<ADDR_FLASH_SECTOR_9)			return FLASH_Sector_8;
	else if(addr<ADDR_FLASH_SECTOR_10)		    return FLASH_Sector_9;
	else if(addr<ADDR_FLASH_SECTOR_11)		    return FLASH_Sector_10; 
	return FLASH_Sector_11;	
}   

//從指定位址開始寫入指定長度的資料
//該函數對OTP區域也有效!可以用來寫OTP區!
//OTP區域位址範圍:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始位址(此位址必須為4的倍數!!)
//pBuffer:資料指針
//NumToWrite:字(32位)數(就是要寫入的32位資料的個數.) 
void GDFLASH_Write(unsigned int WriteAddr,unsigned int *pBuffer,unsigned int NumToWrite)
{   
  fmc_state_enum status = FMC_READY;
  unsigned int addrx=0;
  unsigned int endaddr=0;	
	
  if(WriteAddr<GD32_FLASH_BASE||WriteAddr%4)return;		//輸入的位址是非法位址
  fmc_unlock();  	                                    //FMC解鎖				
  addrx=WriteAddr;                                      //設定寫入的起始位址
  endaddr=WriteAddr+NumToWrite*4;					    //設定寫入的結束位址
	
	/*	隻有主存儲區,才需要執行擦除操作  */
	if(addrx<0X1FFF0000)			
	{
		/*	對非FFFFFFFF的地方,先擦除		*/
		while(addrx<endaddr)		
		{
			/*	有非0XFFFFFFFF的地方,就擦除這個扇區	*/
			if(GDFLASH_ReadWord(addrx)!=0XFFFFFFFF)
			{   
				/*	對指定扇區擦除并傳回擦除狀态		*/
				status=fmc_sector_erase(GDFLASH_GetFlashSector(addrx));
				/*	擦除失敗或者發生錯誤	*/
				if(status != FMC_READY)	break;	
			}
			else	
			{				
				addrx+=4;//位址加4
			}
		}  
	}
	/*		擦除成功		*/
	if(status==FMC_READY)
	{
		/*	寫入的位址沒有超過之前計算的結束位址  */
		while(WriteAddr<endaddr)
		{
			/*	寫入一個字資料并傳回寫入狀态	 */
			if(fmc_word_program(WriteAddr,*pBuffer)!=FMC_READY) 
			{ 
				break;			//寫入異常
			}
			WriteAddr+=4; //寫入位址+4
			pBuffer++;	  //資料位址自增
		} 
	}
	/*	fmc上鎖	*/
	fmc_lock();  		
} 

//從指定位址開始讀出指定長度的資料
//ReadAddr:起始位址
//pBuffer:資料指針
//NumToRead:字(4位)數
void GDFLASH_Read(unsigned int ReadAddr,unsigned int *pBuffer,unsigned int NumToRead)   	
{
	unsigned int i;
	for(i=0;i<NumToRead;i++)
	{
		pBuffer[i]=GDFLASH_ReadWord(ReadAddr);//讀取4個位元組.
		ReadAddr+=4;						  //偏移4個位元組.	
	}
}  

           

flash.h

#ifndef _FLASH_h_
#define _FLASH_h_

#include "gd32f4xx.h"

//FLASH起始位址
#define GD32_FLASH_BASE 0x08000000 	//GD32 FLASH的起始位址
 

//FLASH 扇區的起始位址
#define ADDR_FLASH_SECTOR_0     ((unsigned int)0x08000000) 	//扇區0起始位址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_1     ((unsigned int)0x08004000) 	//扇區1起始位址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_2     ((unsigned int)0x08008000) 	//扇區2起始位址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_3     ((unsigned int)0x0800C000) 	//扇區3起始位址, 16 Kbytes  
#define ADDR_FLASH_SECTOR_4     ((unsigned int)0x08010000) 	//扇區4起始位址, 64 Kbytes  
#define ADDR_FLASH_SECTOR_5     ((unsigned int)0x08020000) 	//扇區5起始位址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_6     ((unsigned int)0x08040000) 	//扇區6起始位址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_7     ((unsigned int)0x08060000) 	//扇區7起始位址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_8     ((unsigned int)0x08080000) 	//扇區8起始位址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_9     ((unsigned int)0x080A0000) 	//扇區9起始位址, 128 Kbytes  
#define ADDR_FLASH_SECTOR_10    ((unsigned int)0x080C0000) 	//扇區10起始位址,128 Kbytes  
#define ADDR_FLASH_SECTOR_11    ((unsigned int)0x080E0000) 	//扇區11起始位址,128 Kbytes  
	


/** @defgroup FLASH_Sectors
  * @{
  */
#define FLASH_Sector_0     ((uint16_t)0x0000) /*!< Sector Number 0   */
#define FLASH_Sector_1     ((uint16_t)0x0008) /*!< Sector Number 1   */
#define FLASH_Sector_2     ((uint16_t)0x0010) /*!< Sector Number 2   */
#define FLASH_Sector_3     ((uint16_t)0x0018) /*!< Sector Number 3   */
#define FLASH_Sector_4     ((uint16_t)0x0020) /*!< Sector Number 4   */
#define FLASH_Sector_5     ((uint16_t)0x0028) /*!< Sector Number 5   */
#define FLASH_Sector_6     ((uint16_t)0x0030) /*!< Sector Number 6   */
#define FLASH_Sector_7     ((uint16_t)0x0038) /*!< Sector Number 7   */
#define FLASH_Sector_8     ((uint16_t)0x0040) /*!< Sector Number 8   */
#define FLASH_Sector_9     ((uint16_t)0x0048) /*!< Sector Number 9   */
#define FLASH_Sector_10    ((uint16_t)0x0050) /*!< Sector Number 10  */
#define FLASH_Sector_11    ((uint16_t)0x0058) /*!< Sector Number 11  */
#define FLASH_Sector_12    ((uint16_t)0x0080) /*!< Sector Number 12  */
#define FLASH_Sector_13    ((uint16_t)0x0088) /*!< Sector Number 13  */
#define FLASH_Sector_14    ((uint16_t)0x0090) /*!< Sector Number 14  */
#define FLASH_Sector_15    ((uint16_t)0x0098) /*!< Sector Number 15  */
#define FLASH_Sector_16    ((uint16_t)0x00A0) /*!< Sector Number 16  */
#define FLASH_Sector_17    ((uint16_t)0x00A8) /*!< Sector Number 17  */
#define FLASH_Sector_18    ((uint16_t)0x00B0) /*!< Sector Number 18  */
#define FLASH_Sector_19    ((uint16_t)0x00B8) /*!< Sector Number 19  */
#define FLASH_Sector_20    ((uint16_t)0x00C0) /*!< Sector Number 20  */
#define FLASH_Sector_21    ((uint16_t)0x00C8) /*!< Sector Number 21  */
#define FLASH_Sector_22    ((uint16_t)0x00D0) /*!< Sector Number 22  */
#define FLASH_Sector_23    ((uint16_t)0x00D8) /*!< Sector Number 23  */


unsigned int GDFLASH_ReadWord(unsigned int faddr);		  	//讀出字  
void GDFLASH_Write(unsigned int WriteAddr,unsigned int *pBuffer,unsigned int NumToWrite);		//從指定位址開始寫入指定長度的資料
void GDFLASH_Read(unsigned int ReadAddr,unsigned int *pBuffer,unsigned int NumToRead);   		//從指定位址開始讀出指定長度的資料
						   

#endif
           

 main.c

#include "gd32f4xx.h"
#include "systick.h"
#include "usart0.h"
#include "stdio.h"
#include "flash.h"  


//要寫入到GD32 FLASH的字元串數組
const unsigned char TEXT_Buffer[]={"Hello 立創梁山派!"};
#define TEXT_LENTH sizeof(TEXT_Buffer)	 		  	//數組長度	
#define SIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)

#define FLASH_SAVE_ADDR  0X0800C004 	//設定FLASH 儲存位址(必須為偶數,且所在扇區,要大于本代碼所占用到的扇區.
									    //否則,寫操作的時候,可能會導緻擦除整個扇區,進而引起部分程式丢失.引起當機.

int main(void)
{
	unsigned char datatemp[SIZE];   
	unsigned char temp_buff[200]; 
	
	nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 優先級分組
	systick_config();		                           //系統滴答定時器 定時1MS		 
	USART1_Init();
	USART0_send_String((unsigned char *)"--開始--");
	                        
	/*	寫入TEXT_Buffer數組裡的資料	*/
	GDFLASH_Write(FLASH_SAVE_ADDR,(unsigned int*)TEXT_Buffer,SIZE);
	
	delay_1ms(1000);

	/*	讀出資料儲存至datatemp數組		*/
	GDFLASH_Read(FLASH_SAVE_ADDR,(unsigned int*)datatemp,SIZE);
	
	/*	序列槽調試		*/
	sprintf((char *)temp_buff, "讀取的資料=%s\r\n", datatemp);
	USART0_send_String(temp_buff);
	                      
  while(1)  
	{        
		
		
	}
}
           

實驗結果

通過序列槽調試助手顯示讀取到的資料

立創梁山派GD32F450ZGT6--内部FLASH的讀寫flash.cflash.h main.c實驗結果

繼續閱讀