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

【经验分享】STM32F103:内部Flash的读写

[复制链接]
STMCU小助手 发布时间:2022-5-4 23:00
一、Flash基本知识
1. Flash容量

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

1、小容量产品:Flash大小为1-32KB(STM32F10X_LD)
2、中容量产品:Flash大小为64-128KB(STM32F10X_MD)
3、大容量产品:Flash大小为256KB以上(STM32F10X_HD)
2. ST库函数
ST库中对Flash操作主要提供了以下几类操作API函数:

2.1 Flash解锁、锁定函数
  1. void FLASH_Unlock(void);    //解锁函数:在对Flash操作之前必须解锁
  2. void FLASH_Lock(void);      //锁定函数:同理,操作完Flash之后必须重新上锁
复制代码

2.2 Flash写操作函数
  1. FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);             //32位字写入函数
  2. FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);         //16位半字写入函数
  3. FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);    //用户选择字节写入函数
复制代码

注:这里需要说明,32 位字节写入实际上是写入的两次 16 位数据,写完第一次后地址+2,这与我们前面讲解的 STM32 闪存的编程每次必须写入 16 位并不矛盾。写入 8位实际也是占用的两个地址了,跟写入 16 位基本上没啥区别。

2.3 Flash擦除函数
  1. FLASH_Status FLASH_ErasePage(uint32_t Page_Address);        //擦除一页
  2. FLASH_Status FLASH_EraseAllPages(void);                                        //擦除所有页
复制代码

2.4 获取Flash状态
  1. FLASH_Status FLASH_GetStatus(void);
复制代码

获取Flash状态函数,主要是为了获取Flash的状态,以便于根据状态对Flash进行操作。该函数返回值是通过枚举类型定义的,在代码中可以看到FLASH_Status类型定义如下(具体含义看注释即可):

  1. typedef enum {
  2.     FLASH_BUSY = 1,       //忙
  3.     FLASH_ERROR_PG,       //编程错误
  4.     FLASH_ERROR_WRP,      //写保护错误
  5.     FLASH_COMPLETE,       //操作完成
  6.     FLASH_TIMEOUT         //操作超时
  7. }FLASH_Status;
复制代码

2.5 等待操作完成函数

  1. FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
复制代码

注:在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。所以在每次操作之前,我们都要等待上一次操作完成这次操作才能开始。

二、Flash的写入和读取
此次操作Flash使用的MCU是STM32F103C8T6,在数据手册中,可以看到STM32F103C8T6的flash起始地址是0x0800 0000,而STM32F103C8T6的Flash大小为64K,可以计算出STM32F103C8T6的Flash地址范围是:0x0800 0000——0x0800 FFFF。这里选取0x0800 F000作为读写操作的起始地址,对于C8T6这款MCU,操作这个起始地址应该算是很安全的范围了。

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

  1. #define STARTADDR 0x0800F000 //STM32F103C8T6适用

  2. /*
  3. * Name:            WriteFlashData
  4. * Function:        向内部Flash写入数据
  5. * Input:            WriteAddress:数据要写入的目标地址(偏移地址)
  6. *             data[]:      写入的数据首地址
  7. *             num:         写入数据的个数
  8. */
  9. void WriteFlashData(uint32_t WriteAddress, uint16_t data, uint32_t num)
  10. {
  11.         uint16_t sign =        0;        //标志位
  12.         
  13.         FLASH_Unlock();     //解锁Flash
  14.         FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);  // 清除所有标志
  15.         sign = FLASH_ErasePage(STARTADDR);        //擦除整页
  16.         if(sign == FLASH_COMPLETE)        //Flash操作完成
  17.         {
  18.                 for(uint32_t i=0;i<num;i++)
  19.                 {
  20.                         FLASH_ProgramHalfWord(STARTADDR+WriteAddress+i*2, data<i>);        //写入数据
  21.                 }
  22.         }
  23.         FLASH_Lock();        //重新锁定Flash
  24. }</i>
复制代码

2.Flash的读取

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

  1. #define STARTADDR 0x0800F000 //STM32F103C8T6适用
  2. /*
  3. * Name:            ReadFlashData
  4. * Function:        从内部Flash读取num字节数据
  5. * Input:            ReadAddress:数据地址(偏移地址)
  6. *              dest_Data:  读取到的数据存放位置指针
  7. *              num:        读取字节个数
  8. */
  9. void ReadFlashData(uint32_t ReadAddress, uint8_t *dest_Data, uint32_t num)
  10. {
  11.         for(uint32_t i=0;i<num;i++)
  12.         {
  13. <i>                dest_Data=*(uint8_t*)(STARTADDR+ReadAddress+i);        //读取数据
  14.         }
  15. }
  16. </i>
复制代码


收藏 1 评论0 发布时间:2022-5-4 23:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版