STM32中存储区分为:随机存取存储器RAM只读存储器ROM。 
其中:

  • RAM为常说的内存,比如手机的2G内存4G内存等,就是程序跑起来的时候所占用的存储空间,特点是掉电数据丢失
  • ROM为常说的硬盘,比如手机的64G和128G等,可以简单的理解为硬盘的存储空间,特点是掉电数据不丢失,所以又叫“非易失性存储器件”。 
    • ROM又包含:EEPROM和flash。

画个嵌入式产品存储器件的思维导图如下(如有什么地方不对,恳请大神们进行指正): 

作为ROM的一份子,flash的特点自然是掉电数据不丢失。但是,flash在STM32中比较重要,程序也是保存在这个地方,所以轻易不让用户进行随意的读写,以避免不必要的问题。

而这篇博客就先简单记录一下flash的访问流程和方法(读和写),具体原理以后理解深刻了再做补充。

1、STM32 FLASH操作流程

Flash操作已经属于嵌入式设备中很底层的操作了,直接对地址进行存取,简单描述,Flash操作大致需要以下流程:

  • 1、确定要写入Flash的首地址(稍后介绍确定地址的方法)
  • 2、解锁Flash
  • 3、对Flash进行操作(写入数据)
  • 4、对Flash重新上锁

1.1 如何查找并选定要写入Flash十六进制地址值的方法

要想选定安全的Flash地址进行读写,可以根据自己的STM32 MCU型号,查找数据手册,确定FLASH的地址区段,因为起始段会存储代码,所以一定要避开起始段,以避免数据错误。(我一般是根据Flash大小计算Flash的最末尾地址,往前推一段地址空间,在这里一般不会对代码中的数据产生覆盖等影响)

我此次操作Flash使用的MCU是STM32103C8T6,所以以该型号MCU为例进行描述:

  • 在数据手册中,可以看到STM32103C8T6的flash起始地址是0x0800 0000(如下图所示),而STM32103C8T6的Flash大小为64K,可以计算出STM32103C8T6的Flash地址范围是:0x0800 0000——0x0800 FFFF(计算方法参考另一篇博客:STM32内存大小与地址的对应关系以及计算方法)。这里选取0x0800 F000作为读写操作的起始地址,对于C8T6这款MCU,操作这个起始地址应该算是很安全的范围了。 

2、Flash基本知识点

2.1 Flash容量

Flash根据容量大小可以分为以下三种:

  • 1、小容量产品:Flash大小为1-32KB(STM32F10X_LD)
  • 2、中容量产品:Flash大小为64-128KB(STM32F10X_MD)
  • 3、大容量产品:Flash大小为256KB以上(STM32F10X_HD)

2.2 ST库对Flash操作的支持

ST库中对Flash操作主要提供了以下几类操作API函数:

  • 1、Flash解锁、锁定函数

    • void FLASH_Unlock(void);//解锁函数:在对Flash操作之前必须解锁
    • void FLASH_Lock(void);//锁定函数:同理,操作完Flash之后必须重新上锁
  • 2、Flash写操作函数 
    • FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);//32位字写入函数
    • FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);//16位半字写入函数
    • FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);//用户选择字节写入函数 
      注:这里需要说明,32 位字节写入实际上是写入的两次 16 位数据,写完第一次后地址+2,这与我们前面讲解的 STM32 闪存的编程每次必须写入 16 位并不矛盾。写入 8位实际也是占用的两个地址了,跟写入 16 位基本上没啥区别。
  • 3、Flash擦除函数 
    • FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
    • FLASH_Status FLASH_EraseAllPages(void);
    • FLASH_Status FLASH_EraseOptionBytes(void);
  • 4、获取Flash状态 
    • FLASH_Status FLASH_GetStatus(void); 
      获取Flash状态函数,主要是为了获取Flash的状态,以便于根据状态对Flash进行操作。该函数返回值是通过枚举类型定义的,在代码中可以看到FLASH_Status类型定义如下(具体含义看注释即可):
    • typedef enum 
                                                       { 
                                                          FLASH_BUSY = 1,        //忙 
                                                          FLASH_ERROR_PG,      //编程错误 
                                                          FLASH_ERROR_WRP,   //写保护错误 
                                                          FLASH_COMPLETE,      //操作完成 
                                                          FLASH_TIMEOUT         //操作超时 
                                                        }FLASH_Status;
  • 5、等待操作完成函数 
    • FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); 
      注:在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。所以在每次操作之前,我们都要等待上一次操作完成这次操作才能开始。

