立创梁山派GD32F450ZGT6--内部FLASH的读写

关于flash的介绍

 

详情见数据手册的第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)  
	{        
		
		
	}
}

实验结果

通过串口调试助手显示读取到的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老怪.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值