单片机FLASH深度解析和编程实践(上)

本篇文章主要针对单片机FLASH编程和FLASH基本原理进行学习分享。以STM32单片机作为实例进行编程实训。

关于FLASH操作的相关寄存器及编程,大家可以参考下一篇文章:

单片机FLASH深度解析和编程实践(下)-CSDN博客

目录

一、STM32编程方式

 二、闪存模块存储器组织(以STM32F767IGT为例)

 1、主存储器

2、系统存储器 

3、OPT区域 

4、选项字节 

 三、FLASH闪存操作

(一)、FLASH闪存的读取

注意 

(二)、FLASH闪存的编程(写)和擦除操作 

(三)、FLASH编程注意事项 

(四)、STM32的标准编程步骤

四、闪存擦除

(一)、扇区擦除的步骤 

(二)、批量擦除的步骤 

 五、FLASH中断

 六、结语


 

一、STM32编程方式

1在线编程(ICP,In-Circuit Programming):
通过JTAG/SWD协议或者系统加载程序(Bootloader)下载用户应用程序到微控制器中。


2在程序中编程(IAPIn Application Programming):

通过任何一种通信接口(如IO端口,USB, CAN,UART,I2C,SPI等)下载程序或者应用数据到存储器中。也就是说,STM32允许用户在应用程序中重新烧写闪存存储器中的内容。然而,IAP需要至少有一部分程序已经使用ICP方式烧到闪存存储器中(Bootloader).

 二、闪存模块存储器组织(以STM32F767IGT为例)

储器组织分为四个部分,分别是主存储器、系统存储器、OPT区域、选项字节。

 1、主存储器

该部分用来存放代码和数据常数(如const类型的数据)。它可以分为1个Bank或者2个Bank,可以通过选项字节的nDBANK位来设置,默认是1个bank,也就是单Bank模式。


在单Bank模式下,STM32F767的主存储器被分为8个扇区,前4个扇区为32KB大小,第五个扇区是128KB大小,剩下的3个扇区都是256KB大小,总共1M字节。


因为STM32F7的FLASH访问路径有两条:AXIM和ITCM,对应不同的地址映射,表中我们列出了这两条不同访问路径下的扇区地址范围。我们一般选择AXIM接目访问FLASH,其主存储器的起始地址就是ox08000000。


B0、B1都接GND的时候,就是从OX08000000开始运行代码的。

2、系统存储器 

这个主要用来存放STM32的bootloader代码,此代码是出厂的时候就固化在STM32里面了,专门来给主存储器下载代码的。当B0接V3.3,B1接GND的时候,从该存储器启动(即进入串口下载模式)。

3、OPT区域 

OTP区域,即一次性可编程区域,共1056字节,被划分为16个64字节的OTP 数据块和1个16字节的OTP锁定块。OTP数据块和锁定块均无法擦除。锁定块中包含16字节的 LOCKBi (0 <= i <= 15),用于锁定相应的OTP数据块(块0到15)。每个OTP数据块均可编程,除非相应的OTP锁定字节编程为0x00。锁定字节的值只能是0x0和0xFF,否则这些OTP字节无法正确使用。

4、选项字节 

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

闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。


在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行;既在进行写或擦除操作时,不能进行代码或数据的读取操作。

 三、FLASH闪存操作

(一)、FLASH闪存的读取

STM32的FLASH读取是很简单的。例如,我们要从地址addr ,读取一个字(字节为8位,半字为16位,字为32位),可以通过如下的语句读取:

将addr强制转换为vu32指针,然后取该指针所指向的地址的值,即得到了addr地址的值。类似的,将上面的vu32改为vu16,即可读取指定地址的一个半字。相对FLASH读取来说,STM32 FLASH的写就复杂一点了,下面我们介绍STM32闪存的编程和擦除。

注意 

为了准确读取 Flash数据,必须根据CPU时钟 (HCLK)频率和器件电源电压在 Flash存取控制寄存器(FLASH ACR)中正确地设置等待周期数(LKTENCY)。Flash等待周期与CPU时钟频率之间的对应关系:

