目录
一、FLASH简介
1.1读写FLASH的用途:
1.2闪存模块组织
1.3FLASH基本结构
二、FLASH相关操作
2.1解锁
2.2指针访问寄存器
2.3擦除和编程
三、选项字节
3.1选项字节擦除
3.2选项字节编程
3.3 软件设置
四、器件电子签名
五、接口实现
5.1 底层
5.2 应用层
5.3 小应用
STM32F1系列的FLASH由程序存储器(存储代码)、系统存储器(原厂写入不可修改的Bootloader)、选项字节(独立配置参数)三部分组成,其中程序存储器和选项字节可通过闪存存储器接口来操作(实际就是一个外设,相当于“管理员”,可进行擦除和编程)
关于bootloader,也叫自举程序,用途是程序自我更新,串口下载。在程序更新过程中,bootloader接收usart1数据,刷新到程序存储器,这时主程序还处于瘫痪状态。刷新完成,再启动主程序,就可以执行新程序,相当于“刷机”
1.1读写FLASH的用途:
- 利用程序存储器中的剩余空间来保存需要掉电不丢失的用户数据
- 程序中编程(IAP),实现程序的自我更新
IAP:In Application Programming,程序中编程,可支持任一种通信接口下载更新程序
ICP:In Circuit Programming,在线/电路中编程,用于更新程序存储器中的全部内容,它通过JTAG、SWD协议(ST-Link)或Bootloader(串口)进行下载程序
1.2闪存模块组织
以中容量为例:
1.3FLASH基本结构
2.1解锁
对于FLASH的解锁(读不用解锁!)相当于W25Q64中的写使能,实际是对FLASH_KEYR寄存器进行操作
- FPEC共有3个键值:PDPRT键、KEY1、KEY2(都可自定义)
- 解锁操作通过先写KEY1、再写KEY2
- 上锁通过FLASH_CR的LOCK位锁住FPEC和FLASH_CR
- 复位后FPEC被保护不可写,误操作顺序会锁死直到复位
2.2指针访问寄存器
因为对于闪存的编程是以页为单位,为避免覆盖和有序使用,往往根据地址来操作,与地址相关当然用指针比较高效
- 读寄存器:uint16_t Data = *((__IO uint16_t *)(0x8000 0400));
- 写寄存器: *((__IO uint16_t *)(0x8000 0400)) = 0x1234;
其中:#define __IO volatile 表示易变数据,防止编译器优化。keil编译器默认是最低优化等级,对于编译器的优化可以用来去除无用的代码、降低代码空间,提高执行效率。但优化之后,可能会在某些地方弄巧成拙,比如利用变量计数空循环实现延时就可能被优化掉。另外,编译器还会利用缓存来加速代码,比如要频繁读写内存的某个数据,最常见的优化方式就是先把数据转移到高速缓存,在这里面进行读写速度会更高效,用完写回内存即可,但如果在读写过程中,同时程序有多个线程,比如中断函数中改变了原始数据,但高速缓存并不知情,就会导致更改数据不同步,这时候加上volatile就能避免这类问题
2.3擦除和编程
1.全擦除流程
判断是否要解锁->FLASH_CR中的MER=1(表示全擦)、START=1(启动擦除)->循环擦除同时判断忙状态
2.页擦除流程
判断是否要解锁->FLASH_CR中的PR=1(表示页擦)、写页起始地址选择要擦的页、START=1(启动擦除)->循环擦除同时判断忙状态
3.编程/写入
写前会自动检查有没有擦除(尤其是写1,因为FLASH里的数据只能由1变0而不能由0变1)
判断是否要解锁->FLASH_CR中的PG=1(表示编程)->在指定地址写入半字(启动编程)
注意:任何对于闪存的读写操作都会导致CPU暂停,其他代码会得不到执行,对中断的影响尤为严重!
3.1选项字节擦除
3.2选项字节编程
3.3 软件设置
ST-Link Utility中对于选项字节读保护、写保护可以便捷设置
其实就是STM32的ID号,电子签名存放在闪存的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,可通过指针读指定地址下的存储器获取电子签名
- 闪存容量寄存器, 基地址:0x1FFF F7E0,大小16位
- 产品唯一身份标识寄存器,基地址:0x1FFF F7E8,大小96位
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/24761.html