STM32 内部 EEPROM 读写
STM32 的某些系列 MCU 自带 EEPROM。笔者使用的 STM32L151RET6 自带 16 KB 的 EEPROM,可以用来存储自定义的数据。在芯片选型时,自带 EEPROM 也可以作为一个考量点,省去了在外接 EEPROM 的烦恼。
下面简单介绍下 STM32 内部 EEPROM 的读写流程。
Memory Mapping
以笔者使用的这款 STM32L151RET6 MCU 为例,自带 16 KB 的 EEPROM。Map 到了 2 个 Bank 中:

- Data EEPROM Bank1: 0x08080000 ~ 0x08081FFF (8KB)
- Data EEPROM Bank2: 0x08082000 ~ 0x08083FFF (8KB)
Operations
内部 EEPROM 的操作无非就是 读取、写入、擦除 等操作。直接调用库函数或者 HAL 库中对应的 API 即可。这里只是对内部 EEPROM 的操作做一个简要的分析。
本文档主要以库函数中的 EEPROM 接口 API 进行分析。
Unlocking/locking memory
STM32 复位后,Data EEPROM 和 Program/erase 控制寄存器 (FLASH_PECR) 默认是 处于 lock 状态,需要 unlock 之后才能执行写入和擦除操作。
如何 unlock 可以参考芯片对应的 datasheet,简单的说就是往 Program/erase 密钥寄存器 (FLASH_PEKEYR) 写指定的密钥集即可。
- Write PEKEY1= 0x89ABCDEF to the Program/erase key register (FLASH_PEKEYR)
- Write PEKEY2= 0x02030405 to the Program/erase key register (FLASH_PEKEYR)
/*** @brief Unlocks the data memory and FLASH_PECR register access.* @param None* @retval None*/
void DATA_EEPROM_Unlock(void)
{if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET){ /* Unlocking the Data memory and FLASH_PECR register access*/FLASH->PEKEYR = FLASH_PEKEY1;FLASH->PEKEYR = FLASH_PEKEY2;}
}
#define FLASH_PEKEY1 ((uint32_t)0x89ABCDEF) /*!< Flash program erase key1 */
#define FLASH_PEKEY2 ((uint32_t)0x02030405) /*!< Flash program erase key: used with FLASH_PEKEY2to unlock the write access to the FLASH_PECR register anddata EEPROM */
如何 lock 可以参考芯片对应的 datasheet,相较于 unlock,lock 仅需要置位 Program/erase 控制寄存器 (FLASH_PECR) 中的 FLASH_PECR 位。
/*** @brief Locks the Data memory and FLASH_PECR register access.* @param None* @retval None*/
void DATA_EEPROM_Lock(void)
{/* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */FLASH->PECR |= FLASH_PECR_PELOCK;
}
Erasing memory
对于 EEPROM,支持以下 2 种擦除方式:
- Word 和 double word 擦除
- Mass 擦除
对于 Word 和 double word 擦除,这种方式仅针对 EEPROM;但是对于 Mass 擦除,这种方式针对 Program memory、EEPROM 和 Option bytes。所以尽量在使用 EEPROM 的时候采用 Word 和 double word 擦除方式。
EEPROM 擦除方式也很简单,只需要将值 0x00000000 写入到对应的有效的擦除地址中即可。

