当前位置:   article > 正文

关于STM32内部flash闪存的总结和配置_stm32flash存储数据

stm32flash存储数据

存储器的概述:(源于数电教材)

分类:        只读存储器(ROM)   只写存储器(RAM)

只读存储器(ROM):

 只写存储器(RAM):


嵌入式 Flash:(以STM32f407为例)

内存容量:  stmf407内存512k

Flash 具有以下主要特性:

● 对于 STM32F40x 和 STM32F41x,容量高达 1 MB;对于 STM32F42x 和 STM32F43x,
容量高达 2 MB
● 128 位宽数据读取
● 字节、半字、字和双字数据写入
● 某个扇区擦除与全部擦除
● 存储器组织结构
● 低功耗模式(有关详细信息,请参见参考手册的“电源控制 (PWR)”部分)

Flash 结构:
— 主存储器块,分为 4 个 16 KB 扇区、1 个 64 KB 扇区和 7 个 128 KB 扇区
— 系统存储器,器件在系统存储器自举模式下从该存储器启动
— 512 字节 OTP(一次性可编程),用于存储用户数据
OTP 区域还有 16 个额外字节,用于锁定对应的 OTP 数据块。
— 选项字节,用于配置读写保护、BOR 级别、软件/硬件看门狗以及器件处于待机或
停止模式下的复位。 

注意:我们的f407只有3个128kb的沙扇区,对扇区进行访问或者擦除的时候需要计算出其实地址和结束地址,用户下载数据时候,是从起始地址下载进去的;

注意:

              用户在存储自定义的数据时候,尽量从后面开始存储数据;避免对用户数据进行干扰

内部FLASH使用方法:

1.flash解锁-->2.flash擦除-->3.flash写入-->4.flash上锁-->5.flash读取

第一步:Flash 控制寄存器解锁:

        原因:复位后,Flash 控制寄存器 (FLASH_CR) 不允许执行写操作,以防因电气干扰等原因出现对Flash 的意外操作。

寄存器的解锁顺序如下:
1. 在 Flash 密钥寄存器 (FLASH_KEYR) 中写入 KEY1 = 0x45670123
2. 在 Flash 密钥寄存器 (FLASH_KEYR) 中写入 KEY2 = 0xCDEF89AB

注意:如果顺序出现错误,将返回总线错误并锁定 FLASH_CR 寄存器,直到下一次复位。

具体步骤:

第二步:flash擦除:

        擦除扇区之前需要设计编程/擦除并行位数,决定了写入的时间,Flash 擦除操作可针对扇区或整个 Flash(批量擦除)执行。执行批量擦除时,不会影响OTP 扇区或配置扇区。

扇区擦除的具体步骤如下:

1. 检查 FLASH_SR 寄存器中的 BSY 位,以确认当前未执行任何 Flash 操作
2. 在 FLASH_CR 寄存器中,将 SER 位置 1,并从主存储块的 12 个 (STM32F405xx/07xx
和 STM32F415xx/17xx) 或 24 个 (STM32F42xxx 和 STM32F43xxx) 扇区中选择要擦除
的扇区 (SNB) 需要指定扇区号(0~7),通过扇区地址计算,本芯(STM32F407)片只有7个扇区
3. 将 FLASH_CR 寄存器中的 STRT 位置 1开始擦除扇区
4. 等待 BSY 位清零 等待擦除完成

 

通过扇区地址判断扇区号的自定义函数:

  1. //获取flash的扇区号 通过扇区地址进行获取
  2. uint32_t GetSector(uint32_t Address)
  3. {
  4. uint32_t sector = 0;
  5. if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  6. {
  7. sector = FLASH_Sector_0;
  8. }
  9. else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  10. {
  11. sector = FLASH_Sector_1;
  12. }
  13. else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  14. {
  15. sector = FLASH_Sector_2;
  16. }
  17. else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  18. {
  19. sector = FLASH_Sector_3;
  20. }
  21. else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  22. {
  23. sector = FLASH_Sector_4;
  24. }
  25. else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  26. {
  27. sector = FLASH_Sector_5;
  28. }
  29. else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  30. {
  31. sector = FLASH_Sector_6;
  32. }
  33. else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  34. {
  35. sector = FLASH_Sector_7;
  36. }
  37. else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  38. {
  39. sector = FLASH_Sector_8;
  40. }
  41. else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  42. {
  43. sector = FLASH_Sector_9;
  44. }
  45. else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  46. {
  47. sector = FLASH_Sector_10;
  48. }
  49. else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
  50. {
  51. sector = FLASH_Sector_11;
  52. }
  53. return sector; //把计算出来的扇区号返回
  54. }

具体步骤:

 

第三/四步:flash写入flash上锁:

可通过软件将 FLASH_CR 寄存器中的 LOCK 位置为 1 来锁定 FLASH_CR 寄存器。

具体步骤:

第五步:flash读取

具体步骤:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/481344
推荐阅读
相关标签
  

闽ICP备14008679号