GD32F303固件库开发(17)----内部Flash读写

36 篇文章 124 订阅

概述

本例程主要讲解如何对芯片自带Flash进行读写,用芯片内部Flash可以对一些需要断电保存的数据进行保存,无需加外部得存储芯片,本例程采用的是GD32F303ZET6主控,512K大小的Flash。
最近在弄ST和GD的课程,需要GD样片的可以加群申请:6_15061293 。

csdn课程

课程更加详细。
https://download.csdn.net/course/detail/37144

样品申请

https://www.wjx.top/vm/wFGhGPF.aspx#

生成例程

这里准备了自己绘制的开发板进行验证。
在这里插入图片描述

系统架构示意图

Flash的操作可以通过FMC控制器进行操作。
在这里插入图片描述

FLASH分配

要注意的是,将数据存在flash不同的地方,速度可能不一样。
在闪存的前256K字节空间内,CPU执行指令零等待,在此范围外,CPU读取指令存在较长延时。
同时FLASH有2大块,对于GD32F30x_CL和GD32F30x_XD,使用了两片闪存,前512KB容量在第一片闪存(bank0)中,后续的容量在第二片闪存(bank1)中;
在这里插入图片描述
在这里插入图片描述

操作流程

如果要对FLASH进行写入数据,需要执行以下四步:

  1. 解锁FLASH
  2. 擦除FLASH
  3. 写入FLASH
  4. 锁住FLASH

在这里插入图片描述

FMC_CTLx 寄存器解锁

首先第一步是确保FMC_CTLx寄存器不处于锁定状态。
在这里插入图片描述
解锁用fmc_unlock()函数,UNLOCK_KEY0和UNLOCK_KEY1分别是0x45670123和0xCDEF89AB,向FMC_KEY0分别写入着2个参数。
在这里插入图片描述
在这里插入图片描述
对于第二层解锁,需要使用ob_unlock()函数,向FMC_OBKEY写入UNLOCK_KEY0和UNLOCK_KEY1。
同时通过软件将FMC_CTL0的OBWEN位清0来锁定FMC_CTL0的OBPG位和OBER位。
在这里插入图片描述
解锁代码。

    /* unlock the flash program/erase controller */
    fmc_unlock();//解锁Flash操作
    ob_unlock();//解锁选项字节,先决条件fmc_unlock

    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

页擦除

第二步进行页擦除。

在这里插入图片描述

在这里插入图片描述

其中第一步确保FMC_CTLx寄存器不处于锁定状态已在上面解锁了,所以直接进行第二步,检查FMC_STATx寄存器的BUSY位来判定闪存是否正处于擦写访问状态,若BUSY位为1,则需等待该操作结束,BUSY位变为0;
对于擦除函数,使用fmc_page_erase();

在这里插入图片描述

对于if(FMC_BANK0_SIZE < FMC_SIZE)
在这里插入图片描述
FMC_BANK0_SIZE 和 FMC_SIZE 是两个定义的常量,它们表示 FMC 控制器的两个不同的地址空间。FMC_BANK0_SIZE 指的是 FMC 控制器的 BANK0 地址空间的大小,而 FMC_SIZE 则指的是整个 FMC 控制器的地址空间的大小。因此,如果 FMC_BANK0_SIZE 小于 FMC_SIZE,则说明 FMC 控制器的 BANK0 地址空间不能完全覆盖整个 FMC 控制器的地址空间,此时可能需要使用其他的地址空间来存储数据。

上述说到的检查FMC_STATx寄存器的BUSY位,使用fmc_bank0_ready_wait()函数。

在这里插入图片描述

对于以下几个步骤
3. 置位FMC_CTLx寄存器的PER位;
4. 将待擦除页的绝对地址(0x08XX XXXX)写到FMC_ADDRx寄存器;
5. 通过将FMC_CTLx寄存器的START位置1来发送页擦除命令到FMC;
6. 等待擦除指令执行完毕,FMC_STATx寄存器的BUSY位清0;

在fmc_page_erase()都有对应操作。

在这里插入图片描述

写数据

解锁和擦除之后,就可以对flash进行写数据的操作。

在这里插入图片描述

其中第一步确保FMC_CTLx寄存器不处于锁定状态已在上面解锁了,所以直接进行第二步,检查FMC_STATx寄存器的BUSY位来判定闪存是否正处于擦写访问状态,若BUSY位为1,则需等待该操作结束,BUSY位变为0;
对于写函数,使用fmc_word_program();

在这里插入图片描述
解锁FMC_CTL0寄存器的可选字节操作位和等待FMC_CTL0寄存器的OBWEN位置1在解锁时候已经操作了,故进入第五步。

在这里插入图片描述

读数据

在这里插入图片描述

对于读数据,可以直接访问地址进行读取。

    OutData=(*(__IO uint32_t*)(WriteAddr));

上锁

上锁可以使用fmc_lock()函数。
在这里插入图片描述

当上锁时,对控制寄存器 0 (FMC_CTL0)的第7位写1。

在这里插入图片描述
在这里插入图片描述

变量定义

/* USER CODE BEGIN 0 */
uint32_t WriteFlashData[3] = {0x11111111,0x22222222,0x33333333};//数据
uint32_t WriteFlashData1[3] = {0x44444444,0x55555555,0x66666666};//数据
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 */

如果要对FLASH进行写入数据,需要执行以下四步:

  1. 解锁FLASH
  2. 擦除FLASH
  3. 写入FLASH
  4. 锁住FLASH

擦除只能是按页或者整块擦除。
GD32F103ZET6的Flash容量是512KB,所以只有255页,每页2KB。
我们可以写入到页255中,即0x0807F800-0x0807FFFF中。
由于单片机是32位,故连续写入多个uint32_t的数据时,地址应该依次增加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();//解锁选项字节,先决条件fmc_unlock
		
  //清除标志位	
	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*/
  //擦除页
  fmc_page_erase(addr);
	
	/* 3/4对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);

    }

演示效果

可以看见,对于高容量,页的大小位2k,故写入addr1时候,addr的数据就被擦除了。

在这里插入图片描述

GD32F303固件开发是指使用GD32F303系列芯片进行软件开发的过程。该系列芯片具有丰富的外设资源和强大的性能,可以广泛应用于各种嵌入式系统开发中。 在GD32F303固件开发中,可以利用官方提供的固件开发工具进行软件开发。可以通过前期准备与烧录、GPIO输入输出、USART通信、ADC采集、PWM输出、定时器等功能来实现各种应用需求。 在前期准备与烧录阶段,需要准备好开发环境,并将固件烧录到芯片中。之后可以根据需要使用GPIO进行输入输出操作,使用USART进行数据收发,使用ADC进行模拟信号采集,使用PWM输出控制电机或灯光,使用定时器进行定时任务的实现等。 在GD32的官方网站和一些技术博客上可以找到大量的DEMO文件和教程,这些资源可以帮助开发者更好地理解和应用GD32F303固件。 总之,GD32F303固件开发提供了丰富的外设资源和强大的性能,可以满足各种嵌入式系统的开发需求。开发者可以根据具体的应用需求,使用固件和相应的开发工具进行软件开发。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [GD32F303固件开发](https://blog.csdn.net/qq_24312945/article/details/127648981)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

记帖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值