等待周期通过FLASHAC寄存器的LATENCY[3:0]四三个位设置。系统复位后,CPU时钟频率为内部16MRC振荡器,LATENCY默认是0,即1个等待周期。供电电压,我们一般是3.3V,所以,在我们设置216Mhz频率作为CPU时钟之前,必须先设置LATENCY为7,即8个等待周期,否则FLASH读写可能出错,导致死机。


正常工作时(216Mhz),虽然FLASH需要8个CPU等待周期,但是由于STM32F767具有自适应实时存储器加速器(ARTAccelerator),通过指令缓存存储器,预取指令,实现相当于0 FLASH等待的运行速度。

(二)、FLASH闪存的编程(写)和擦除操作 

在对 STM32的Flash执行写入或擦除操作期间,任何读取Flash的尝试都会导致总线阻塞。只有在完成编程操作后,才能正确处理读操作。这意味着,写/擦除操作进行期间不能从Flash中执行代码或数据获取操作。

 STM32的闪存编程由7个32位寄存器控制。

(三)、FLASH编程注意事项 

Step1:

STM32复位后,FLASH编程操作是被保护的,不能写入FLASH_CR寄存器;
通过写入特定的序列(0X45670123和OXCDEF89AB)到FLASH_KEYR寄存器才可解除写保护,只有在写保护被解除后,我们才能操作相关寄存器。FLASH_CR的解锁序列为:


1)写0X45670123 ( KEY1)到FLASH_ KEYR

2)写OXCDEF89AB(KEY2)到FLASH_KEYR


通过这两个步骤,即可解锁FLASH_CR,如果写入错误,那么FLASH_CR将被锁定,直到下次复位后才可以再次解锁。

Step2:

STM32闪存的编程位数可以通过FLASH_CR的PSIZE字段配置,PSIZE的设置必须和电源电压匹配,由于我的开发板用的电压是3.3V,所以PSIZE必须设置为10,即32位并行位数。擦除或者编程,都必须以32位为基础进行。

Step3:

STM32的FLASH在编程的时候,也必须要求其写入地址的FLASH是被擦除了的(也就是其值必须是0XFFFFFFFF ),否则无法写入。

(四)、STM32的标准编程步骤

按照以上四步操作,就可以完成一次FLASH编程。但是需要注意一下:

1、编程之前,必须确保要写入地址的FLASH已经擦除 ;

2、需要先解锁,否则不能操作FLASH;

3、编程操作对OPT区域也有效,方法一摸一样。

四、闪存擦除

我们在STM32的FLASH编程的时候,要先判断缩写地址是否被擦除了,所以,我们有必要再介绍-下STM32的闪存擦除,STM32的闪存擦除分为两种:
①扇区擦除

②整片擦除。

(一)、扇区擦除的步骤 

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

2、检查FLASH_SR寄存器中的BSY位,确保当前未执行任何FLASH操作
3、在FLASH_CR寄存器中,将SER位置1,并从主存储块的12个扇区中选择要擦除的扇区(SNB)
4、将FLASH_CR寄存器中的STRT位置1,触发擦除操作

5、等待BSY位清零
经过以上五步,就可以擦除某个扇区!

(二)、批量擦除的步骤 

1、检查FLASH_SR寄存器中的BSY位,确保当前未执行任何FLASH操作
2、在FLASH_CR寄存器中,将MER位置1(F767/F407)

3、在FLASH_CR寄存器中,将MER和OMER1位置1(F429xx)

4、将FLASH_CR寄存器中的STRT位置1,触发擦除操作5等待BSY位清零
经过以上几个步骤,就可以批量擦除扇区。

 

 五、FLASH中断

1、如果将FLASH_CR寄存器中的操作结束中断使能位(EOPIE)置1,则在擦除或者编程操作结束时,即FLASH_SR寄存器中的繁忙位BSY清零时,将产生中断。此时FLASH_SR寄存器中的操作结束(EOP)位置1。
2、如果在请求编程,擦
除或读操作期间出现错误,则FLASH_SR寄存器中的以下错误标志位之一将置1:
PGAERR ,PGPERR ,ERSERR(编程错误标志)

