FLASH

1.FLASH介绍

**主存储器:**分为4个16KB扇区、1个64KB扇区和7个128KB扇区。boot0/boot1都接GND时从0x08000000开始运行代码。

**系统存储器:**器件在系统存储器自举模式下从该存储器启动,主要存放芯片的bootloader代码,此代码出厂时固化在芯片内部了。用于给主存储器下载代码。当boot0接3.3V、boot1接GND时从此处开始运行,即进入串口下载模式。

**OTP区域:**512字节OTP(一次性可编程),用于存储用户数据。OTP区域还有额外的16个字节,用于锁定对应的OTP数据块。

**选项字节:**用于配置读写保护、BOR级别、软件/硬件看门狗以及器件处于待机或停止模式下的复位。

1.1闪存的编程和擦除

STM32F4的闪存编程由6个32位寄存器控制:

(1)FLASH访问控制寄存器(FLASH_ACR)

(2)FLASH秘钥寄存器(FLASH_KEYR)

(3)FLASH选项秘钥寄存器(FLASH_OPTKEYR)

(4)FLASH状态寄存器(FLASH_SR)

(5)FLASH控制寄存器(FLASH_CR)

(6)FLASH选项控制寄存器(FLASH_OPTCR)

STM32F4复位后,FLASH编程操作是被保护的,不能写入FLASH_CR。

FALSH_CR解锁步骤为:

(1)写0X45670123到FLASH_KEYR

(2)写0XCDEF89AB到FLASH_KEYR

STM32F4闪存的编程位数通过FLASH_CR的PSIZE字段设置,PSIZE的设置必须和电源电压匹配。

STM32F4标准编程步骤:

(1)检查FLASH_SR中的BSY位,确保当前未执行任何FLASH操作。

(2)将FLASH_CR寄存器中的PG位置1,激活FLASH编程。

(3)执行写入操作

(4)等待BSY位清零,完成一次编程。

扇区擦除步骤:

(1)检查FLASH_CR的LOCK是否解锁,如果没有先解锁

(2)检查FLASH_SR寄存器中的BSY位,确保当前未执行任何FLASH操作

(3)在FLASH_CR寄存器中,将SER位置1,并从主存储块的12个扇区中选择要擦除的扇区(SNB)

(4)将FLASH_CR寄存器中的STRT位置1,触发擦除操作

(5)等待BSY位清零

2.相关寄存器

3.配置方法

3.1 内部flash分步操作

3.1.1解锁和锁定
#define FLASH_KEY1               ((uint32_t)0x45670123)
#define FLASH_KEY2               ((uint32_t)0xCDEF89AB)
#define FLASH_CR_LOCK            ((uint32_t)0x80000000)
//解锁函数
void FLASH_Unlock(void)
{if((FLASH->CR & FLASH_CR_LOCK) != RESET){/* Authorize the FLASH Registers access */FLASH->KEYR = FLASH_KEY1;FLASH->KEYR = FLASH_KEY2;}
}
//锁定函数
void FLASH_Lock(void)
{/* Set the LOCK Bit to lock the FLASH Registers access */FLASH->CR |= FLASH_CR_LOCK;
}
3.1.2写操作
//写入双字
FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR &= CR_PSIZE_MASK;FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;FLASH->CR |= FLASH_CR_PG;*(__IO uint64_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();/* if the program operation is completed, disable the PG Bit */FLASH->CR &= (~FLASH_CR_PG);} /* Return the Program Status */return status;
}
//写入字
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR &= CR_PSIZE_MASK;FLASH->CR |= FLASH_PSIZE_WORD;FLASH->CR |= FLASH_CR_PG;*(__IO uint32_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();/* if the program operation is completed, disable the PG Bit */FLASH->CR &= (~FLASH_CR_PG);} /* Return the Program Status */return status;
}
//写入半字
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR &= CR_PSIZE_MASK;FLASH->CR |= FLASH_PSIZE_HALF_WORD;FLASH->CR |= FLASH_CR_PG;*(__IO uint16_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();/* if the program operation is completed, disable the PG Bit */FLASH->CR &= (~FLASH_CR_PG);} /* Return the Program Status */return status;
}
//写入字节
FLASH_Status FLASH_ProgramByte(uint32_t Address, uint8_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();if(status == FLASH_COMPLETE){/* if the previous operation is completed, proceed to program the new data */FLASH->CR &= CR_PSIZE_MASK;FLASH->CR |= FLASH_PSIZE_BYTE;FLASH->CR |= FLASH_CR_PG;*(__IO uint8_t*)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation();/* if the program operation is completed, disable the PG Bit */FLASH->CR &= (~FLASH_CR_PG);} /* Return the Program Status */return status;
}
3.1.3擦除操作
//FLASH_Sector:选择擦除扇区
//VoltageRange:选择电源电压范围
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange);
FLASH_Status FLASH_EraseAllSectors(uint8_t VoltageRange);
FLASH_Status FLASH_EraseAllBank1Sectors(uint8_t VoltageRange);
FLASH_Status FLASH_EraseAllBank2Sectors(uint8_t VoltageRange);
3.1.4获取FLASH状态
FLASH_Status FLASH_GetStatus(void)
{FLASH_Status flashstatus = FLASH_COMPLETE;if((FLASH->SR & FLASH_FLAG_BSY) == FLASH_FLAG_BSY) {flashstatus = FLASH_BUSY;}else {  if((FLASH->SR & FLASH_FLAG_WRPERR) != (uint32_t)0x00){ flashstatus = FLASH_ERROR_WRP;}else{if((FLASH->SR & FLASH_FLAG_RDERR) != (uint32_t)0x00){ flashstatus = FLASH_ERROR_RD;} else {if((FLASH->SR & (uint32_t)0xE0) != (uint32_t)0x00){flashstatus = FLASH_ERROR_PROGRAM; }else{if((FLASH->SR & FLASH_FLAG_OPERR) != (uint32_t)0x00){flashstatus = FLASH_ERROR_OPERATION;}else{flashstatus = FLASH_COMPLETE;}}}}}/* Return the FLASH Status */return flashstatus;
}

