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

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学习笔记汇总

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spark中读parquet文件是怎么实现的

背景 最近在整理了一下 spark对Parquet的写文件的过程&#xff0c;也是为了更好的理解和调优Spark相关的任务&#xff0c; 因为对于Spark来说&#xff0c;任何一个事情都不是独立的存在的&#xff0c;比如说parquet文件的rowgroup设置的大小对读写的影响&#xff0c;以及parqu…

数据删除

目录 数据删除 删除员工编号为 7369 的员工信息 删除若干个数据 删除公司中工资最高的员工 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 数据删除 删除数据就是指删除不再需要的数据 delete from 表名称 [where 删…

Java架构之路-架构应全面了解的技术栈和工作域

有时候我在想这么简单简单的东西&#xff0c;怎么那么难以贯通。比如作为一个架构师可能涉及的不单单是技术架构&#xff0c;还包含了项目管理&#xff0c;一套完整的技术架构也就那么几个技术栈&#xff0c;只要花点心思&#xff0c;不断的往里面憨实&#xff0c;总会学的会&a…

huggingface学习|controlnet实战:云服务器使用StableDiffusionControlNetPipeline生成图像

ControlNet核心基础知识 文章目录 一、环境配置和安装需要使用的库二、准备数据及相关模型三、参照样例编写代码&#xff08;一&#xff09;导入相关库&#xff08;二&#xff09;准备数据&#xff08;以知名画作《戴珍珠耳环的少女》为例&#xff09;&#xff08;三&#xff0…

C++惯用法之RAII思想: 资源管理

C编程技巧专栏&#xff1a;http://t.csdnimg.cn/eolY7 目录 1.概述 2.RAII的应用 2.1.智能指针 2.2.文件句柄管理 2.3.互斥锁 3.注意事项 3.1.禁止复制 3.2.对底层资源使用引用计数法 3.3.复制底部资源(深拷贝)或者转移资源管理权(移动语义) 4.RAII的优势和挑战 5.总…

制造业数字化赋能:1核心2关键3层面4方向

随着科技的飞速发展&#xff0c;制造业正站在数字化转型的风口浪尖。数字化转型不仅关乎企业效率与利润&#xff0c;更决定了制造业在全球竞争中的地位。那么&#xff0c;在这场波澜壮阔的数字化浪潮中&#xff0c;制造业如何抓住机遇&#xff0c;乘风破浪&#xff1f;本文将从…

Maven终端命令生成Spring-boot项目并输出“helloworld“

1. 生成项目 mvn archetype:generate填写groupId和artifactId&#xff0c;其余默认即可 2. 修改pom.xml文件 将如下内容放入pom.xml文件内 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artif…

计网面试题整理上

1. 计算机网络的各层协议及作用&#xff1f; 计算机网络体系可以大致分为一下三种&#xff0c;OSI七层模型、TCP/IP四层模型和五层模型。 OSI七层模型&#xff1a;大而全&#xff0c;但是比较复杂、而且是先有了理论模型&#xff0c;没有实际应用。TCP/IP四层模型&#xff1a…

Git入门学习笔记

Git 是一个非常强大的分布式版本控制工具&#xff01; 在下载好Git之后&#xff0c;鼠标右击就可以显示 Git Bash 和 Git GUI&#xff0c;Git Bash 就像是在电脑上安装了一个小型的 Linux 系统&#xff01; 1. 打开 Git Bash 2. 设置用户信息&#xff08;这是非常重要的&…

使用GRU进行天气变化的时间序列预测

本文基于最适合入门的100个深度学习项目的学习记录&#xff0c;同时在Google clolab上面是实现&#xff0c;文末有资源连接 天气变化的时间序列的难点 天气变化的时间序列预测涉及到了一系列复杂的挑战&#xff0c;主要是因为天气系统的高度动态性和非线性特征。以下是几个主…

(十五)【Jmeter】取样器(Sampler)之HTTP请求

简述 操作路径如下: HTTP请求 (HTTP Sampler): 作用:模拟发送HTTP请求并获取响应。配置:设置URL、请求方法、请求参数等参数。使用场景:测试Web应用程序的HTTP接口性能。优点:支持多种HTTP方法和请求参数,适用于大多数Web应用程序测试。缺点:功能较为基础,对于复杂…

突发,Anthropic推出突破性Claude 3系列模型,性能超越GPT-4

&#x1f989; AI新闻 &#x1f680; 突发&#xff0c;Anthropic推出突破性Claude 3系列模型 摘要&#xff1a;人工智能创业公司Anthropic宣布推出其Claude 3系列大型语言模型&#xff0c;该系列包括Claude 3 Haiku、Claude 3 Sonnet和Claude 3 Opus三个子模型&#xff0c;旨…

第18章 Java I/O系统

第18章 Java I/O系统 18.1 File类 File类不仅仅指文件&#xff0c;还能代表一个目录下的一组文件。 18.1.1 目录列表器 public class Test {public static void main(String[] args) {File file new File("E:\\test");String[] strings file.list(new DirFilte…

安装Proxmox VE虚拟机平台

PVE是专业的虚拟机平台&#xff0c;可以利用它安装操作系统&#xff0c;如&#xff1a;Win、Linux、Mac、群晖等。 1. 下载镜像 访问PVE官网&#xff0c;下载最新的PVE镜像。 https://www.proxmox.com/en/downloads 2. 下载balenaEtcher balenaEtcher用于将镜像文件&#…

「滚雪球学Java」:多线程(章节汇总)

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

数据可视化原理-腾讯-3D网格热力图

在做数据分析类的产品功能设计时&#xff0c;经常用到可视化方式&#xff0c;挖掘数据价值&#xff0c;表达数据的内在规律与特征展示给客户。 可是作为一个产品经理&#xff0c;&#xff08;1&#xff09;如果不能够掌握各类可视化图形的含义&#xff0c;就不知道哪类数据该用…

带你全方位体验 Amazon Connect

1.前言 授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道。 近日亚马逊云科技在拉斯维加斯拉开了年度客户大会-亚马逊云科技 re:Invent 的序…

python网络爬虫教程笔记(1)

系列文章目录 文章目录 系列文章目录前言一、爬虫入门1.爬虫是什么&#xff1f;2.爬虫工作原理3.爬虫基本原理4.工作流程5.HTTP请求6.HTTP响应7.HTTP原理&#xff1a;证书传递、验证和数据加密、解密过程解析8.Urllib.request库的使用9.TCP3次握手&#xff0c;4次挥手过程 总结…

PHP+MySQL实现后台管理系统增删改查之够用就好

说明 最近要给博客弄个后台&#xff0c;不想搞得很复杂&#xff0c;有基本的增删改查就够了&#xff0c;到网上找了一圈发现这个不错&#xff0c;很实用&#xff0c;希望可以帮到大家&#xff0c;需要的朋友评论区留下邮箱&#xff0c;我安排发送。 演示效果 项目介绍 本项目…

【RISC-V 指令集】RISC-V 向量V扩展指令集介绍(一)-向量扩展编程模型

1. 引言 以下是《riscv-v-spec-1.0.pdf》文档的关键内容&#xff1a; 这是一份关于向量扩展的详细技术文档&#xff0c;内容覆盖了向量指令集的多个关键方面&#xff0c;如向量寄存器状态映射、向量指令格式、向量加载和存储操作、向量内存对齐约束、向量内存一致性模型、向量…