STM32读写内部FLASH读取芯片id

news2024/11/8 17:42:58

文章目录

  • 读写内部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)
	{
		
	}
}

在这里插入图片描述


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

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

相关文章

Spring Cloud Gateway 集成 Nacos、Knife4j

目录 1、gateway网关配置1.1 pom 配置2.2 配置文件1.3 yaml 配置 2、其他服务配置2.1 pom 配置2.2 配置文件2.3 yaml 配置 3、界面访问4、其他 官方文档地址&#xff1a;Spring Cloud Gateway集成Knife4j 官方完整源码&#xff1a;https://gitee.com/xiaoym/swagger-bootstrap-…

Redis篇 哈希表在redis中的命令

哈希命令 一.哈希表的基本认识二. 哈希表在redis中的命令1.hset,hget2.hdel3.hkeys,hvals4.hexists5.hgetall6.hmget7.hlen8.hincrby和hincrbyfloat 一.哈希表的基本认识 在JAVA数据结构中&#xff0c;我们就已经接触到了哈希表&#xff0c; 在当时&#xff0c;我们主要用到的哈…

第16章-超声波跟随功能 基于STM32的三路超声波自动跟随小车 毕业设计 课程设计

第16章-超声波跟随功能 无PID跟随功能 //超声波跟随if(HC_SR04_Read() > 25){motorForward();//前进HAL_Delay(100);}if(HC_SR04_Read() < 20){motorBackward();//后退HAL_Delay(100);}PID跟随功能 在pid.c中定义一组PID参数 tPid pidFollow; //定距离跟随PIDpidFol…

CISP难度将加大?还考不考啊...

最新消息&#xff1a;CISP即将调整知识体系大纲&#xff0c;更新题库&#xff0c;后续考试难度加大。 最近几年&#xff0c;CISP改版地比较频繁&#xff0c;难度也在不断上升&#xff0c;因此各位小伙伴有考CISP想法的尽早考。 随着《网络安全法》、《网络空间安全战略》、《…

牛客NC324 下一个更大的数(三)【中等 双指针 Java/Go/PHP/C++】参考lintcode 52 · 下一个排列

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/475da0d4e37a481bacf9a09b5a059199 思路 第一步&#xff1a;获取数字上每一个数&#xff0c;组成数组arr 第二步&#xff1a;利用“下一个排列” 问题解题方法来继续作答&#xff0c;步骤&#xff1a;利用lintc…

oracle12.1 rac 静默dbca教程(百分之百创建成功)

修改原响应文件 [oracleprimary1 database]$ cd response/ [oracleprimary1 response]$ ls dbca.rsp db_install.rsp netca.rsp [oracleprimary1 response]$ vi dbca.rsp 默认即可 数据库类型内存占比按需选择 运行静默创建实例脚本 [oracleprimary1 response]$ dbca -silen…

虚拟机改IP地址

使用场景&#xff1a;当你从另一台电脑复制一个VMware虚拟机过来&#xff0c;就是遇到一个问题&#xff0c;虚拟的IP地址不一样&#xff08;比如&#xff0c;一个是192.168.1.3&#xff0c;另一个是192.168.2.4&#xff0c;由于‘1’和‘2’不同&#xff0c;不是同一网段&#…

探索自动发邮件的奥秘:从配置到实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;邮件自动化的魅力 二、配置环境&#xff1a;选择适合的SMTP服务器 示…

【C++】模拟实现string类

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 二.逐步实现项目功能模块及其逻辑详解 &#x1f38f;构建成员变量 &#x1f38f;实现string类默认成员函数 &#x1f4cc;构造函数 &#x1f4cc;析构函数…

React热更新异常

问题现象 本地一个react项目&#xff0c;当修改任意内容保存时本地编译会失败报错 解决方案 将dependencies中的react-scripts移至devDependencies中

Kafka原生API使用Java代码-生产者-分区策略-默认分区策略轮询分区策略

