stm32入门学习16-闪存

news2024/9/22 13:34:49

(一)闪存

在之前的学习中,已经学习过了W25Q64这个外挂闪存,在stm32内部也有一块闪存,其主要用于存放我们编译的代码,如果我们需要一些掉电不丢失的数据,但是又懒得外挂一块闪存,就可以把少量数据写入stm32内部的闪存中,其操作与写入外设闪存的操作基本相同,且有库函数封装,使用的函数也很简单

void FLASH_Unlock(void);
// 解锁 FLASH 编写擦除控制器

void FLASH_Lock(void);
// 锁定 FLASH 编写擦除控制器

FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
// 擦除一页
 
FLASH_Status FLASH_EraseAllPages(void);
// 擦除所有

FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
// 写入32位数据

FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
// 写入16位数据

(二)读取、写入、擦除

(1)读取

对于读取闪存,没有封装的库函数用于读取,因为要读取只要给定指针即可,通过解引用一个地址指针则可以读取任意位置任意大小的数据

uint32_t flash_read_word(uint32_t address)
{
	return *(uint32_t*)address;
}

uint16_t flash_read_halfword(uint32_t address)
{
	return *(uint16_t*)address;
}

uint8_t flash_read_byte(uint32_t address)
{
	return *(uint8_t*)address;
}

这里分别读取32比特(1字)、16比特(半字)、8比特(1字节),接收的是一个32位的无符号整形数字,里面存放要读取的地址,随后强转换为不同数据大小的指针,最后解引用读取该指针地址下的数据

(2)写入

写入只需要调用库函数即可,写入之前要先解锁编写擦除控制器,写完后要对编写擦除控制器上锁,stm还对写入等操作进行了加锁,还有写入等待事件等问题,但是这些封装的库函数都帮我们完成了

void flash_write_half_word(uint32_t address, uint16_t inf)
{
	FLASH_Unlock();
	FLASH_ProgramHalfWord(address, inf);
	FLASH_Lock();
}

void flash_write_word(uint32_t address, uint32_t inf)
{
	FLASH_Unlock();
	FLASH_ProgramWord(address, inf);
	FLASH_Lock();
}

这里分别写入16位数据和32位数据

(3)擦除

擦除有所有擦除和按页擦除,同样,擦除操作之前要解锁编写擦除控制器,擦除完成后要对其上锁

void flash_erase_page(uint32_t address)
{
	FLASH_Unlock();
	FLASH_ErasePage(address);
	FLASH_Lock();
}

void flash_erase_all()
{
	FLASH_Unlock();
	FLASH_EraseAllPages();
	FLASH_Lock();
}

(三)不覆盖写入

我们在写入之前必须执行擦除操作,如果我们在上电后写入,有可能把上次存储的掉电不丢失的数据擦除,我们可以在上电后进行一次初始化,把里面的数据都搬到数据里,然后再执行写入等操作

这里只操作闪存中的最后一页,将其最开始的16位作为标志位,判断之前是否写过,0x5555即原本有数据,0xFFFF为无数据

#define last_page 0x0801FC00

uint16_t information[128] = {0};

void op_flash_init()
{
	uint16_t i;
	if (flash_read_halfword(last_page) == 0x5555)
	{
		for (i = 0; i < 128; i++)
		{
			information[i] = flash_read_halfword(last_page+i*2);
		}
	}
}

 在写入数据之前,把标志位置为0x5555,随后擦除页,写入数据所有数据,我们在主程序中想要修改数据可以直接修改数组即可

void op_write_halfword()
{
	uint16_t i;
	information[0] = 0x5555;
	flash_erase_page(last_page);
	for (i = 0; i < 128; i++)
	{
		flash_write_half_word(last_page + i*2, information[i]);
	}
}

再写一个读写函数,方便读取最后一页的第几个16位数据

uint16_t op_read_half_word(int place)
{
	int i;
	for (i = 0; i < 128; i++)
	{
		information[i] = flash_read_halfword(last_page+i*2);
	}
	return information[place];
}

 这样我们就可以在主函数里先调用初始化函数,然后可以写入要写的数据,这样即使掉电也不会丢失

(四)读取芯片ID号

对于stm32芯片,每个芯片都有独一无二的芯片ID号,称为产品的唯一身份标识,总共有96位数据,其基地址为0x1FFF F7E8,可以通过这个地址加适当的地址偏移来读取芯片ID,芯片的ID有这些用途

