【STM32】STM32学习笔记-读写内部FLASH 读取芯片ID(49)

news2024/11/15 4:41:35

00. 目录

文章目录

    • 00. 目录
    • 01. FLASH概述
    • 02. 读写内部FLASH接线图
    • 03. 读写内部FLASH相关API
    • 04. 读写内部FLASH程序示例
    • 05. 读写芯片ID接线图
    • 06. 读写芯片ID程序示例
    • 07. 程序示例下载
    • 08. 附录

01. FLASH概述

STM32F10xxx内嵌的闪存存储器可以用于在线编程(ICP)或在程序中编程(IAP)烧写。

在线编程(In-Circuit Programming – ICP)方式用于更新闪存存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载用户应用程序到微控制器中。ICP是一种快速有效的编程方法,消除了封装和管座的困扰。

与ICP方式对应,在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口(如I/O端口、USB、CAN、UART、I 2 C、SPI等)下载程序或数据到存储器中。IAP允许用户在程序运行时重新烧写闪存存储器中的内容。然而,IAP要求至少有一部分程序已经使用ICP烧到闪存存储器中。

闪存接口是在AHB协议上实现了对指令和数据的访问,它通过对存储器的预取缓存,加快了存储器的访问;闪存接口还实现了在所有工作电压下对闪存编程和擦除所需的逻辑电路,这里还包括访问和写入保护以及选择字节的控制。

02. 读写内部FLASH接线图

在这里插入图片描述

03. 读写内部FLASH相关API

/*------------ Functions used for all STM32F10x devices -----*/
void FLASH_SetLatency(uint32_t FLASH_Latency);
void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess);
void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer);
void FLASH_Unlock(void);
void FLASH_Lock(void);
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
FLASH_Status FLASH_EraseAllPages(void);
FLASH_Status FLASH_EraseOptionBytes(void);
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);
uint32_t FLASH_GetUserOptionByte(void);
uint32_t FLASH_GetWriteProtectionOptionByte(void);
FlagStatus FLASH_GetReadOutProtectionStatus(void);
FlagStatus FLASH_GetPrefetchBufferStatus(void);
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
FLASH_Status FLASH_GetStatus(void);
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

04. 读写内部FLASH程序示例

测试程序1

main.c

#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "flash.h"

 int main(void)
 {	 
	 //初始化
	 OLED_Init();

	 //显示一个字符
	 OLED_ShowChar(1, 1, 'A');

#if 0	 
	 //显示字符串
	 OLED_ShowString(1, 3, "HelloWorld!");
	 //显示十进制数字
	 OLED_ShowNum(2, 1, 12345, 5);
	 //显示有符号十进制数
	 OLED_ShowSignedNum(2, 7, -66, 2);
	 //显示十六进制
	 OLED_ShowHexNum(3, 1, 0xAA55, 4);
	 //显示二进制数字
	 OLED_ShowBinNum(4, 1, 0xAA55, 16);
#endif

	OLED_ShowHexNum(1, 1, flash_read_word(0x08000000), 8);
	OLED_ShowHexNum(2, 1, flash_read_half_word(0x08000000), 4);
	OLED_ShowHexNum(3, 1, flash_read_byte(0x08000000), 2);
	
	 while(1)
	 {
		 
	 }
	 
	 return 0;
 }

测试程序2

flash.h

#ifndef __FLASH_H__
#define __FLASH_H__

#include "stm32f10x.h"                  // Device header
//存储的开始地址
#define STORE_START_ADDR 0x0800FC00

//存储数据的个数
#define STORE_SIZE 		 512

extern uint16_t store_data[STORE_SIZE];

uint32_t flash_read_word(uint32_t addr);
uint16_t flash_read_half_word(uint32_t addr);
uint8_t flash_read_byte(uint32_t addr);

//擦除所有的页
void flash_erase_all_pages(void);
//页擦除
void flash_erase_pages(uint32_t page_addr);

//存储初始化
void store_init(void);
//将数据保存到闪存
void store_save(void);
//数据清零
void store_clear(void);



#endif


flash.c

