STM32读写内部FLASH读取芯片id
文章目录
- 读写内部Flash
- 接线
- 程序编写
- 测试效果
- 补充
- 读取芯片id
- 代码编写
读写内部Flash
接线

程序编写
首先使用ThisFlash.c来写入flash的基本操作,写入、读取、擦除,然后使用Store.c配合数组来进行主存与flash的交互
ThisFlash.c
#include "stm32f10x.h" // Device header
/*** @brief 读取此地址一个字的数据* @param Address,页地址* @retval 此地址的一个字的数据*/
uint32_t ThisFlash_ReadWord(uint32_t Address){return *((__IO uint32_t *)(Address));
}
/*** @brief 读取此地址的半字数据* @param Address,页地址* @retval 此地址的半字数据*/
uint16_t ThisFlash_ReadHalfWord(uint32_t Address){return *((__IO uint16_t *)(Address));
}
/*** @brief 读取此地址一个字节的数据* @param Address,页地址* @retval 此地址的一个字节的数据*/
uint8_t ThisFlash_ReadByte(uint32_t Address){return *((__IO uint8_t *)(Address));
}
/*** @brief 擦除整页数据* @param 无* @retval 无*/
void ThisFlash_EraseAllPages(void){FLASH_Unlock(); // 解锁FLASH_EraseAllPages(); // 擦除所有页FLASH_Lock(); // 重新上锁
}
/*** @brief 擦除指定页数据* @param 无* @retval 无*/
void ThisFlash_ErasePage(uint32_t PageAddress){FLASH_Unlock(); // 解锁FLASH_ErasePage(PageAddress); // 擦除指定页FLASH_Lock(); // 重新上锁
}
/*** @brief 指定地址写入一个字的数据* @param Address,页地址 Data,数据* @retval 无*/
void ThisFlash_PragramWord(uint32_t Address,uint32_t Data){FLASH_Unlock(); // 解锁FLASH_ProgramWord(Address,Data); // 指定地址写入一个字的数据FLASH_Lock(); // 重新上锁
}
/*** @brief 指定地址写入半字数据* @param Address,页地址 Data,数据* @retval 无*/
void ThisFlash_PragramHalfWord(uint32_t Address,uint16_t Data){FLASH_Unlock(); // 解锁FLASH_ProgramHalfWord(Address,Data); // 指定地址写入一个字的数据FLASH_Lock(); // 重新上锁
}
ThisFlash.h
#ifndef __THISFLASH_H
#define __THISFLASH_H
uint32_t ThisFlash_ReadWord(uint32_t Address);
uint16_t ThisFlash_ReadHalfWord(uint32_t Address);
uint8_t ThisFlash_ReadByte(uint32_t Address);
void ThisFlash_EraseAllPages(void);
void ThisFlash_ErasePage(uint32_t PageAddress);
void ThisFlash_PragramWord(uint32_t Address,uint32_t Data);
void ThisFlash_PragramHalfWord(uint32_t Address,uint16_t Data);#endif
store.c
#include "stm32f10x.h" // Device header
#include "ThisFlash.h"// 用于与flash交互的数组,存储与ram中
uint16_t Store_Data[512];/*** @brief 初始化最后一页* @param 无* @retval 无*/
void Store_Init(void){// 使用最后一页第一个半字作为是否为第一次写入的标志位if(ThisFlash_ReadHalfWord(0x0800fc00) != 0xa5a5){ThisFlash_ErasePage(0x0800fc00); // 第一次写入,擦掉此页数据ThisFlash_PragramHalfWord(0x0800fc00,0xa5a5); // 写入标志位for(uint16_t i=1;i<512;i++){ThisFlash_PragramHalfWord(0x0800fc00+i*2,0x0000); }}for(uint16_t i=0;i<512;i++){Store_Data[i] = ThisFlash_ReadHalfWord(0x0800fc00+i*2); // 写入标志位}
}
/*** @brief 备份Store_Data到flash* @param 无* @retval 无*/
void Store_Backup(void){ThisFlash_ErasePage(0x0800fc00);for(uint16_t i=0;i<512;i++){ThisFlash_PragramHalfWord(0x0800fc00+i*2,Store_Data[i]); // 写入标志位}
}
/*** @brief 擦除Store_Data并备份到flash* @param 无* @retval 无*/
void Store_Clear(void){for(uint16_t i=0;i<512;i++){Store_Data[i] = 0x0000; // 写入标志位}Store_Backup(); // flash同步清空
}
store.h
#ifndef __STORE_H
#define __STORE_H
extern uint16_t Store_Data[512];
void Store_Init(void);
void Store_Backup(void);
void Store_Clear(void);#endif
button.c
#include "stm32f10x.h" // Device header
#include "Delay.h"/*** @brief 初始化Button相关端口* @param 无* @retval 无*/
void Button_Init(void){// 初始化时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*** @brief 返回所按按键值* @param 无* @retval KeyNum 按键值*/
uint8_t Key_Num(void){uint8_t KeyNum = 0;if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==0){Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)==0);Delay_ms(20);KeyNum = 1;}if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0){Delay_ms(20);while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==0);Delay_ms(20);KeyNum = 11;}return KeyNum;
}
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Store.h"
#include "button.h"uint8_t KeyNum;int main(void)
{OLED_Init();Button_Init();Store_Init();// 为了不影响芯片的其他功能,在flash最后一页写入数据来测试while (1){KeyNum = Key_Num();if(KeyNum == 1){Store_Data[1] = 0x1314;Store_Data[3] = 0X3344;Store_Backup();}if(KeyNum == 11){Store_Clear();}OLED_ShowHexNum(1,1,Store_Data[1],4);OLED_ShowHexNum(2,1,Store_Data[3],4); OLED_ShowString(3,1,"Flag:");OLED_ShowHexNum(3,7,Store_Data[0],4);}
}
测试效果
下载程序后按下b11的按键最后一页数据清零,使用ST-LINK Utility查看