这里就先读取芯片ID来显示一下

读取芯片ID和读取闪存一样,只要一个指针即可

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

#define base_loc 0x1FFFF7E8

int main()
{
	OLED_Init();
	OLED_ShowHexNum(1, 1, *(uint16_t*)base_loc, 4);
	OLED_ShowHexNum(2, 1, *(uint16_t*)(base_loc+0x02), 4);
	OLED_ShowHexNum(3, 1, *(uint32_t*)(base_loc+0x04), 8);
	OLED_ShowHexNum(4, 1, *(uint32_t*)(base_loc+0x08), 8);
	while (1)
	{
		
	}
	return 0;
}

这样我们就可以读取自己stm32的身份标识了

(五)总结

通过读写stm32的闪存部分和读取芯片的身份标识,我们了解了读写stm32闪存部分的基本操作和方法

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

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

相关文章

树莓派4b换源+安装neo4j知识图谱

烧录树莓派系统&#xff0c; ssh 1.在SD中的boot区中&#xff0c;新建两个文件ssh(没有任何后缀)和wpa_supplicant.conf。 2.往wpa_supplicant.conf中写入 countryCN ctrl_interfaceDIR/var/run/wpa_supplicant GROUPnetdev update_config1 network{ ssid“wifi账号” psk“…

VS Code 配置docker 管理员权限终端

问题描述 在容器中需要使用sudo或者su root时候&#xff0c;权限不够&#xff0c;被灵魂提问。 然而&#xff0c;镜像是官方发布的&#xff0c;翻遍了githubissues也没有找到password. 解决 Attach shell 在docker插件中&#xff0c;attach shell 可以直接获得shell。 所…

AI顾投高级策略之六:马丁格尔策略

作者&#xff1a;老余捞鱼 原创不易&#xff0c;转载请标明出处及原作者。 写在前面的话&#xff1a; 在投资世界中&#xff0c;隐藏着众多精妙的策略&#xff0c;其中一些历经时间的考验&#xff0c;被基金经理们广泛使用。今天&#xff0c;我们要探讨的是马丁格尔策略…

不依靠for循环,Python如何对列表进行去重并保留排列顺序

在python中&#xff0c;我们想要从列表中删除重复元素&#xff0c;并且保留去重之前的先后排列顺序。在这里&#xff0c;我们本文不谈论for循环&#xff0c;我们来谈论其他的更优方法——OrderedDict和set。 要知道&#xff0c;OrderedDict可以通过保留插入顺序来实现元素去重…

【面试题】接雨水

接雨水 仅学习 一、问题描述 二、解调思路 这个问题是一个典型的双指针问题&#xff0c;也称为"接雨水问题"。我们可以通过遍历数组两次来解决这个问题&#xff1a;一次从左到右&#xff0c;一次从右到左&#xff0c;分别记录每个位置左边和右边的最大高度。然后&…

springboot学校防疫物资管理平台的设计与实现boot--论文源码调试讲解

第2章 开发环境与技术 本章节对开发学校防疫物资管理平台管理系统需要搭建的开发环境&#xff0c;还有学校防疫物资管理平台管理系统开发中使用的编程技术等进行阐述。 2.1 Java语言 Java语言是当今为止依然在编程语言行业具有生命力的常青树之一。Java语言最原始的诞生&…

C语言—扫雷项目

一、扫雷游戏分析和设计 &#xff08;1.1&#xff09;扫雷游戏功能说明 • 使⽤控制台实现经典的扫雷游戏 • 游戏可以通过菜单实现继续玩或者退出游戏 • 扫雷的棋盘是9*9的格⼦ • 默认随机布置10个雷 • 可以排查雷 ◦ 如果位置不是雷&#xff0c;就显⽰周围有⼏个雷 ◦ 如…

C# 元组类型详解与示例

文章目录 1. 元组的基本概念1.1 元组的定义1.2、元组的类型 2. 元组的特性2.1 元组的命名元素2.2 元组的类型推断2.3 元组的结构2.4 元组的比较和哈希 3. 元组的实际应用3.1 方法返回多个值3.2 作为数据容器3.3 元组与数据结构 4. 总结 元组&#xff08;Tuple&#xff09;是 C#…

【AI】机器学习基本概念详解1