3、OK,上干货,上代码

根据ST库提供的上述函数,我们可以自己编写Flash的读写操作代码如下:

3.1 先定义一个Flash操作的起始地址宏定义Flash状态指示标志位

#define STARTADDR 0x0800F000 //STM32F103C8T6适用volatile FLASH_Status FLASHStatus = FLASH_BUSY; //Flash操作状态变量

3.2 编写各个读写函数

//
// Name:        WriteFlashOneWord
//
// Function:    向内部Flash写入32位数据
//
// Input:       WriteAddress:数据要写入的目标地址(偏移地址)
//              WriteData:   写入的数据
//
void WriteFlashOneWord(uint32_t WriteAddress, uint32_t WriteData)
{   FLASH_UnlockBank1();FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);FLASHStatus = 1;    //清空状态指示标志位FLASHStatus = FLASH_ErasePage(STARTADDR);  if(FLASHStatus == FLASH_COMPLETE)   {  FLASHStatus = 1;    //清空状态指示标志位FLASHStatus = FLASH_ProgramWord(STARTADDR+WriteAddress, WriteData); //flash.c 中API函数}FLASHStatus = 1;    //清空状态指示标志位FLASH_LockBank1();
}//
// Name:        WriteFlashData
//
// Function:    向内部Flash写入数据
//
// Input:       WriteAddress:数据要写入的目标地址(偏移地址)
//              data[]:      写入的数据首地址
//              num:         写入数据的个数
//
void WriteFlashData(uint32_t WriteAddress, uint8_t data[], uint32_t num)
{uint32_t i = 0;uint16_t temp = 0;FLASH_UnlockBank1();    //解锁flashFLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); FLASHStatus = 1;        //清空状态指示标志位FLASHStatus = FLASH_ErasePage(STARTADDR);//擦除整页if(FLASHStatus == FLASH_COMPLETE)//flash操作完成{FLASHStatus = 1;    //清空状态指示标志位for(i=0; i<num; i++){temp = (uint16_t)data[i];FLASHStatus = FLASH_ProgramHalfWord(STARTADDR+WriteAddress+i*2, temp);//写入数据}}FLASHStatus = 1;    //清空状态指示标志位FLASH_LockBank1();  //锁定flash
} 

//
// Name:        ReadFlashNBtye
//
// Function:    从内部Flash读取N字节数据
//
// Input:       ReadAddress:数据地址(偏移地址)
//              ReadBuf:读取到的数据存放位置指针
//              ReadNum:读取字节个数
//
// Output:      读取的字节数
//
int ReadFlashNBtye(uint32_t ReadAddress, uint8_t *ReadBuf, int32_t ReadNum)
{   int DataNum = 0;ReadAddress = (uint32_t)STARTADDR + ReadAddress;  while(DataNum < ReadNum)   {        *(ReadBuf + DataNum) = *(__IO uint8_t*) ReadAddress++;  DataNum++;     }return DataNum;
}//
// Name:        ReadFlashData
//
// Function:    从内部Flash读取num字节数据
//
// Input:       ReadAddress:数据地址(偏移地址)
//              dest_Data:  读取到的数据存放位置指针
//              num:        读取字节个数
//
void ReadFlashData(uint32_t ReadAddress, uint8_t *dest_Data, uint32_t num)
{int i = 0;ReadAddress = (uint32_t)STARTADDR + ReadAddress; while(i < num) {*(dest_Data+i) = *(__IO uint16_t*) ReadAddress;ReadAddress += 2;i++;}
}来源:https://blog.csdn.net/Ace_Shiyuan/article/details/78196648