#include "flash.h"



uint16_t store_data[STORE_SIZE];

uint32_t flash_read_word(uint32_t addr)
{
	return *((__IO uint32_t *)(addr));;
}

uint16_t flash_read_half_word(uint32_t addr)
{
	return *((__IO uint16_t *)(addr));
}

uint8_t flash_read_byte(uint32_t addr)
{
	return *((__IO uint8_t *)(addr));
}


//擦除所有的页
void flash_erase_all_pages(void)
{
	FLASH_Unlock();
	FLASH_EraseAllPages();
	FLASH_Lock();
}

//页擦除
void flash_erase_pages(uint32_t page_addr)
{
	FLASH_Unlock();
	FLASH_ErasePage(page_addr);
	FLASH_Lock();
}

//flash编程字
void flash_program_word(uint32_t addr, uint32_t data)
{
	FLASH_Unlock();
	FLASH_ProgramWord(addr, data);
	FLASH_Lock();
}

//flash编程半字
void flash_program_half_word(uint32_t addr, uint16_t data)
{
	FLASH_Unlock();
	FLASH_ProgramHalfWord(addr, data);
	FLASH_Lock();
}

//存储初始化
void store_init(void)
{
	uint16_t i;
	
	//判断是不是第一次使用
	if (flash_read_half_word(STORE_START_ADDR) != 0xA5A5)
	{
		flash_erase_pages(STORE_START_ADDR);
		flash_program_half_word(STORE_START_ADDR, 0xA5A5);
		
		//清空数据
		for (i = 1; i < STORE_SIZE; i++)
		{
			flash_program_half_word(STORE_START_ADDR + i * 2, 0x0000);
		}
	}
	
	//上电时候将数据拷贝到数组中
	for (i = 0; i < STORE_SIZE; i++)	
	{
		store_data[i] = flash_read_half_word(STORE_START_ADDR + i * 2);
	}
}

//将数据保存到闪存
void store_save(void)
{
	uint16_t i;
	
	flash_erase_pages(STORE_START_ADDR);
	
	for (i = 0; i < STORE_SIZE; i++)	
	{
		flash_program_half_word(STORE_START_ADDR + i * 2, store_data[i]);
	}
}

//数据清零
void store_clear(void)
{
	uint16_t i;
	
	for (i = 1; i < STORE_SIZE; i++)	
	{
		store_data[i] = 0x0000;
	}
	store_save();
}


main.c

#include "stm32f10x.h"

#include "delay.h"
#include "oled.h"
#include "key.h"
#include "flash.h"


 int main(void)
 {	
	 uint8_t key = 0;
	 //初始化
	 OLED_Init();
	 
	 //按键初始化
	 key_init();

	 //显示一个字符
	 OLED_ShowChar(1, 1, 'A');

#if 0	 
	 //显示字符串
	 OLED_ShowString(1, 3, "HelloWorld!");
	 //显示十进制数字
	 OLED_ShowNum(2, 1, 12345, 5);
	 //显示有符号十进制数
	 OLED_ShowSignedNum(2, 7, -66, 2);
	 //显示十六进制
	 OLED_ShowHexNum(3, 1, 0xAA55, 4);
	 //显示二进制数字
	 OLED_ShowBinNum(4, 1, 0xAA55, 16);
#endif

	store_init();
	
	//显示字符串
	OLED_ShowString(1, 1, "Flag: ");
	OLED_ShowString(2,1, "Data: ");
	
	 while(1)
	 {
		 key = key_scan();
		 
		 if (1 == key)
		 {
			store_data[1]++;
			store_data[2] += 2;
			store_data[3] += 3;
			store_data[4] += 4;
			 
			 store_save();
			 
		 }
		 
		 if (2 == key)
		 {
			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);
	 }
	 
	 return 0;
 }

05. 读写芯片ID接线图

在这里插入图片描述

06. 读写芯片ID程序示例

main.c

#include "stm32f10x.h"

