【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);
#endifOLED_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 		 512extern 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);
#endifstore_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);#endifOLED_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.mzph.cn/news/720961.shtml

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

相关文章

华为OD机试 - 数字排列 - 深度优先搜索dfs算法(Java 2024 C卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述1、输入2、输出3、说明 四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&a…

外部存储器接口(EMIF)

外部存储器接口&#xff08;EMIF&#xff09; 该设备支持双核架构&#xff1b;为了为每个CPU子系统提供一个专用的EMIF&#xff0c;该设备支持两个EMIF模块——EMIF1和EMIF2。两个模块完全相同&#xff0c;具有相同的功能集&#xff0c;但具有不同的地址/数据大小。EMIF1在CPU…

Unity 角色控制(初版)

角色控制器组件&#xff0c;当然是将组件放在角色上了。 using System.Collections; using System.Collections.Generic; using UnityEngine;public class c1 : MonoBehaviour {// 获取角色控制器private CharacterController player;void Start(){// 加载角色控制器player …

机器学习 | 模型性能评估

目录 一. 回归模型的性能评估1. 平均平方误差(MSE)2. 平均绝对误差(MAE)3. R 2 R^{2} R2 值3.1 R 2 R^{2} R2优点 二. 分类模型的性能评估1. 准确率&#xff08;Accuracy&#xff09;2. 召回率&#xff08;Recall&#xff09;3. 精确率&#xff08;Precision&#xff09;4. …

大模型学习笔记五:RAG

文章目录 一、RAG介绍1)局限性2)通过检索增强生成二、RAG系统的基本搭建流程1)搭建流程简介2)文档的加载和切割3)检索引擎4)LLM接口封装5)prompt模板6)RAG Pipeline初探7)关键字检索局限性三、向量检索1)文本向量2)向量相似度计算3)向量数据库4)基于向量检索的RAG…

电源完整性设计的重要三步!

电源模块布局布线 电源模块是电子设备的能量来源&#xff0c;其性能与布局直接影响到整个系统的稳定性和效率。正确的布局和走线不仅能减少噪声干扰&#xff0c;还能确保电流的顺畅流通&#xff0c;从而提高整体性能。 1、电源模块布局 ● 源头处理&#xff1a;电源模块作为…

Java 面试题

Java 基础 以下代码执行结果&#xff1f; 示例1&#xff1a; public static void main(String[] args) {int a 0;Integer b 0;String c "0";String d new String("0");change(a, b, c, d);System.out.println(a "|" b "|" …

glibc

交叉编译器的glibc库位置&#xff1a; 用此交叉编译器编译的根文件系统对应的开发板上的GLIBC版本&#xff1a; 证明buildroot会使用交叉编译器自带的glibc库来对根文件系统进行编译。

如何在CentOS部署JumpServer堡垒机并实现无公网ip环境远程访问

文章目录 前言1. 安装Jump server2. 本地访问jump server3. 安装 cpolar内网穿透软件4. 配置Jump server公网访问地址5. 公网远程访问Jump server6. 固定Jump server公网地址 前言 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpS…

通义千问1.5(Qwen1.5)大语言模型在PAI-QuickStart的微调与部署实践

作者&#xff1a;汪诚愚&#xff08;熊兮&#xff09;、高一鸿&#xff08;子洪&#xff09;、黄俊&#xff08;临在&#xff09; Qwen1.5&#xff08;通义千问1.5&#xff09;是阿里云最近推出的开源大型语言模型系列。作为“通义千问”1.0系列的进阶版&#xff0c;该模型推出…

【鸿蒙 HarmonyOS 4.0】登录流程

一、背景 登录功能在应用中是一个常用模块&#xff0c;此次使用 HarmonyOS 实现登录流程&#xff0c;包含页面呈现与网络请求。 二、页面呈现 三、实现流程 3.1、创建项目 构建一个ArkTS应用项目(Stage模型)&#xff0c;今天创建流程可查看官网教程&#xff1a;文档中心 目…

llc半桥开关电源基础知识2(电路图简化)

llc半桥开关电源拓扑图如下 稳态:LLC电源已经正常工作,已经输出电压稳定稳态:LLC电源已经正常工作,已经输出电压稳定。 我们在分析拓扑结构的时候,都是基于他已经正常稳定输出的时候来分析的,毕竟LC电源只要以工作啊,绝大多数时间都是工作在稳态。 具体电路图化简分析如…

yolov9训练

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

力扣每日一道系列 --- LeetCode 160. 相交链表

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构探索 ✅LeetCode每日一道 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 LeetCode 160. 相交链表 思路&#xff1a; 首先计算两个链表的长度&#xff0c;然后判断两个链…

如何选择程序员职业赛道

目录 前言1 个人技能分析1.1 技术栈评估1.2 经验积累1.3 数据科学能力 2 兴趣与价值观2.1 用户交互与界面设计2.2 复杂问题解决与系统优化 3 长期目标规划4 市场需求分析4.1 人工智能和云计算4.2 前沿技术趋势 5 就业前景5.1 前端在创意性公司中的应用5.2 后端在大型企业中的广…

前端爬虫+可视化Demo

爬虫简介 可以把互联网比做成一张 “大网”&#xff0c;爬虫就是在这张大网上不断爬取信息的程序。 爬虫是请求网站并提取数据的自动化程序。 省流&#xff1a;Demo实现前置知识&#xff1a; JS 基础Node 基础 &#xff08;1&#xff09;爬虫基本工作流程&#xff1a; 向…

『运维备忘录』之 RegEx 正则表达式实例汇总

运维人员不仅要熟悉操作系统、服务器、网络等知识&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

深入理解Tomcat

目录&#xff1a; TomcatTomcat简介如何下载tomcatTomcat工作原理Tomcat架构图Tomcat组件Server组件Service组件Connector组件Engine组件Host组件Context组件 配置虚拟主机(Host)配置Context Tomcat Tomcat简介 Tomcat服务器是Apache的一个开源免费的Web容器。它实现了JavaEE…

【Android】源码解析 Activity 的构成

本文是基于 Android 14 的源码解析。 当我们写 Activity 时会调用 setContentView() 方法来加载布局。现在来看看 setContentView() 方法是怎么实现的&#xff0c;源码如下所示&#xff1a; 路径&#xff1a;/frameworks/base/core/java/android/app/Activity.javapublic void…

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

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