STM32单片机-FLASH闪存

STM32单片机-FLASH闪存

  • 一、FLASH简介
  • 二、FLASH工作原理
  • 三、读写内部FLASH
  • 四、读取芯片ID

一、FLASH简介

  • STM32F1系列的FLASH包含程序存储器系统存储器选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程
  • 读写FLASH的用途:

  利用程序存储器的剩余空间来保存掉电不丢失的用户数据
  通过在程序中编程(IAP),实现程序的自我更新

  • 在线编程(ICP)用于更新存储器的全部内容,它通过JTAGSWD协议系统加载程序(Bootloader)下载程序
  • 程序中编程(IAP)可以使用微控制器支持的任一种通信接口下载程序

  下图为中容量闪存模块组织
  主存储器:用来存放程序代码,主要且容量最大的部分,基本单位是1K的页,C8T6只有64K
  信息块启动程序代码-系统存储器,存放原厂写入的Bootloader,用于串口下载。用户选择字节-存放独立的参数
  闪存存储器接口寄存器:普通外设,存储介质是SRAM,控制擦除和编程

在这里插入图片描述

二、FLASH工作原理

  下图为FLASH基本结构图
  整个闪存分为程序存储器、系统存储器和选项字节
  以C8T6为例,程序存储器为64K,最后一页地址是0x0800 FC00。左边控制器是闪存管理院,可以擦除和编程程序存储器和选项字节。选项字节配置程序存储器的读写保护

在这里插入图片描述

FPEC擦除和编程程序存储器和选项字节时需要前置操作

  • FLASH解锁:FLASH操作前需要解锁,在键寄存器写入指定的键值来实现

  FPEC有三个键值:RDPRT键 = 0x000000A5(解除读保护)、KEY1 = 0x45670123、KEY2 = 0xCDEF89AB
  复位后,FPEC被保护,不能写入FLASH_CR。在FLASH_KEYR先写入KEY1,再写入KEY2解锁。错误的操作序列会在下次复位前锁死FPEC和LASH_CR
  加锁:设置FLASH_CR中的LOCK位锁住FPEC和FLASH_CR

  下图为闪存页擦除过程
  判断LOCK锁没锁,需要解锁,随后置寄存器、判断页地址、等待状态寄存器标志位,擦除

在这里插入图片描述

  下图为闪存全擦除过程
  判断LOCK锁没锁,需要解锁,随后置寄存器、等待状态寄存器标志位,擦除

在这里插入图片描述

  下图为闪存写入过程
  判断LOCK锁没锁,需要解锁,随后置寄存器、在指定地址写入数据、等待状态寄存器标志位

在这里插入图片描述

三、读写内部FLASH

  读内部FLASH指定地址的数据,只需要调用读函数即可uint16_t Data = *((__IO uint16_t *)(0x8000000)),其中数据位数可以更改,地址可以更改
  指定地址写数据时,需要先擦除再写
  下面为MyFLASH.c,其中包括擦除写数据

#include "stm32f10x.h"                  // Device header/*
@brief:读取指定地址FLASH里的地址-32、16和8位
*/
uint32_t MyFLASH_ReadWord(uint32_t Address)
{return *((__IO uint32_t *)(Address));//读取32位数据
}
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)
{return *((__IO uint16_t *)(Address));//读取16位数据
}
uint8_t MyFLASH_ReadByte(uint32_t Address)
{return *((__IO uint8_t *)(Address));//读取8位数据
}/*
@brief:全擦除
*/
void MyFLASH_EraseAllPages()
{FLASH_Unlock();//解锁FLASH_EraseAllPages();FLASH_Lock();//锁上
}
/*
@brief:指定页擦除
*/
void MyFLASH_ErasePage(uint32_t PageAddress)
{FLASH_Unlock();//解锁FLASH_ErasePage(PageAddress);FLASH_Lock();//锁上
}
/*
@brief:指定地址写32位数据
*/
void MyFLASH_ProgramWord(uint32_t Address,uint32_t Data)
{FLASH_Unlock();//解锁FLASH_ProgramWord(Address,Data);FLASH_Lock();//锁上
}
/*
@brief:指定地址写16位数据
*/
void MyFLASH_ProgramHalfWord(uint32_t Address,uint16_t Data)
{FLASH_Unlock();//解锁FLASH_ProgramHalfWord(Address,Data);FLASH_Lock();//锁上
}

  由于FLASH是擦除后再写入,擦除后还容易丢数据,可以在RSAM里新建一个数组,FLASH的数据复制到SRAM,实现掉电不丢失,往FLASH里写入SRAM里的数据,实现参数的任意读写和保存
  首次上电,FLASH数据复制给SRAM数组时,需要判断第一个数据-标志位(任意设置),之后断电上电或者复位时,存在FLASH的数据(不丢失)继续复制给SRAM
  下面为Store.c