返回值是通过枚举类型定义的

typedef enum
{ FLASH_BUSY = 1,//操作忙FLASH_ERROR_RD,//读保护错误FLASH_ERROR_PGS,//编程顺序错误FLASH_ERROR_PGP,//编程并行位数错误FLASH_ERROR_PGA,//编程对齐错误FLASH_ERROR_WRP,//写保护错误FLASH_ERROR_PROGRAM,//编程错误FLASH_ERROR_OPERATION,//操作错误FLASH_COMPLETE//操作结束
}FLASH_Status;
3.1.5等待操作完成

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

FLASH_Status FLASH_WaitForLastOperation(void)
{ __IO FLASH_Status status = FLASH_COMPLETE;/* Check for the FLASH Status */status = FLASH_GetStatus();/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.Even if the FLASH operation fails, the BUSY flag will be reset and an errorflag will be set */while(status == FLASH_BUSY){status = FLASH_GetStatus();}/* Return the operation status */return status;
}
3.1.6读取FLASH指定地址数据
//读取指定地址的字(32 位数据)
//faddr:读地址
//返回值:对应数据.
u32 STMFLASH_ReadWord(u32 faddr)
{ return *(u32*)faddr; }

3.2FLASH读数据函数

//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToRead:字(4位)数
void STM32_FLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
{u32 i;for(i=0;i<NumToRead;i++){pBuffer[i]=STM32_FLASH_ReadWord(ReadAddr);//读取4个字节.ReadAddr+=4;//偏移4个字节.   }
}

3.3FLASH写数据函数

//从指定地址开始写入指定长度的数据
//特别注意:因为STM32F4的扇区实在太大,没办法本地保存扇区数据,所以本函数
//         写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
//         写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
//         没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
//该函数对OTP区域也有效!可以用来写OTP区!
//OTP区域地址范围:0X1FFF7800~0X1FFF7A0F
//WriteAddr:起始地址(此地址必须为4的倍数!!)
//pBuffer:数据指针
//NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
void STM32_FLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{ FLASH_Status status = FLASH_COMPLETE;u32 addrx=0;u32 endaddr=0;    if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;   //非法地址FLASH_Unlock();                                   //解锁 FLASH_DataCacheCmd(DISABLE);//FLASH擦除期间,必须禁止数据缓存addrx=WriteAddr;              //写入的起始地址endaddr=WriteAddr+NumToWrite*4;  //写入的结束地址if(addrx<0X1FFF0000)            //只有主存储区,才需要执行擦除操作!!{while(addrx<endaddr)        //扫清一切障碍.(对非FFFFFFFF的地方,先擦除){if(STM32_FLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区{   status=FLASH_EraseSector(STM32_FLASH_GetFlashSector(addrx),VoltageRange_3);//VCC=2.7~3.6V之间!!if(status!=FLASH_COMPLETE)break;  //发生错误了}else addrx+=4;} }if(status==FLASH_COMPLETE){while(WriteAddr<endaddr)//写数据{if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)//写入数据{ break;   //写入异常}WriteAddr+=4;pBuffer++;} }FLASH_DataCacheCmd(ENABLE);    //FLASH擦除结束,开启数据缓存FLASH_Lock();//上锁
}
//这个宏定义用法保存一下,挺好
const u8 text_buf[]="www.prechin.net";
#define TEXTLEN sizeof(text_buf)
#define TEXTSIZE (TEXTLEN/4+((TEXTLEN%4)?1:0))

讲解不到位的希望大家指出,有需要我讲解的部分,希望大家提出,我会出文档讲解。

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详解(1)

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

  5. 读写STM32内部flash读写代码

    读写STM32内部flash读写代码 由于老师的要求,所以写了一份读写STM32内部FLASH的代码,这样的话就可以把STM32里面没有用来保存代码段的部分用来存储数据了. 由于<stm32fl ...

  6. STM32CubeMX系列|STM32内部FLASH

    STM32内部FLASH 1. 内部FLASH简介 之前的文章中介绍过STM32F1利用SPI与外部FLASH(W25QXX芯片)通讯的例程,本例程将介绍STM32F1的内部FLASH,通过内部FLA ...

  7. STM32内部Flash的使用

    简介 STM32内部自带不同大小的Flash,其主要功能是保存已经编译完成的代码.在实际的产品中为了节约成本如果有需要存储少量的数据会选择存放在内部Flash中. 注:STM32对于Flash 大小的 ...

  8. c语言flash里能存文件吗,STM32内部FLASH打包读写

    最近做到的项目在运行需要把一组uint8_t(unsigned char)的数据进行掉电储存,想到单片机STM32f030f4p6内部flash可以直接由程序操作,写了以下代码用于uint8_t数据打 ...

  9. 【STM32】STM32内部flash编程和擦除

    一直在想设计OTA方案,使用开源的软件工具实现OTA,因为涉及较多,暂未完成... 关于OTA设计,可以先参考IAP:[IAP]IAP在线升级流程,涉及对芯片BootLoader和flash操作:升级 ...

  10. STM32内部Flash读写问题

    STM32Flash读写之Flash调试技巧 文章目录 1.先熟悉所用MCU的Flash存储大小以及扇区地址 2.Flsah写之前为什么要先擦除 3.Flash擦除长时间占用CPU 4.实测Flash ...

最新文章

  1. Qt for Android获取手机热点开关状态
  2. linux交叉编译无法识别gcc编译器
  3. MySQL 覆盖索引、最左前缀原则、索引下推
  4. modern android5.1,Modern摩登印
  5. can硬件滤波 stm32cubemx_[转载]STM32的CAN滤波器设置
  6. Python如何从社交用户信息中寻找潜在客户?
  7. Linux作者批评英特尔指令集,Linux之父炮轰英特尔:ECC内存很重要,不好买都怪你胡搞...
  8. chm 转 html 带索引,chm 的项目文件中包含创建 chm 文件所需的HTML文件信息、目录表文件信息、索引文件信息、窗口属 - 试题答案网问答...
  9. 模糊控制算法在MATLAB/SIMULINK中的应用
  10. 如何将App程序发布到苹果App Store
  11. PyTorch学习(二):Transform
  12. EasyExcel简单使用学习
  13. java 打开url连接访问不了,android 应用Java自带的HttpURLConnection 连接网络 读取返回数据...
  14. 宏碁施振荣:大陆是国际化的练兵场
  15. 安装CV2,安装opencv
  16. (已解决)jar!/BOOT-INF/classes!/application.yml (No such file or directory)
  17. 非常好用的PC端软件,个个都是宝藏!
  18. linux查看gcccmake当前版本
  19. ros2 foxy 设置publisher与subscription的qos
  20. 针对广州这一城市,运用Python来进行数据分析房地产市场

热门文章

  1. 【2016年第1期】大数据环境下的管理信息系统发展研究
  2. c语言kmp算法代码,C语言KMP算法的实现
  3. 局域网、以太网(标准以太网、工业以太网和实时以太网)与无线局域网
  4. 想要提高网站关键词排名需要注意什么?
  5. 计算机网络的定义及其特点(谢希仁)
  6. 单机秒杀系统的架构设计与实现
  7. unity avPro player PC 版本 黑屏问题,有声音
  8. 如何在华为应用市场上架新应用
  9. 中国现代书画家——彭双全、韩隐、冯尧成、周承启
  10. 计算机二级ms考试知识点,计算机二级Ms office考试考点总结