/*** @brief Erase a word in data memory.* @param Address: specifies the address to be erased.* @note For STM32L1XX_MD, A data memory word is erased in the data memory only * if the address to load is the start address of a word (multiple of a word).* @note To correctly run this function, the DATA_EEPROM_Unlock() function* must be called before.* Call the DATA_EEPROM_Lock() to disable the data EEPROM access* and Flash program erase control register access(recommended to protect * the DATA_EEPROM against possible unwanted operation).* @retval FLASH Status: The returned value can be: * FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.*/
FLASH_Status DATA_EEPROM_EraseWord(uint32_t Address)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_DATA_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);if(status == FLASH_COMPLETE){/* Write "00000000h" to valid address in the data memory" */*(__IO uint32_t *) Address = 0x00000000;}/* Return the erase status */return status;
}
Programming memory
写入 EEPROM 的步骤也很简单,一般的流程如下:
- unlock
- erase
- write
- lock
/*** @brief Programs a word at a specified address in data memory without erase.* @note To correctly run this function, the DATA_EEPROM_Unlock() function* must be called before.* Call the DATA_EEPROM_Lock() to disable the data EEPROM access* and Flash program erase control register access(recommended to protect * the DATA_EEPROM against possible unwanted operation).* @note The function DATA_EEPROM_FixedTimeProgramCmd() can be called before * this function to configure the Fixed Time Programming.* @param Address: specifies the address to be written.* @param Data: specifies the data to be written.* @retval FLASH Status: The returned value can be:* FLASH_ERROR_PROGRAM, FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */
FLASH_Status DATA_EEPROM_ProgramWord(uint32_t Address, uint32_t Data)
{FLASH_Status status = FLASH_COMPLETE;/* Check the parameters */assert_param(IS_FLASH_DATA_ADDRESS(Address));/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);if(status == FLASH_COMPLETE){*(__IO uint32_t *)Address = Data;/* Wait for last operation to be completed */status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);}/* Return the Write Status */return status;
}
Reading Momory
读取 EEPROM 中的数据就没那么多步骤了,直接读取对应的 Map 的 Bank 即可。
Note
对于 EEPROM 的操作,以下几点需要注意:
- 尽量以 4 字节为一个单位进行操作
- 在执行写入或者擦除操作的时候,尽量将全局中断关闭,以免中断触发引起其它的问题
- 不要对相同的一个 Bank 同时做多种操作,尽量保证一个 Bank 只有一种操作在执行
列出一段 EEPROM 的参考代码:
void EEPROM_Test(void)
{__set_PRIMASK(1);DATA_EEPROM_Unlock();/* EEPROM Operations */DATA_EEPROM_Lock();__set_PRIMASK(0);
}
相关文章:
STM32 内部 EEPROM 读写
STM32 的某些系列 MCU 自带 EEPROM。笔者使用的 STM32L151RET6 自带 16 KB 的 EEPROM,可以用来存储自定义的数据。在芯片选型时,自带 EEPROM 也可以作为一个考量点,省去了在外接 EEPROM 的烦恼。 下面简单介绍下 STM32 内部 EEPROM 的读写流…...
androidStudio sync failed GradlePropertiesModel (V2)
大家在增加模块的时候经常遇到吧?重启后就好了。 Cannot get GradlePropertiesModel (V2) for project ‘GradleProject{path’:app’}’ 然而,今天开机以后,无论如何,点击gradle的大象图标(Sync Project with Gradle Files)&…...
结构方程模型(SEM)
结构方程模型(Structural Equation Modeling)是分析多变量间因果关系的利器,在众多学科领域具有巨大应用潜力。我们前期推出的《基于R语言结构方程模型》课程通过结构方程原理介绍、结构方程全局和局域估计、模型构建和调整、潜变量分析、复合…...
基于UDP的网络编程
UDP服务端 #ifdef _WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS #define close closesocket #include <winsock2.h> #else #include <arpa/inet.h> #include <netdb.h> #include <netinet/in.h> #in…...
vue判断组件有没有传入的slot有就渲染slot没有就渲染内部节点
GPT4国内站点:海鲸AI 在 Vue 中,你可以使用 $slots 对象来检查是否有特定的插槽内容被传递给组件。Vue 3 中的 $slots 是一个对象,其中包含了所有插槽的引用。如果插槽没有内容,对应的插槽属性将会是 undefined。 下面是一个例子…...
MS713/MS713T:CMOS 低压、4Ω四路单刀单掷开关,替代ADG713
产品简述 MS713/MS713T 是一款单芯片 CMOS 4 路可选择开关,具有低 功耗、高开关速度、低导通阻抗、低漏电和高带宽特性。其工作 电压范围是 1.8V 到 5.5V ,可以广泛应用在电池供电仪器仪表、新 一代的模数转换和数模转换系统中。其高带宽特性可用在 …...
Android 内容生成pdf文件
1.引入itext7 implementation com.itextpdf:itext7-core:7.1.13上面比较大,可以直接下载需要集成的jar包 implementation files(libs\\layout-7.1.13.jar) implementation files(libs\\kernel-7.1.13.jar) implementation files(libs\\io-7.1.13.jar) implementatio…...
Javaweb-日程管理
094.日程管理第二期_准备数据库和实体类_哔哩哔哩_bilibili navicat 下载 学生认证: Navicat 教育版 - 学生许可证 | Navicat navicat连接mysql 使用navicat连接mysql数据库创建数据库、表、转储sql文件,导入sql数据_哔哩哔哩_bilibili...
SwiftUI之深入解析如何创建一个灵活的选择器
一、前言 在 Dribbble 上找到的设计的 SwiftUI 实现时,可以尝试通过一些酷炫的筛选器扩展该项目以缩小结果列表。筛选视图将由两个独立的筛选选项组成,两者都有一些可选项可供选择。但是,在使用 UIKit 时,总是将这种类型的视图实…...
【模拟量采集1.2】电阻信号采集
【模拟量采集1.2】电阻信号采集 1 怎么测?2 测输入电阻电压即转为测模拟电压值,这里需要考虑选用怎样的辅助电阻?3 实际电路分析3.1 在不考虑 VCC-5V 电压的纹波等情况时(理想化此时输入的 VCC 就是稳定的 5V)3.2 若考…...
c++牛客总结
一、c/c语言基础 1、基础 1、指针和引用的区别 指针是一个新的变量,指向另一个变量的地址,我们可以通过这个地址来修改该另一个变量; 引用是一个别名,对引用的操作就是对变量本身进行操作;指针可以有多级 引用只有一…...
ts相关笔记(基础必看)
推荐一下小册 TypeScript 全面进阶指南,此篇笔记来源于此,记录总结,加深印象! 另外,如果想了解更多ts相关知识,可以参考我的其他笔记: vue3ts开发干货笔记TSConfig 配置(tsconfig.…...
Docker随笔
OverView 为什么需要Docker 如果我需要部署一个服务,那么我需要提前部署其他应用栈,不同的应用栈会依赖于不用的操作系统和环境。这样做会产生一些负面影响: 不同版本依赖较长的部署时间不同的Dev/Test/Prod环境 这时我们需要一个工具去解…...
uni-app 前后端调用实例 基于Springboot
锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…...
vue3+ts开发干货笔记
总结一下在vue3中ts的使用。当篇记录部分来自于vue官网,记录一下,算是加深印象吧。 纯干笔记,不断补充,想到什么写什么,水平有限,欢迎评论指正! 另外,如果想了解更多ts相关知识&…...
Android开发新的一年Flag
在新的一年里,为了提升Android开发技能,实现更优质的应用程序,我们制定了2024的新年Flag。这些Flag涵盖了技术学习、代码优化、架构升级、用户体验等多个方面,旨在帮助我们成为更优秀的Android开发者。 1. 学习新技术 1.1. Andr…...
好的OODA循环与快慢无关
OODA循环是指观察(Observe)、导向(Orient)、决策(Decide)和行动(Act)这四个步骤的循环过程。它是一种决策和行动的框架,旨在帮助个人或组织更快地适应和应对变化。 OODA循…...
Android 车联网——CarUserService介绍(十三)
一、简介 CarUserService 是 Android 汽车平台的一个组件,它用于管理和提供车辆用户信息。该组件可以让开发者创建和管理与车辆用户相关的数据和配置,包括车辆拥有者和乘客的个人信息、偏好设置、用户偏好配置文件等。 CarUserService 提供了以下功能和特性: 用户配置管理:…...
【开题报告】基于微信小程序的母婴商品仓库管理系统的设计与实现
1.选题背景 随着社会经济的发展和家庭生活水平的提高,母婴商品市场逐渐兴起。然而,传统的母婴商品仓库管理方式存在着许多问题,如信息不透明、操作繁琐等。为了提高仓库管理的效率和准确性,基于微信小程序的母婴商品仓库管理系统…...
分布式锁相关问题(三)
Redis实战精讲-13小时彻底学会Redis 一、什么是分布式锁? 要介绍分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。 l 线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一个线程执行该方法或该…...
形转化理论:基本概念、深刻机制与研究框架的系统性阐述
摘要形转化理论(Form-Transformation Theory, FTT)是一种基于信息本体论的全新物理范式,旨在将宇宙的基本实在重新界定为永恒、离散的信息处理网络动力学。本文系统阐述该理论的核心概念体系、两大支柱性数学框架及从微观网络到宏观物理的涌现…...
Windows10系统V-rep安装避坑指南:从百度网盘资源到环境配置
1. 为什么选择V-rep以及准备工作 如果你是机器人学或仿真技术的初学者,V-rep(现更名为CoppeliaSim)绝对是一个值得尝试的仿真平台。它轻量级、跨平台,而且对硬件要求不高,特别适合在个人电脑上进行算法验证和教学演示…...
本地AI任务编排工具AgentForge:从看板管理到多代理协作
1. 项目概述:一个能调度AI编码代理的本地看板工具如果你和我一样,日常开发中经常需要让Claude Code这类AI编码助手去执行一些重复性的代码审查、重构或者生成任务,并且希望这些任务能像CI/CD流水线一样被编排、调度和监控,那么你一…...
离散流匹配与MaskFlow框架:视频生成技术解析
1. 离散流匹配在视频生成中的技术演进 视频生成技术近年来取得了显著进展,但长视频生成仍然面临两大核心挑战:一是如何有效建模视频中复杂的时空动态关系,二是如何在有限的计算资源下实现高效生成。传统方法通常采用固定长度的训练序列&…...
保姆级教程:用Intel官方工具搞定Realsense D435深度不准和黑点问题
深度视觉优化实战:Intel RealSense D435深度校准全流程解析 刚拆封的RealSense D435摄像头在深度模式下出现零星黑点?深度图某些区域数值明显失真?这些问题往往不是硬件缺陷,而是出厂校准参数与实际使用环境不匹配导致的。作为计算…...
iOS越狱防火墙ijfw:从网络流量监控到精细化应用管控实战
1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫ijfw,全称是iOS Jailbreak Firewall。顾名思义,这是一个专门为越狱后的iOS设备设计的防火墙工具。如果你和我一样,是个喜欢在iPhone上“折腾”的玩家,或者对…...
基于EVE ESI API与AI Agent的自动化游戏监控与数据分析实践
1. 项目概述:为AI助手注入EVE宇宙的灵魂 如果你是一名《EVE Online》的玩家,同时又对AI自动化工具感兴趣,那么你很可能和我一样,长期被一个矛盾所困扰:一方面,EVE这个沙盒宇宙充满了需要监控和管理的日常事…...
PiliPlus:用Flutter重新定义你的B站观影体验
PiliPlus:用Flutter重新定义你的B站观影体验 【免费下载链接】PiliPlus PiliPlus 项目地址: https://gitcode.com/gh_mirrors/pi/PiliPlus 在众多视频平台中,B站以其独特的社区文化和丰富内容生态深受用户喜爱。然而,官方客户端的一些…...
大模型“开源”迷思:小白与程序员必看,收藏这份避坑指南!
大模型“开源”并非简单代码开放,涉及权重、数据、训练方法等多维度。文章详解不同协议(如MIT、Apache-2.0、GPL、AGPL等)对企业商业化的影响,强调理解协议边界至关重要。从开放权重到真正开源,企业需关注协议对商用、…...
FaaS承载AI Agent的性能断崖真相,实测AWS Lambda vs Cloudflare Workers响应延迟对比(含17项压测数据)
更多请点击: https://intelliparadigm.com 第一章:FaaS承载AI Agent的性能断崖真相 当AI Agent被部署至函数即服务(FaaS)平台时,其推理延迟常出现非线性跃升——从本地毫秒级响应骤增至数秒甚至超时失败。这一“性能断…...