uint16_t Store_Data[512];void Store_Init()
{//第一次需要判断标志位if(MyFLASH_ReadHalfWord(0x0800FC00) != 0xA5A5){MyFLASH_ErasePage(0x0800FC00);MyFLASH_ProgramHalfWord(0x0800FC00,0xA5A5);for(uint16_t i = 1;i<512;i++){MyFLASH_ProgramHalfWord(0x0800FC00+i*2,0x0000);}}//设置闪存最后一页第一个半字为A5A5,剩下全部为0for(uint16_t i = 0;i<512;i++){Store_Data[i] = MyFLASH_ReadHalfWord(0x0800FC00+i*2);}//上电时保证数据不丢失,将FLASH数据复制到SRAM数组中
}
/*
@brief:往闪存里面写数据(SRAM数组-FLASH)
*/
void Store_Save()
{MyFLASH_ErasePage(0x0800FC00);for(uint16_t i = 0;i<512;i++){MyFLASH_ProgramHalfWord(0x0800FC00+i*2,Store_Data[i]);}
}
/*
@brief:清除FLASH
*/
void Store_Clear()
{for(uint16_t i = 1;i<512;i++)//标志位不擦除{Store_Data[i] = 0x0000;}Store_Save();
}

  下面为main.c,按键1-SRAM数组值加1,按键2-清零数组

