你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 实现内部Flash的读写(HAL库版)

[复制链接]
STMCU小助手 发布时间:2022-1-16 19:29
Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器。可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除。一个Nand Flash由多个块(Block)组成,每个块里面又包含很多页(page)。每个页对应一个空闲区域/冗余区域(spare area),这个区域不是用来存储数据的,用于放置数据的校验值检测和纠错的。块,是Nand Flash的擦除操作的基本/最小单位。页,是Nand Flash的写入操作的基本/最小的单位。
  首先简要写一下FLASH的读写流程:
    对FLASH写入数据
    解锁FLASH
    擦除FLASH
    写入数据到FLASH
    锁住FLASH  
          FLASH读取数据 (直接读取相应的FLASH地址即可)
  操作MCU里的Flash,还有几个注意事项:
  1、往Flash写入数据的时候,要先对要写入的页进行擦除,如果要写的页里有数据,要先读出来在缓存区,再把页擦除,再写入数据;在擦除页之后,只要这次你写的数据大小不够一页,可以连续写入。
  2、要计算好程序的内存,因为你的程序也是保存在MCU的Flash里的,如果你操作到保存着程序的内存,程序就会死掉,至于程序内存怎么看,你可以生成bin文件,bin文件的大小就是你程序所占内存的大小了;程序内存基本都是从Flash内存一开始存起的,这里以STM32Fo72c8t6举例,如下图。
 
1433771-20191017133616331-493231916.png ; f7 t! D$ H5 g
1433771-20190813160306451-195238868.png , K: K. s) e/ V8 J# {( _4 F! e) K: o
 
  看图可以看出,这个芯片的Flash内存范围是 0x0800 0000 ~ 0x0802 0000  ,假设我要烧录进去的bin文件为10K,那我们操作Flash的时候,地址就要从 0x0800 0000 +  (0x400*11) 开始,避开程序的存储位置,Flash地址偏移1位就是1个字节。
  3、要注意MCU一页的大小,一些MCU一页是1KB,一些MCU一页是2KB
- `& m) X4 |+ ?% d6 z* t1 u$ ~
  下面举个例子写入数据 0x0001 到Flash中uint16_t my_add = 0x0001;
  1. uint32_t Robot_Num_Flash_Add = 0x08005000;      
    9 X* j2 d: ~, F7 l) l
  2.         FLASH_EraseInitTypeDef My_Flash;  //声明 FLASH_EraseInitTypeDef 结构体为 My_Flash/ d5 G" d2 l# n2 a9 ?9 h
  3.         HAL_FLASH_Unlock();               //解锁Flash
    * V1 g3 X9 ~* e6 m
  4.             ' w4 j4 L1 n% k# i3 L% W6 Q0 R
  5.         My_Flash.TypeErase = FLASH_TYPEERASE_PAGES;  //标明Flash执行页面只做擦除操作
    4 e1 ~' @/ R% r6 @1 I2 H3 Q
  6.         My_Flash.PageAddress = Robot_Num_Flash_Add;  //声明要擦除的地址; P4 h4 M: a: ]) c; ^# M; e
  7.         My_Flash.NbPages = 1;                        //说明要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值. n5 `. n0 q* Z0 j5 b
  8.             
    & |5 x! G5 K1 p9 e: u. J: \1 l- V
  9.         uint32_t PageError = 0;                    //设置PageError,如果出现错误这个变量会被设置为出错的FLASH地址3 o  Q, W# a" r3 U& S( [
  10.         HAL_FLASHEx_Erase(&My_Flash, &PageError);  //调用擦除函数擦除. x( ^. y8 R) K5 R, q; b0 W2 y
  11.         
    ' f! F2 J% t$ q8 V  i
  12.         uint16_t Write_Flash_Data = my_add;8 n+ V# Z! O8 V. I, y- t  O; P
  13.        //对Flash进行烧写,FLASH_TYPEPROGRAM_HALFWORD 声明操作的Flash地址的16位的,此外还有32位跟64位的操作,自行翻查HAL库的定义即可
    : t" z1 }8 p0 t. ~
  14.       HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Robot_Num_Flash_Add, Write_Flash_Data);            HAL_FLASH_Lock(); //锁住Flash
复制代码
; z. I! C8 \6 W( H% {% J8 {
  写完之后,接着就到读了,Flash写有次数限制,写的次数在1W次还是10W次(忘了)就不可写入了,而读是没有次数限制的,读多少次都可以,下面就把写入到Flash里的数据 0x0001 读出来
  1.     uint32_t Robot_Num_Flash_Add = 0x08005000;
    ' O3 K! Y) F% V9 W
  2.    ID_Num = *(__IO uint16_t*)( Robot_Num_Flash_Add ); //*(__IO uint16_t *)是读取该地址的参数值,其值为16位数据,一次读取两个字节,*(__IO uint32_t *)就一次读4个字节
    2 [: H- t% F; o: ]: f; V
  3.     printf("ID_num:0x%x\r\n", ID_Num);
复制代码
# u" I" P6 W9 f1 j$ B+ z8 l& }6 W; P
  经过上面的程序就可以实现 STM32 中 Flash 数据的读写了,具体怎么读写,每个案子不同,各位就可以根据需求去修改,只要注意好注意事项即可,代码已经实测可用。

( I7 y' @. J. x. W9 @  N
. J3 m$ `# z5 E( c
收藏 评论0 发布时间:2022-1-16 19:29

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版