然后按下复位键,初始化函数执行,标志位置a5a5(为小端对齐反式)

然后按下b1按键,写入数据到数组并备份到flash,并且掉电不丢失

补充
还可以根据所需要的闪存空间来设置留给程序的闪存大小

读取芯片id
代码编写
根据手册给出的器件id地址一一使用指针读取
- 显示闪存大小

显示uid


main.c内容如下:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"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,8,*((__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(3,1,*((__IO uint32_t *)(0x1FFFF7E8+0x08)),8);while (1){}
}

相关文章:
STM32读写内部FLASH读取芯片id
文章目录 读写内部Flash接线程序编写测试效果补充 读取芯片id代码编写 读写内部Flash 接线 程序编写 首先使用ThisFlash.c来写入flash的基本操作,写入、读取、擦除,然后使用Store.c配合数组来进行主存与flash的交互 ThisFlash.c #include "stm32…...
前端npm打包及报错解决
前端npm install 安装node 下载地址 https://nodejs.org/en/download/prebuilt-binaries 配置环境变量 wget https://nodejs.org/dist/v14.21.3/node-v14.21.3-linux-x64.tar.xz tar xf node-v14.21.3-linux-x64.tar.xz -C /data/ vim /etc/profile export NODE_HOME/data/n…...
vbs执行报错vbs没有文件拓展,双击无法打开
如果看不到文件扩展名需要设置: 无法双击打开vbs 一般为注册表问题 解决办法 将下方代码保存为xxx.reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.VBS] "VBSFile" [HKEY_CLASSES_ROOT.VBS\PersistentHandler] "{5e941d80-bf96-…...
超详细的前后端实战项目(Spring系列加上vue3)前端篇(二)(一步步实现+源码)
好了,兄弟们,继昨天的项目之后,开始继续敲前端代码,完成前端部分 昨天完成了全局页面的代码,和登录页面的代码,不过昨天的代码还有一些需要补充的,这里添加一下 内容补充:在调用登…...
【国产中颖】SH79F9202U单片机驱动LCD段码液晶学习笔记
1. 引言 因新公司之前液晶数显表产品单片机一直用的是 C51单片机(SH79F9202U9),本人之前没有接触过这款单片机,为了维护老产品不得不重新研究研究这款单片机。 10位ADC LCD的增强型8051微控制器 SH79F9202是一种高速高效率8051可兼容单片机。在同样振…...
人工智能初识
🌞欢迎来到人工智能基础的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2024年5月1…...
【算法刷题day60】Leetcode:84. 柱状图中最大的矩形
文章目录 Leetcode 84. 柱状图中最大的矩形解题思路代码总结 草稿图网站 java的Deque Leetcode 84. 柱状图中最大的矩形 题目:84. 柱状图中最大的矩形 解析:代码随想录解析 解题思路 反方向接雨水。见上一篇文章 代码 class Solution {public int la…...
ThingsBoard物联网网关在智慧城市数据采集中的应用
智慧城市由监控中心、采集网关、前端采集设备、前端感应执行器组成。 为何选用ThingsBoard作为平台 监控中心为物联网平台,该平台包含云计算、大数据、人工智能、物联网、GIS、云安全等主要模块,具备数据采集、数据交换、超大规模计算、数据分析、数据应…...
Java中的打印流PrintStream 和 PrintWriter
PrintStream和PrintWriter在Java中都是用于打印输出的类,但它们之间存在一些明显的区别。以下是关于这两个类的详细解释和比较: PrintStream 基本特性 PrintStream是一个字节打印流,它继承自FilterOutputStream。 主要操作byte流࿰…...
【MATLAB源码-第217期】基于matlab的16QAM系统相位偏移估计HOS算法仿真,对比补偿前后的星座图误码率。
操作环境: MATLAB 2022a 1、算法描述 高阶统计量(HOS)频偏估计算法 高阶统计量(Higher Order Statistics, HOS)频偏估计算法是一种先进的信号处理技术,广泛应用于现代数字通信系统中,以应对…...
C# CryptoStream流的详解与示例
在当今数字时代,数据安全变得越来越重要。保护敏感信息免受未授权访问是每个开发者的责任。在C#中,使用CryptoStream流可以方便地对数据进行加密和解密。本文将详细介绍C# CryptoStream库的用法、功能以及它如何对数据进行加密和解密。 一、CryptoStrea…...
Kubernetes 之 ReplicaSet
Kubernetes 之 ReplicaSet ReplicaSet 定义 ReplicaSet 是 Kubernetes 中的一种副本控制器,其主要作用是控制其管理的 Pod 的预设副本数量。它会持续监听这些 Pod 的运行状态,在Pod发生故障时执行重启策略,当 Pod 数量减少时会重新启动新的…...
转发和重定向
目录 是什么 转发(Forwarding) 概念 特点 实现方式 重定向(Redirecting) 概念 特点 实现方式 转发和重定向区别整理 转发和重定向的适用场景 转发(Forwarding) 重定向(Redirect&am…...
源码部署ELK
目录 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 单节点 集群(3台节点集群为例) 启动 二、部署logstash 部署logstash 添加配置文件 启动 三、部署kiban…...
构造+模拟,CF1148C. Crazy Diamond
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1148C - Codeforces 二、解题报告 1、思路分析 题目提示O(5n)的解法了,事实上我们O(3n)就能解决,关键在于1,n的处理 我们读入数据a[],代表初始数组…...
CAD二次开发(2)-将直线对象添加到CAD图形文件
1. 准备工作 创建一个类库项目,如下: 2. 分析Line对象 Line类的初始化方法和参数 using Autodesk.AutoCAD.DatabaseServices; Line line new Line();Line 继承Curve 继承Entity 继承DBObject 继承Drawable 继承RXObject 初始化方法有两个…...
代码随想录二刷 Day05 | 242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和,454.四数相加II,383. 赎金信
题目与题解 参考资料:哈希表理论基础 Tips: 一般哈希表都是用来快速判断一个元素是否出现集合里哈希表生成原理:先通过哈希函数将变量映射为hashcode,如果二者hashcode相同,再通过哈希碰撞方法(拉链法&…...
2024年四川省三支一扶报名流程图解✅
2024年四川省三支一扶报名流程图解✅ 🔴时间安排 1、报名时间:5月31日—6月4日17:00 2、资格初审时间:5月31日—6月5日17:00 3、准考证打印时间:6月25日—6月29日 4、笔试时间:6月30日 5、笔试成绩:7…...
js Dom基础
获取元素 1、getElementById() 通过id属性获取一个元素节点对象 <div id"div1"></div> <script> var div1 document.getElementById(div1) </script> 2、 getElementsByTagName()可以根据标签名来获取一组元素节点对象 这个方法会给我们返…...
pytest识别测试用例的机制以及和unittest的区别
pytest识别测试用例的机制 文件 以test_开头或以_test结尾的python文件,即test_xxx.py或xxx_test.py类,在第一点识别到的文件中的类,且满足一下任一条件: 1)以Test_开头,且没有__init__()初始化函数的类&a…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