友情链接&#xff1a;numpy使用、SciPy、Matplotlib 定期更新&#xff0c;建议关注、点赞、收藏。 目录 监督学习 or 非监督学习clustering & non-clustering分类 or 回归线性回归逻辑回归 目标函数or 损失函数规范化归一化标准化正则化&#xff08;惩罚penalty&#xff09…

如何制作优秀的年终总结PPT?

制作优秀的年终总结PPT&#xff0c;是每位职场人士在年底时的一项重要任务。 一个优秀的年终总结PPT不仅能够清晰地展示你过去一年的工作成果&#xff0c;还能让领导对你的工作能力和态度留下深刻印象。 下面&#xff0c;我将从几个方面详细讲解如何制作这样的PPT&#xff0c…

杰理AC7916与MK米客方德SD NAND:高效适配,卓越存储

杰理科技的AC7916是一款高性能、多功能的系统级芯片&#xff08;SoC&#xff09;&#xff0c;广泛应用于智能终端产品&#xff0c;如AI智能音箱、蓝牙音箱、蓝牙耳机等。这款芯片以其卓越的性能和丰富的接口选项&#xff0c;满足了多样化的市场需求。 AC7916接口及性能特点 AC…

如何避免常见的R语言学习陷阱?

学习R语言不仅能够增强数据分析能力&#xff0c;还能开拓解决复杂问题的新方法。然而&#xff0c;在学习R语言的过程中&#xff0c;许多初学者会遇到各种陷阱&#xff0c;这些陷阱不仅会延缓学习进度&#xff0c;还可能导致学习动机的丧失。 陷阱一&#xff1a;忽视基础知识 基…

Java面向对象与封装

目录 封装 封装引入 private修饰符 this关键字 构造函数 JavaBean 标准JavaBean JavaBean中的成员与数据库的关系 static关键字 static基本使用 static关键字访问特点 可变参数 对象数组与传值/址调用 对象数组 传值调用与传址调用 命令行参数 封装 封装引入 …

Unity 中创建动画的教程

Unity 动画创建教程 在游戏开发中&#xff0c;生动的动画能够极大地提升玩家的体验。在这篇教程中&#xff0c;我们将一起探索如何在 Unity 中创建动画。 一、准备工作 首先&#xff0c;确保您已经安装了最新版本的 Unity 引擎。创建一个新的 Unity 项目或者打开您现有的项目…

昂科烧录器支持PAI-IC澎湃微电子的32位微控制器PT32L031K6T6

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中PAI-IC澎湃微电子的32位微控制器PT32L031K6T6已经被昂科的通用烧录平台AP8000所支持。 PT32L031K6T6是基于Cortex-M0内核的一款32位高性能微控制器&#xff0c;支持工作电压 1…

C# VisionPro 海康相机SDK源代码

运行界面如下所时&#xff1a; 实时图像效果如下&#xff1a; Winform窗体代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Fo…

为什么选择搭建自己的大模型?

在数字化和智能化的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正迅速成为企业和机构的核心驱动力。无论是在数据分析、自然语言处理&#xff0c;还是自动化决策&#xff0c;AI的应用范围广泛且深远。而在众多AI解决方案中&#xff0c;本地搭建专属的大模型正逐渐成…

前端vue项目——打包部署(nginx中部署静态资源)

1、当前的开发方式 前端人员开发前端&#xff0c;后端人员开发后端的java工程&#xff0c;最终要将开发完毕的前端工程和后端工程分开部署在对应的服务器上&#xff08;前端流行的nginx&#xff09; 2、打包 &#xff08;1&#xff09;原理 &#xff08;2&#xff09; &#xf…

git 两个分支对比以及合并

git 两个分支对比以及合并 git 两个分支对比以及合并显示两个分支提示之间的差异使用图形化工具&#xff0c;如pycharm 打补丁的一般流程diff命令&#xff1a;生成补丁包文件patch命令&#xff1a;打补丁命令 Git Merge 与 Rebase[重要]使用 merge 命令来进行分支合并rebase 命…

使用 GPT-4 Vision 的 CLIP 嵌入来改进多模态 RAG

多模态 RAG 将附加模态集成到传统的基于文本的 RAG 中&#xff0c;通过提供额外的背景信息和基础文本数据来增强 LLM 的问答能力&#xff0c;从而提高理解力。 我们直接嵌入图像进行相似性搜索&#xff0c;绕过文本字幕的有损过程&#xff0c;以提高检索准确性。 使用基于 CL…