WRPERR(保护错误标志)
这种情况下,FLASH_CR的
错误中断使能位(ERRIE)置1,并且如果FLASH_SR的操作错误位(OPERR)置1,则产生一个中断。
 

 六、结语

有关FLASH操作的相关知识就分享至此了,下一篇文章将会带大家深度了解FLASH相关的寄存器和寄存器的配置。

单片机FLASH深度解析和编程实践(下)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/748765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ansys Lumerical | 激光雷达天线仿真

附件下载 联系工作人员获取附件 在本文中&#xff0c;我们将了解如何根据激光雷达应用需求设计和优化相控阵光栅天线。 概述 激光雷达&#xff08;LIDAR&#xff09;是“light detection and ranging”的简称&#xff0c;近年来由于在机器人、自动驾驶汽车、高精度测绘等领域…

万物互联的价值

随着我们习惯了万物互联&#xff0c;我们将需要改变我们的行为和使用互联网的方式。这并不像看起来那么困难。毕竟&#xff0c;自 20 世纪 90 年代中期互联网普及以来&#xff0c;你们中的许多人都会经历过各种经历的变化。你们中的许多人已经看到了网络邮件、在线电影和音乐、…

挑战杯 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

基于comsol七芯光纤超模模拟分析

本期教程主要向大家介绍一期采用comsol有限元分析软件进行七芯光纤模拟分析的模拟教程。首先介绍一下基本知识点 七芯光纤超模理论&#xff08;Supermode Theory for Seven-Core Fibers&#xff09;涉及一种特殊类型的多芯光纤&#xff08;MCF&#xff09;技术。在这里&#x…

【消息队列开发】 测试MessageFileManager(对硬盘中的消息操作)类

文章目录 &#x1f343;前言&#x1f384;测试流程&#x1f334;准备工作&#x1f332;测试创建队列功能&#x1f333;测试统计文件的读写&#x1f38b;测试将相应消息放入文件中&#x1f38d;测试读文件里的消息到内存&#x1f340;测试删除消息&#x1f60e;测试垃圾回收⭕总…

MySQL行锁核心知识介绍

MySQL的行锁是数据库中用于控制并发访问的一种机制。它允许在数据库的行级别上实现锁定&#xff0c;从而允许多个事务同时修改不同行的数据&#xff0c;而不会相互干扰。这种锁机制可以提高数据库的并发性能&#xff0c;减少锁争用&#xff0c;提高事务的吞吐量。在本教程中&am…

电视盒子解析安装包失败,安卓4.4安装不了kodi的解决方法,如何安装kodi

有些安卓电视或者电视盒子的安卓系统版本太低、自身架构或者屏蔽了安装其他应用的功能&#xff0c;下载的Kodi apk安装包提示无法安装&#xff0c;解析程序包时出现问题、解析出错无法安装、[INSTALL_FAILED_OLDER_SDK]、此应用与您的电视不兼容。 解决方法&#xff1a; 1、3…

OFDM调制解调过程

OFDM&#xff1a; Orthogonal Frequency Division Multiplexing 正交频分复用 1、OFDMA处理流程图 2、QPSK星座图和映射关系 QPSK&#xff08;Quadrature Phase Shift Keying&#xff0c;正交相移键控&#xff09;四相相移调制是利用载波的四种不同相位差来表征输入的…

服务器数据恢复—服务器硬盘灯显示红色的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台服务器中有一组由多块硬盘组建的raid阵列&#xff0c;在运行过程中服务器突然崩溃&#xff0c;管理员检查服务器发现该服务器raid阵列中有两块硬盘的指示灯显示红色。于是&#xff0c;管理员重启服务器&#xff0c;服务器重启后&a…

大规模自动化重构框架--OpenRewrite浅析

