admin管理员组文章数量:1566354
文章目录
- FLASH
- 闪存模块存储器组织
- 组成
- FLASH闪存的读取
- 编程和擦除操作
- 注意事项
- 标准编程步骤
- 闪存擦除
- FLASH操作相关寄存器
- FLASH访问控制寄存器
- FLASH秘钥寄存器
- FLASH控制寄存器
- 库函数
FLASH
通常指FLASH MEMORY 即闪存 全名叫FLASH EEPROM Memory
结合了POM和RAM的长处 不仅具备电子可擦除编程性能 还可以 快速读取数据(NVRAM的优势)
数据断电不会消失
应用有U盘 MP3
闪存模块存储器组织
组成
① 主存储器
存放代码 和 数据常数 分12个扇区
② 系统存储器
主要存放BootLoader代码 固化 专门给主存储器下载代码
存储器启动 即进入串口下载模式
③ OPT区域
一次性可编程区域 被分为五个部分 前512字节 可用来存储用户数据 一次性
后面16个字节 用于锁定对应块
④ 选项字节
配置 读保护 BOR级别 软硬件看门狗 以及 器件处于待机模式或停止模式下的保护服务
FLASH闪存的读取
动用语句:data =(vu32)addr;
将addr强制转换为vu32 指针 然后取该指针所指向的地址的 值 即得到addr地址的值
准确读取 要根据CPU时钟频率 和 器件 电压 在Flash存取控制寄存器
FLASH_ACR 中正确设置等待周期数
供电电压一般是3.3V 所以 在设置168Mhz频率作为CPU时钟之前 必须先设置LATENCY为5
否则fLASH 读写可能出错 导致死机
编程和擦除操作
在对Flash执行写入擦除操作时 任何读取flash的操作都会导致总线阻塞
闪存编程控制器:
FLASH访问控制寄存器
FLASH秘钥寄存器
FLASH选项秘钥寄存器
FLASH状态寄存器
FLASH控制寄存器
FLASH选项控制寄存器
注意事项
写保护被解除后 才能操作相关寄存器
FLASH_CR解锁序列:
若写入错误 则FLASH_CR 将被锁定 直到下次复位后才可以再次解锁
标准编程步骤
① 检查FLASH_SR中的BSY位
②将FLASH_CR寄存器中的PG位置1 激活flash编程
③真对所需存储器地址 执行数据写入操作
并行位数 x8时按字节写入 PSIZE==00
为x16时按半字写入 PSIZE=01
为x32时按字写入 PSIZE=02
为x64时按双字写入 PSIZE=03
④等待BSY位清零 完成一次编程
闪存擦除
分两种:
扇区擦除 整片擦除
擦除步骤:
① 检查解锁
② 检查BSY位
③ 将SER位置1 并从主存储块的12个扇区中选择要擦除的扇区
④ STRT位置1 触发擦除操作
⑤等待BSY清零
批量擦除:
① 检查BSY位
②将MER位置1
③将STRT位置1 触发擦除操作
④等待BSY位清零
FLASH操作相关寄存器
FLASH访问控制寄存器
FLASH秘钥寄存器
FLASH控制寄存器
库函数
//读取指定地址的半字
u32 STMFLASH_ReadWord(u32 faddr)
{
return *(vu32*)faddr;
}
//返回某地址所在的扇区
uint16_t STMFLASH_GetFlashSector(u32 addr)
{
if(addr<ADDR_FLASH_SECTOR_1)return FLASH_Sector_0;
else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_Sector_1;
else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_Sector_2;
else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_Sector_3;
else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_Sector_4;
else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_Sector_5;
else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_Sector_6;
else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_Sector_7;
else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_Sector_8;
else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_Sector_9;
else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_Sector_10;
return FLASH_Sector_11;
}
//写函数 在指定地址写入一定长度的数据
void STMFLASH_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(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方擦除这个扇区
{
status=FLASH_EraseSector(STMFLASH_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();//上锁
}
//读数据
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
{
u32 i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节
ReadAddr+=4;//偏移四个字节
}
}
版权声明:本文标题:FLASH闪存 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1725875494a1046605.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论