#include "delay.h"
#include "oled.h"


 int main(void)
 {	

	 
	 
	 //初始化
	 OLED_Init();

	 #if 0
	 //显示一个字符
	 OLED_ShowChar(1, 1, 'A');
	 //显示字符串
	 OLED_ShowString(1, 3, "HelloWorld!");
	 //显示十进制数字
	 OLED_ShowNum(2, 1, 12345, 5);
	 //显示有符号十进制数
	 OLED_ShowSignedNum(2, 7, -66, 2);
	 //显示十六进制
	 OLED_ShowHexNum(3, 1, 0xAA55, 4);
	 //显示二进制数字
	 OLED_ShowBinNum(4, 1, 0xAA55, 16);
	 #endif
	 
	 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 + 0x2)), 4); 
	 OLED_ShowHexNum(3, 1, *((__IO uint16_t *)(0x1FFFF7E8 + 0x4)), 8); 
	 OLED_ShowHexNum(4, 1, *((__IO uint16_t *)(0x1FFFF7E8 + 0x8)), 8); 
	 
	 
	 
	 while(1)
	 {
		 
	 }
	 
	 return 0;
 }


 

07. 程序示例下载

40-读写FLASH.rar

41-读写芯片ID.rar

08. 附录

参考: 【STM32】江科大STM32学习笔记汇总

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

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

相关文章

yolov9训练

目录 说明 1、下载代码安装新的python环境 2、准备数据 3、修改代码 说明 本文参考该博主的文章&#xff0c;在已经有数据的情况&#xff0c;进行简单总结。需要详细版见原文链接如下&#xff1a;YOLOV9保姆级教程-CSDN博客 1、下载代码安装新的python环境 代码下载&…

【数据结构和算法初阶(C语言)】带环链表问题详解(快慢指针的烧脑应用)

目录 1.铺垫-----带环链表基本了解 2. 题目&#xff1a;环形链表 3.环形链表|| ​编辑 3.1题解1 3.2 题解2 4.总结 1.铺垫-----带环链表基本了解 环形链表题目启迪&#xff1a; 环形链表特点&#xff1a;遍历链表会出现一模一样的地址 2. 题目&#xff1a;环形链表 给…

如何使用 ArcGIS Pro 制作三维地形图

伴随硬件性能的提高和软件算法的优化&#xff0c;三维地图的应用场景会越来越多&#xff0c;这里为大家介绍一下在ArcGIS Pro怎么制作三维地形图&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM和影像数据&#xff0c;除了DEM和影像数据…

笨办法学 Python3 第五版(预览)(二)

原文&#xff1a;Learn Python the Hard Way, 5th Edition (Early Release) 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 练习 19&#xff1a;函数和变量 现在你将把函数与你从之前练习中了解到的变量结合起来。如你所知&#xff0c;变量给数据片段一个名称&#x…

Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径

一、前言 在Spring Boot项目开发过程中&#xff0c;对于接口API发布URL访问路径&#xff0c;一般都是在类上标识RestController或者Controller注解&#xff0c;然后在方法上标识RequestMapping相关注解&#xff0c;比如&#xff1a;PostMapping、GetMapping注解&#xff0c;通…

⭐每天一道leetcode:21.合并两个有序链表(简单;双指针)

⭐今日份题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例2 输入&#xff1a;l1 [], l2 [] 输出&#xff1a;[] 示例3 输入…

【机器学习】包裹式特征选择之递归特征添加法

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

Unity 摄像机的深度切换与摄像机画面投影

摄像机可选&#xff1a;透视、正交 正交类似投影&#xff0c;1比1 透视类似人眼&#xff0c;近大远小 摄像机投影 在项目中新建&#xff1a;渲染器纹理 将新建纹理拖动到相机的目标纹理中 新建一个平面&#xff0c;将新建材质组件放到平面中即可。 相机深度切换 使用代…

探索Java开发面试笔记:以听为目的,助力编程技术提升与面试准备

文章目录 一、制作背景介绍二、 Java开发面试笔记&#xff1a;为你的编程之路加速2.1 公众号主题和目标读者群体2.2 为什么面试笔记对于提高编程视野和技术至关重要2.3 親測效率 三、形式案例3.1 文章形式3.2 手机案例3.3 电脑案例 一、制作背景介绍 做公众号的背景&#xff1a…

