stm32 hal库 flash读写擦除(基于江科大代码)

        最近有一个项目需要掉电不丢失数据,但是项目的板子已经画好了,同时为了方便也没有外接存储器芯片。这个时候要实现掉电不丢失,除了外挂的flash之后我想到了stm32芯片的内部flash。

        基于此我去学习了江科大的flash视频,参考了他的代码写了flash的读写操作,这篇文章作为自己复习flash操作的时候使用。

        在此之前我首先要说明一下我的代码是基于STM32L031G6u6这款芯片写的,这款芯片的flash大小是32kb,而c8t6的flash大小是64kb,所以一些地方可能会有些许不同,请读者观看的时候注意。

        言归正传,首先初步介绍一下flash,flash芯片也叫闪存芯片是存储芯片中的一种。作为常见的存储芯片,flash芯片和sram芯片之间有一些区别下面一张图就是他们之间的部分区别

可以看到flash相对于sram芯片他的读写次数是有限的,同时读写速度相对于sram也要慢得多。那么大家可能会想既然sram芯片那么好,那为什么还要用flash芯片呢?其中之一是sram芯片的价格相对于flash芯片而言非常的高昂,其次也是比较重要的一点是,存储在sram中的数据掉电会丢失,但是存储在flash芯片中的数据掉电确是不丢失的。相信大家看到这里也猜到了,stm32的程序都是存储在flash中的。        

        

STM32可以根据flash的大小分为小容量,中容量和大容量产品。小于等于32Kb是小容量产品,大于64Kb小于128Kb是中容量产品,大于128Kb属于大容量产品。

        然后根据stm32的芯片手册,flash的起始地址一般为0x0800 0000,最大的页地址只需要在起始地址的基础上加上flash的大小即可。(举个例子,L0的flash大小是32Kb,换算成字节也就是1024*32=32768字节。但是地址是从0-31,所以他的最后一页的起始地址是0x0800 0000+0x0000 7C00)对于低容量和中容量产品来说,他们每一页的大小都是1Kb,而对于大容量的产品而言他们的每一页的大小是2Kb。        

         接下里我们来看stm32的flash分区

还是以上面那副图为例,因为我网上没找到低容量的flash组织图片,所以这边以中容量产品的flash分区为例。我们可以看到FLASH分为了三个部分,分别是主存模块,信息块和寄存器接口。我们需要关注的是主存模块,也就是平时我们代码存储的地方。我们可以看到FLASH的地址从0x0800 0000开始,经过1Kb的大小到大下一页的起始地址。而且一共是128页。本文的FLASH读写也是基于这部分FLASH而言的。        

        接下来我们看信息块,信息块中包含了系统存储器,系统存储器是不允许修改的因为其中存储了ST公司的bootloader程序。之后就是选择字节了,可以看到选择字节的大小比较小只有16字节,这部分的FLASH用于配置和保护FLASH存储器的特性和行为。‌

        至于最后FLASH就是用来访问对应的存储器的。

通过以上的介绍我们大致对FLASH有了一个初步的了解。接下来我会讲flash如何读取。

        flash的读取相对于flash的擦除和写入而言要简单一些,只需要读取对应的地址的数据即可。

以下是读取的代码部分:

具体的格式就是*((__IO uint32_t *)(Address)),其中我们需要读取32位的数据就是uint32_t,要是想读取16位就将其改为uint16_t即可,8位也是一样。这段代码的意思是,将访问Address的地址,*将地址中的数据取出来,至于其中的__IO,其实这个符号是volatile的宏定义,volatile是一个C语言的关键字,这个关键字告诉编辑器这个变量是在程序运行的过程中随时会被修改的,可以防止被编译器优化,但是要是编辑器优化等级是最低的话,这个符号加与不加都可以。

        

        Flash的擦除操作:

在进行Flash的写和擦除操作之前,我们首先要对Flash进行解锁,因为Flash默认是锁着的。

在hal库当中,我们对于Flash的操作方式有两种,一种是按banks也就是按块操作,一种是按page按页操作,以上的两个函数的代码是以页操作为基础的。在hal库中我们通过配置FLASH_EraseInitTypeDef这个结构体来配置擦除的基本属性,这个结构体有四个参数 banks   PageAddress   NbPages  TypeErase。第一个是按块操作的我们不管,第二个参数PageAddress是需要操作的页的首地址,第三个参数NbPages是需要操作的页数,最后一个也就是擦除类型了,我们的是按页擦除,擦除完成记得上锁。

所以看到这边大家也应该知道了Flash全擦除的原理就是在flash的起始地址开始,往后擦除的页数等于FLASH的大小即可。比如L0的FLASH大小是32Kb,所以我们擦除的页数选32页即可。

以上两个函数是针对stm32L0的Flash全擦书和制定页擦除函数。

        FLASH寄存器的写操作:

首先在进行FLASH寄存器的写操作之前我们同样需要对Flash进行解锁,之后只需要调用HAL_FLASH_Program 传入需要写的数据位数的类型,写入的FLASH地址和数据即可。

需要注意的是在调用F1的hal库的时候我发现F1的这个函数是支持写入double类型的参数的,与此同时F1中的写入FLASH_TYPEPROGRAMDATA_BYTE的这个参数是消失了的。

而L0则是支持写入字节操作但是没有double类型的选项。

在进行选择写入数据的位数的时候我遇到了一个问题就是有两个写word参数,后面我对这两个参数的底层代码都进行了查看

发现这两个写word的 参数应该是一样的,所以这个地方填哪一个都行。

以上就是我们对于FLASH读写擦除的基本操作。

但是这部分代码只是完成了我目前需要的部分,严谨的flash操作肯定不止这些。后期会在江科大的代码基础上进行完善。

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值