目录 1. OpenRewrite是什么&#xff1f;定位&#xff1f; 2. OpenWrite具体如何做&#xff1f; 3. 核心概念释义 3.1 Lossless Semantic Trees (LST) 无损语义树 3.2 访问器&#xff08;Visitors&#xff09; 3.3 配方&#xff08;Recipes&#xff09; 4. 参考链接 Open…

PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数

摘要/导言 本文旨在介绍如何利用PHP中的simple_html_dom库结合爬虫代理IP技术来高效采集和分析汽车之家网站的电动车参数。通过实际示例和详细说明&#xff0c;读者将了解如何实现数据分析和爬虫技术的结合应用&#xff0c;从而更好地理解和应用相关技术。 背景/引言 随着电…

IO流(3)-文件字符输入\输出流

FIleReader(文件字符输入流&#xff09; 文件字符输出流代码示例 package com.zz.io;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.Reader;public class Test4 {public static void main(String args[]) …

pycharm @NotNull parameter ‘module‘ of ...

下载了最新pycharm &#xff0c;无法启动运行 pycharm或者idea中Run/Debug Python项目报错 Argument for NotNull parameter ‘module‘ of … 解决方案 删除项目根目录的 idea 文件夹 随后重启&#xff0c;重新配置即可

LIN API call LINWakeup() ignored! due to LIN Interactive Master seetings!

在写使用CANoe写测试用例时&#xff0c;想控制LIN节点的休眠和唤醒&#xff0c;笔者想想这玩意再简单不过了&#xff0c;不过就是调用linWakeup()和linGotoSleep()嘛&#xff0c;可是越自信&#xff0c;现实总会给你啪啪啪打脸。实际写完验证并不能达到效果&#xff0c;看了下w…

WRF模型运行教程(ububtu系统)--III.运行WRF模型(官网案例)

零、创建DATA目录 # 1.创建一个DATA目录用于存放数据&#xff08;一般为fnl数据&#xff0c;放在Build_WRF目录下&#xff09;。 mkdir DATA # 2.进入 DATA cd DATA 一、WPS预处理 在模拟之前先确定模拟域&#xff08;即模拟范围&#xff09;,并进行数据预处理&#xff08…

Docker 哲学 - 容器操作

容器&#xff1a; 创建 停止 删除 强制删除&#xff08;正在运行&#xff09; run stop rm rm -f 列出本地容器&#xff1a; docker ps / docker container ls 镜像&#xff1a; search pull run &#xff1a; …

Altium Designer怎么设置默认原理图纸张大小

Altium Designer怎么设置默认原理图纸张大小 绘制原理图时我们需要设置好原理图图纸大小&#xff0c;建议大家可以将默认原理图图纸设置为A3&#xff0c;A3图纸大小可以容纳下大部分原理图&#xff0c;这样就不用每次画原理图前去修改图纸大小&#xff0c;可以提高设计效率。 …

java serlvet 高校学生画像平台系统Myeclipse开发mysql数据库web结构java编程计算机网页项目echarts图形展现

一、源码特点 java serlvet 高校学生画像平台系统是一套完善的java web信息管理系统 系统采用serlvetdaobean 模式开发本系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

sqllab第三关通关笔记

知识点&#xff1a; 通过回显的信息判断原始语句的组成猜测该语句为 select 1,2,3 from 表名 where id (输入) limit 0,1 首先通过测试判断存在什么类型的sql注入 构造id1/0 发现正常输出&#xff1b;说明是字符型的sql注入 好了&#xff0c;下面就测试有什么限制条件 构造…

AI视频矩阵混剪系统|罐头鱼AI批量混剪定时发送

AI视频矩阵混剪系统&#xff1a;智能创作与发布的完美结合 随着社交媒体平台的快速发展&#xff0c;视频已成为各行业推广和传播的热门方式。然而&#xff0c;对于许多人来说&#xff0c;制作高质量的视频仍然是一项挑战。Q:290615413但现在&#xff0c;有了AI视频矩阵混剪系统…