uint8_t KeyNum;int main(void)
{OLED_Init();Key_Init();Store_Init();OLED_ShowString(1,1,"FLAG:");OLED_ShowString(2,1,"Data:");while(1){KeyNum = Key_GetNum();if(KeyNum == 1){Store_Data[1] ++;Store_Data[2] += 2;Store_Data[3] += 3;Store_Data[4] += 4;Store_Save();//SRAM数组写入到FLASH}if(KeyNum == 2){Store_Clear();}OLED_ShowHexNum(1,6,Store_Data[0],4);OLED_ShowHexNum(3,1,Store_Data[1],4);OLED_ShowHexNum(3,6,Store_Data[2],4);OLED_ShowHexNum(4,1,Store_Data[3],4);OLED_ShowHexNum(4,6,Store_Data[4],4);}
}

四、读取芯片ID

  读取ID只需要读取指定地址的数据即可

int main(void)
{OLED_Init();OLED_ShowString(1,1,"F_SIZE:");OLED_ShowHexNum(1,8,*((__IO uint16_t *)(0x1FFFF7E0)),4);OLED_ShowString(2,1,"U_ID:");OLED_ShowHexNum(2,6,*((__IO uint16_t *)(0x1FFFF7E8)),4);OLED_ShowHexNum(2,11,*((__IO uint16_t *)(0x1FFFF7E8+0x02)),4);OLED_ShowHexNum(3,1,*((__IO uint32_t *)(0x1FFFF7E8+0x04)),8);OLED_ShowHexNum(4,1,*((__IO uint32_t *)(0x1FFFF7E8+0x08)),8);while(1){}
}

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

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

相关文章

Web开发模式总结

Web开发模式总结如下&#xff1a; 一、基于服务器端渲染的传统Web开发模式 1. 介绍 服务器端渲染开发模式是指&#xff1a;服务器端通过字符串拼接&#xff0c;动态生成HTML结构和数据&#xff0c;交由客户端浏览器直接渲染的方式。客户端不需要使用Ajax等前后端交互技术额外…

[机器学习算法] 主成分分析

主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;是一种用于降维和特征提取的统计方法。它可以将高维数据投影到较低维度的空间中&#xff0c;同时尽量保留数据的变异性。以下是详细的学习步骤&#xff0c;包括理论和实际操作。 一、了解PCA的基本概念 数…

看广告收益小游戏app平台搭建

搭建一个看广告收益小游戏APP平台是一个复杂且涉及多个方面的过程。以下是一个大致的搭建流程&#xff1a; 市场调研与定位&#xff1a; 首先&#xff0c;进行市场调研&#xff0c;了解目标用户群体的需求和偏好&#xff0c;以及现有市场的竞争情况123。根据调研结果&#xff0…

ReF:斯坦福提出的新型语言模型微调方法

随着预训练语言模型&#xff08;LMs&#xff09;在各种自然语言处理&#xff08;NLP&#xff09;任务中的广泛应用&#xff0c;模型微调成为了一个重要的研究方向。传统的全参数微调方法虽然有效&#xff0c;但计算成本高昂&#xff0c;尤其是在大型模型上。为了解决这一问题&a…

解读代理 IP差异:ISP 代理与住宅代理

独立IP作为跨境必备工具&#xff0c;代理类型五花八门&#xff0c;今天IPFoxy全球代理将为搭建科普&#xff1a;ISP代理与住宅代理在理论上与使用上的区别。代理充当用户和互联网之间的中介&#xff0c;提供各种功能以增强安全性、隐私性和可访问性。在众多代理类型中&#xff…

嵌入式实验---实验四 DMA传输实验

一、实验目的 1、掌握STM32F103DMA传输程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、利用外部按键KEY1来控制DMA的传送&#xff0c;每按一次KEY1&#xff0c;DMA就传送一次数据到USART1&#xff08;串口1&#xff09;&#xff1b; 2、该串口…

【深度学习驱动流体力学】采集OpenFOAM仿真的流体力学数据送入到LSTM模型训练

具体参考上一篇文章: 【深度学习驱动流体力学】采集OpenFOAM仿真数据作为AI模型训练数据集与卷积神经网络搭建到预测(一站式完整代码实现) 原理介绍 数据处理与预处理 该代码首先导入必要的库,包括用于读取和处理VTK文件的pyvista,用于数值计算的numpy,用于路径操作的os,…

win10 安装PowerShell

总结: 直接下一步,下一步… 下载链接 https://download.csdn.net/download/qq_43071699/89462517

Qt扩展-轻量数学公式计算

轻量数学公式计算 一、概述二、代码结构三、简单使用四、解析支持1. 操作数2. 运算符3. 括号 一、概述 这个是我写得简单的一个数学计算公式工具。easy-math-parser 是一个用C编写的简单工具包&#xff0c;支持四个操作字符串的计算工具&#xff0c;灵感来自Muparser。 在这个…

Linux守护进程简介、创建流程、关闭和实例演示

1、什么是守护进程&#xff1f; 守护进程是一个后台运行的进程&#xff0c;是随着系统的启动而启动&#xff0c;随着系统的终止而终止&#xff0c;类似于windows上的各种服务&#xff0c;比如ubuntu上的ssh服务&#xff0c;网络管理服务等都是守护进程。 2、守护进程的创建流…

关于创建String的那点事...

String 首先说明一下&#xff0c;本人是前端小学生级别的菜鸡&#xff0c;吐槽的话请口下留情&#xff0c;在评论区指出错误或者补充不足&#xff0c;我会很喜欢&#xff0c;互喷不会进步&#xff0c;相互指点才会。。。。谢谢大家啦 目录 字面量方式构造函数方式区别 等号判…

如何为自己的项目生成changelog

背景 在github上看到人家的更新日志感觉很cool&#xff0c;怎么能给自己项目来一套呢 环境信息 tdstdsdeMacBook-Pro demo-doc % node -v v14.18.1 tdstdsdeMacBook-Pro demo-doc % npm -v 6.14.15硬件信息 型号名称&#xff1a;MacBook Pro版本&#xff1a; 12.6.9芯片&…

活出属于自己的人生

背景 24年高考帷幕落下&#xff0c;一场新的思考与选择悄然来临。对于每一位高考考生&#xff0c;学校和专业都是开启大学新生活的两个前置必选项。但有时候“鱼与熊掌不可兼得”&#xff0c;在分数受限的条件下&#xff0c;是选择一个心仪的专业还是选择一个知名度更高的学校…

QT自定义标题栏窗口其二:实现拖动及可拉伸效果 + 顶部全屏/侧边半屏

1、效果 2、核心代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent<

yolov10训练自己的数据集(没有显卡的替代方案)

1.没有显卡的替代方案 robflow https://github.com/tensorflow/models/tree/master/official 模型训练替代方案&#xff1a;嘉楠开发者社区

基于鲸鱼优化的DSN弱栅栏覆盖算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 for t1:Itersfor i1:Num%目标函数更新[pa(i),fgai] fitness(xwoa(…

全网最全!25届最近5年上海大学自动化考研院校分析

上海大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、历年真题PDF 七、初试大纲复试大纲 八、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、考试科目…

Linux计划任务与日志

计划任务 主要用于完成一些周期性任务及定时任务&#xff0c;Windows中也有该功能&#xff1a; 单次调度执行 yum install -y at安装at工具&#xff0c;systemctl start atd启动服务&#xff0c;使用方法为at 选项 时间 执行内容时间可以自由设置&#xff0c;开启的栏目中输…

【SpringBoot + Vue 尚庭公寓实战】地区信息管理接口实现(九)

【SpringBoot Vue 尚庭公寓实战】地区信息管理接口实现&#xff08;九&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】地区信息管理接口实现&#xff08;九&#xff09;1、业务说明2、数据逻辑模型3、接口实现3.1、查询省份信息列表3.2、根据省份ID查询城市信息列表3…

AGI|以ChatGPT为例,浅析AI究竟能干什么?

目录 一、前言 二、ChatGPT 三、Prompt Engineering 四、神经网络 五、后记 一、前言 当一个新事物的出现&#xff0c;最好的办法就是了解它出现的背景&#xff0c;发展的历史。 当ChatGPT出现在我们面前&#xff0c;多轮对话能力让人震惊&#xff0c;仿佛机器真的可以&qu…