十九 超级数据查看器 讲解稿 分栏功能

十九 超级数据查看器 讲解稿 分栏功能 点击此处观看视频教程 讲解稿全文: 大家好&#xff0c;这讲介绍一下 &#xff0c;超级数据查看器的分栏功能。 分栏功能设计的初衷是为了让用户同时同地查询两个表格的数据&#xff0c;方便比较&#xff0c;获得更清晰的查询结果 分栏功…

模型优化_XGBOOST学习曲线及改进,泛化误差

代码 from xgboost import XGBRegressor as XGBR from sklearn.ensemble import RandomForestRegressor as RFR from sklearn.linear_model import LinearRegression as LR from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split,c…

如何添加极狐GitLab Runner 信任域名证书

本文作者 徐晓伟 极狐Gitlab Runner 信任实例域名证书&#xff0c;用于注册注册极狐 GitLab Runner。 问题 参见 极狐gitlab-runner-host.md 说明 解决方案是使用颁发给域名 gitlab.test.helm.xuxiaowei.cn 的证书&#xff0c;可以使用自己的域名去各大云厂商免费申请&#…

重学SpringBoot3-yaml文件配置

重学SpringBoot3-yaml文件配置 引言YAML 基本语法YAML 数据类型YAML 对象YAML 数组复合结构标量引用 YAML 文件结构Spring Boot 中的 YAML 配置注意事项总结参考 引言 YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一种常用于配置文件的数据序列化格式&#xff…

Unity3D

一、C# 输入输出 二、三维数学

CSS变量和@property

CSS变量 var() CSS 变量是由CSS作者定义的实体&#xff0c;其中包含要在整个文档中重复使用的特定值。使用自定义属性来设置变量名&#xff0c;并使用特定的 var() 来访问。&#xff08;比如 color: var(--main-color);&#xff09;。 基本用法 CSS变量定义的作用域只在定义该…

搞定国科金 必备王炸新技术!凌恩生物重磅推出微生物单细胞测序产品

单细胞异质性研究如火如荼&#xff0c;但原核生物研究却是个“坎”。 现有常规的原核生物研究&#xff0c;都集中于单菌群落或微生态大群体&#xff0c;只能从宏观角度研究群体状态&#xff0c;而经典的单细胞RNA测序技术无法应用于细菌。 单细胞技术应用于原核生物的几点障碍…

window10 安装配置docker

前言&#xff08;重要&#xff09;&#xff1a;确认window10版本已经更新到最新版 随着时间推移&#xff0c;docker对window版本的支持也在变&#xff0c;截至2024年3月份&#xff0c;支持win10最低版本号&#xff1a;22H2,操作系统最低版本&#xff1a;19045.2965&#xff0c…

学编程怎么样才能更快入手,编程怎么简单易学

学编程怎么样才能更快入手&#xff0c;编程怎么简单易学 一、前言 对于初学编程建议先从简单入手&#xff0c;然后再学习其他复杂的编程语言。 今天给大家分享的中文编程开发语言工具 进度条构件的用法。 编程入门视频教程链接 https://edu.csdn.net/course/detail/39036 …

26、Qt调用.py文件中的函数

一、开发环境 Qt5.12.0 Python3.7.8 64bit 二、使用 新建一个Qt项目&#xff0c;右击项目名称&#xff0c;选择“添加库” 选择“外部库”&#xff0c;点击“下一步” 点击“浏览”&#xff0c;选择Python安装目录下的libs文件夹中的“python37.lib”文件&#xff0c;点击“下…

【Python如何输入工资,五险一金,专项扣除后得出个税和到手工资(2024年最新)】

最近综合所得年度汇算&#xff0c;正好心血来潮算一下到手工资对不对&#xff0c;有些朋友年综合收入也才几万块&#xff0c;结果年综报税时还要补一两万的个税&#xff0c;这主要是因为跳槽后&#xff0c;上家公司的年薪全平均移到了新的公司每个月中&#xff0c;系统的缺陷导…