• STM32内部flash闪存的总结


    参考文章:https://blog.csdn.net/jingling122/article/details/100898806
    https://blog.csdn.net/m0_58168670/article/details/130599477
    在这里插入图片描述

    分类: 只读存储器(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的沙扇区,对扇区进行访问或者擦除的时候需要计算出其实地址和结束地址,用户下载数据时候,是从起始地址下载进去的;
    在这里插入图片描述

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

    内部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(批量擦除)执行。执行批量擦除时,不会影响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 位清零 等待擦除完成
      在这里插入图片描述

    通过扇区地址判断扇区号的自定义函数:
    //获取flash的扇区号 通过扇区地址进行获取

    uint32_t GetSector(uint32_t Address) { uint32_t sector = 0;
    if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) {
    sector = FLASH_Sector_0; } else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) {
    sector = FLASH_Sector_1; } else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) {
    sector = FLASH_Sector_2; } else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) {
    sector = FLASH_Sector_3; } else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) {
    sector = FLASH_Sector_4; } else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) {
    sector = FLASH_Sector_5; } else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) {
    sector = FLASH_Sector_6; } else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) {
    sector = FLASH_Sector_7; } else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) {
    sector = FLASH_Sector_8; } else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) {
    sector = FLASH_Sector_9; } else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) {
    sector = FLASH_Sector_10; }
    else/(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))/ {
    sector = FLASH_Sector_11; }
    return sector; //把计算出来的扇区号返回 }
    在这里插入图片描述

    调用这个函数
    if( ==FLASH_EraseSector( FLASH_Sector_10, VoltageRange_3 ==) != FLASH_COMPLETE )

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

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

    具体步骤:
    在这里插入图片描述

    第五步:flash读取

    具体步骤:
    在这里插入图片描述

  • 相关阅读:
    Java:cookie和session区别与原理
    POSTGRESQL中的SQL高级应用案例——等你来挑战
    报错处理:MongoDB在Linux上部署错误及解决方法
    Error response from daemon: Get https://registry-1.docker.io/v2/
    精读A Study of Face Obfuscation in ImageNet
    Tensorflow使用TFRecords和tf.Example
    强制Unity崩溃的两个方法
    python处理保存富文本内容到数据库中报语法错误的问题
    经典设计原则
    Swift学习笔记一(Array篇)
  • 原文地址:https://blog.csdn.net/weixin_44057803/article/details/133935423