文章目录 1、代码演示1.1、pom.xml1.2、KafkaProducerPartitioningStrategy.java1.2.1、ProducerConfig.LINGER_MS_CONFIG取 0 值得情况&#xff0c;不轮询1.2.2、ProducerConfig.LINGER_MS_CONFIG取 0 值得情况&#xff0c;轮询1.2.3、ProducerConfig.LINGER_MS_CONFIG取 1000…

英语学习笔记29——Come in, Amy!

Come in, Amy! 进来&#xff0c;艾米&#xff01; shut v. 关严 区别&#xff1a;shut the door 把门关紧 口语&#xff1a;Shut up! 闭嘴&#xff01;    态度强硬&#xff0c;不礼貌 例句&#xff1a;请不要把门关严。    Don’t shut the door, please. bedroom n. …

Android Studio无法改变Button背景颜色解决办法

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天我来和大家探讨一个在Android开发中常见但可能让初学者感到困惑的问题——如何在Android Studio中改变Button的背景颜色。这个问题看似简单&#xff0c;但实际操作中可能会遇到一些意想不到的挑战。接下来&#xff0c;我将从多个…

论文笔记:Vision GNN: An Image is Worth Graph of Nodes

neurips 2022 首次将图神经网络用于视觉任务&#xff0c;同时能取得很好的效果 1 方法 2 架构 在计算机视觉领域&#xff0c;常用的 transformer 通常是 isotropic 的架构&#xff08;如 ViT&#xff09;&#xff0c;而 CNN 更喜欢使用 pyramid 架构&#xff08;如 ResNet&am…

Day 6:2981. 找出出现至少三次的最长特殊子字符串 I

Leetcode 2981. 找出出现至少三次的最长特殊子字符串 I 给你一个仅由小写英文字母组成的字符串 s 。 如果一个字符串仅由单一字符组成&#xff0c;那么它被称为 特殊 字符串。例如&#xff0c;字符串 “abc” 不是特殊字符串&#xff0c;而字符串 “ddd”、“zz” 和 “f” 是特…

计算字符串的长度

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 由于不同的字符所占字节数不同&#xff0c;所以要计算字符串的长度&#xff0c;需要先了解各字符所占的字节数。在Python中&#xff0c;数字、英文、…

万亿应急国债项目之通信指挥类应急装备多链路聚合通信设备在应急行业中的重要作用

万亿应急国债项目的推出&#xff0c;无疑是我国在应急领域的一次重大举措。在这一宏大蓝图中&#xff0c;通信指挥类应急装备的多链路聚合通信设备显得尤为重要&#xff0c;其在应急行业中所发挥的作用&#xff0c;堪称不可或缺的关键一环。 通信指挥是应急响应中的核心环节&a…

【开源项目】Excel数据表自动生成工具v1.0版

一、介绍 Excel数据表自动生成工具是Go语言编写的一款小型工具软件&#xff0c;用于将特定的Excel表格内容导出为多种编程语言的代码或可以直接读取的数据内容。 开源Github地址&#xff1a;https://github.com/SkyCreator/goproj 二、版本v1.0功能概览 1.编程语言支持 目前…

ch2应用层--计算机网络期末复习

2.1应用层协议原理 网络应用程序位于应用层 开发网络应用程序: 写出能够在不同的端系统上通过网络彼此通信的程序 2.1.1网络应用程序体系结构分类: 客户机/服务器结构 服务器: 总是打开(always-on)具有固定的、众所周知的IP地址 主机群集常被用于创建强大的虚拟服务器 客…

【漏洞复现】大华智能物联综合管理平台 fastjson远程代码执行漏洞

0x01 产品简介 大华ICC智能物联综合管理平台对技术组件进行模块化和松耦合&#xff0c;将解决方案分层分级&#xff0c;提高面向智慧物联的数据接入与生态合作能力。 0x02 漏洞概述 由于大华智能物联综合管理平台使用了存在漏洞的Fastson组件,未经身份验让的攻击者可利用 /e…