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…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...