STM32的Flash相关推荐

  1. map文件分析 stm32_使用STM32内部Flash额外的空间来存储数据

    本次分享关于STM32内部FLASH的笔记. STM32 芯片内部的 FLASH 存储器,主要用于存储我们代码.如果内部FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利用起来, ...

  2. STM32 内部Flash读写 程序源码 [已验证]

    目录 STM32 内部Flash带缓存读写 程序源码 0 Macro 1.Flash_Erase 2. Flash_Read_Byte 3.Flash_Write_NoBuffer 4.Flash_W ...

  3. stm32内部Flash读写

    文章目录 1.stm32内部flash介绍 2.读写驱动编写 3.源码 上篇文章讲到了STM32来驱动外部flah的操作,flash真是好东西啊,内存大,能存的东西多,这样我们就可以用它来做一些大点的 ...

  4. 关于STM32的Flash使用规划以及程序设计(以f407ZGT6为例)

    关于STM32的Flash使用规划以及程序设计(以f407ZGT6为例) 在涉及到比较多功能应用的时候,我们在对单片机内存资源的应用也是做一些规划比较好.不可胡乱的做内存的划分. 1.STM32F40 ...

  5. 基于STM32的Flash擦除方式

    基于STM32的Flash擦除方式 前言 介绍 STM32 FLASH 闪存的编程和擦除 Flash擦除的标准库函数 软件设计 直接使用固件库函数擦除当前地址所在的内容 擦除对应地址和大小的Flash ...

  6. STM32 擦除flash失败问题

    硬件平台STM32F407VE,HAL库.标准库不会有此问题 软件跑freertos 问题描述:STM32 擦除flash失败,CPU跳不出串口中断,看门狗重启. 问题一.FlashStatus!=H ...

  7. 17-1-数据处理思想和程序架构: 单片机stm32的flash保存数据优化方案(让擦写次数达到上百万至上千万次)

    资料源码:https://gitee.com/yang456/OpenProgrammingModuleForMCU.git 点击加入群聊[单片机,物联网,上位机]: 说明1:知识从未如此性感. 烂程 ...

  8. STM32内部flash详解(1)

    STM32 内部FLAsh概述 今天说一下STM32中的内部flash. 当我们把写好的代码下载MCU中,这个代码时存放在flash中的.当芯片重启复位上电后,会通过内核对flash进行代码的加载运行 ...

  9. stm32的flash和ram占用情况

    stm32的flash和ram占用情况 在stm32中flash就是ROM,掉电数据不会丢失:(通常保存着text段.Code.Ro-data.Rw-data) RAM就是运行内存,掉电数据就丢失:( ...

  10. STM32外挂FLASH模拟U盘(基于HAL库)

    STM32外挂FLASH模拟U盘(基于HAL库) 1.背景 1.1这篇文章能给你带来什么 1.2根据你要解决的问题,精确快速跳转到相应位置 1.3我在做完这个后还有不明白的地方,希望能有大触解答困惑 ...

最新文章

  1. plsql执行command命令控制台出现乱码_设计模式系列 — 命令模式
  2. 取消显示fps的指令_机器人控制指令介绍(一)
  3. yolo 标注转VOC格式(标注转换器)
  4. 如何使用Ubuntu打电话
  5. hashmap 不释放空间_刁难问题,为什么HashMap默认容量为16加载因子为0.75
  6. 参数方程求二阶偏导_偏微分方程
  7. python 接口自动化测试_Python-基于数据驱动的接口自动化测试
  8. C# WindowService 动态修改服务名
  9. IDEA 常用设置 与 常用操作(三)
  10. 今天和孝辉一起去交大买书了!
  11. FUP A17H/A17CH 微量高速冷冻离心机的优劣势
  12. 计算机出现假桌面怎么解决办法,W10电脑下“AppHangXProcB1”导致桌面频繁假死如何解决?...
  13. 厦门大学计算机考研复试线2021,【厦门大学】2021考研复试分数线3月13日已公布!速看!...
  14. 网站虚拟主机是什么?(什么是虚拟主机空间)
  15. ❤️❤️马上安排!闺女想在游戏里成为【超人】,Python游戏开发模块Pygame系列之【跳跃的小球】❤️❤️源码
  16. Openpose2d转换3d姿态识别
  17. VTK移动立方体法创建多个等值面的透视3D模型
  18. 初步学习MOOS-ivp
  19. 艾永亮:超级产品战略助戴森品牌C位出道,它却在汽车行业栽跟头
  20. ubuntu安装显卡问题

热门文章

  1. 在ubuntu用audacity把音频转换成256kbps,单声道。(亲测有效)
  2. c语言 发纸牌 实验报告,“21点”纸牌游戏实验报告
  3. Coursera 申请助学金流程和材料
  4. (五)作业Job和实例Instance | 普罗米修斯(Prometheus)
  5. win10更新后IE不见了
  6. PDF打开后名称与实际文件名称不符的解决
  7. java实现将PDF文件拆分成图片
  8. 网页游戏外挂辅助AMF模拟通讯必备
  9. eclipse建java gui工程,Eclipse java swing开发环境搭建教程
  10. PySpark+Prophet