当前位置: 首页 > ds >正文

E2PROM的学习

STM32 的 Flash 通常用于存储用户程序(代码和常量数据)。例如,一个 STM32F103 系列的微控制器可能有 128KB 的 Flash,其中前 64KB 被应用程序占用,剩下的 64KB 可以用作模拟 E2PROM:

0x08000000 - 0x0800FFFF:应用程序代码(64KB)
0x08010000 - 0x0801FFFF:模拟E2PROM(64KB)
Flash 页大小与对齐

Flash 操作通常以页(Page)为单位进行擦除。不同 STM32 型号的 Flash 页大小可能不同:

  • STM32F1 系列:通常 1KB / 页
  • STM32F4 系列:通常 16KB / 页
  • STM32L0 系列:通常 128 字节 / 页

为了保证模拟 E2PROM 区域从完整的页边界开始,起始地址需要是页大小的整数倍。例如:

  • 对于 1KB 页大小的设备,起始地址应是 0x1000(4096 字节)的倍数
  • 对于 16KB 页大小的设备,起始地址应是 0x4000(16384 字节)的倍数

0x08010000是 1KB、2KB、4KB、8KB、16KB 等常见页大小的整数倍,因此具有良好的通用性。

在 STM32 的 Flash 编程中,"写入操作通常要求地址和数据大小对齐" 是一个重要的约束条件,这涉及到底层硬件的工作机制。下面详细解释这个概念及其实际影响。

一、什么是地址对齐?

地址对齐指的是内存访问地址必须是数据类型大小的整数倍。例如:

  • 8 位数据(1 字节):可以从任意地址开始(无需对齐)
  • 16 位数据(2 字节,半字):地址必须是 2 的倍数(如0x080000000x08000002
  • 32 位数据(4 字节,字):地址必须是 4 的倍数(如0x080000000x08000004

如果地址不满足对齐要求,会导致:

  1. 硬件异常:某些架构直接禁止非对齐访问
  2. 性能下降:处理器需要多次访问内存来拼凑数据
  3. 数据错误:写入的数据可能被截断或错位

二、STM32 Flash 写入的对齐要求

STM32 的 Flash 编程接口对写入操作有严格的对齐要求:

1. 数据类型与对齐关系
操作函数数据大小地址对齐要求
FLASH_ProgramByte()8 位任意地址
FLASH_ProgramHalfWord()16 位地址必须是 2 的倍数
FLASH_ProgramWord()32 位地址必须是 4 的倍数
FLASH_ProgramDoubleWord()64 位地址必须是 8 的倍数(仅部分型号支持)
2. 为什么有对齐要求?
  • 硬件设计限制:Flash 控制器内部按字(32 位)组织数据,非对齐访问需要额外处理
  • 写入效率:对齐的写入操作可以一次性完成,非对齐则需要多次操作
  • 数据完整性:确保数据按正确边界写入

三、实际影响与示例

1. 错误示例

以下代码会导致错误,因为地址0x08010001不是 4 的倍数:

// 错误!地址0x08010001不是4的倍数
FLASH_ProgramWord(0x08010001, 0x12345678);
2. 正确示例

确保地址对齐:

// 正确!地址0x08010000是4的倍数
FLASH_ProgramWord(0x08010000, 0x12345678);// 正确!地址0x08010002是2的倍数
FLASH_ProgramHalfWord(0x08010002, 0x5678);
3. 动态计算对齐地址

在实际应用中,可通过位运算确保地址对齐:

// 将address向上对齐到4的倍数
uint32_t aligned_address = (address + 3) & ~0x03;// 示例:
// address = 0x08010001 → aligned_address = 0x08010004
// address = 0x08010004 → aligned_address = 0x08010004

四、模拟 E2PROM 中的对齐处理

在模拟 E2PROM 时,由于 Flash 写入前需要擦除整页,通常会设计数据结构来确保对齐:

// 定义按4字节对齐的结构体
typedef __packed struct {uint32_t id;         // 变量IDuint32_t value;      // 变量值
} EEPROM_Variable;// 写入操作示例
void EEPROM_WriteVariable(uint32_t address, uint32_t id, uint32_t value) {EEPROM_Variable var = {id, value};FLASH_ProgramWord(address, *(uint32_t*)&var);  // 确保address是4的倍数
}

五、总结

  1. 对齐规则

    • 写入数据时,地址必须是数据大小的整数倍
    • 例如 32 位写入要求地址为XXXXXX00(二进制)
  2. 检查方法

    // 判断地址是否对齐
    if ((address % 4) == 0) {  // 32位对齐// 地址有效
    } else {// 地址无效,需要调整
    }
    
  3. 最佳实践

    • 从页边界开始分配 E2PROM 空间
    • 使用结构体和数组组织数据,确保自然对齐
    • 在写入前检查地址有效性
    • 避免跨页写入,防止数据碎片化

理解并遵守对齐规则是 Flash 编程的基础,违反这些规则可能导致难以调试的问题(如数据丢失、硬件错误)。

http://www.xdnf.cn/news/5078.html

相关文章:

  • 力扣刷题Day 45:旋转图像(48)
  • C语言中的文本读写和二进制读写接口
  • 软件工程之软件项目管理深度解析
  • Elasticsearch太重?它的超轻量的替代品找到了!
  • 【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)
  • 计算机视觉——MedSAM2医学影像一键实现3D与视频分割的高效解决方案
  • 数图闪耀2025深圳CCFA中国零售博览会:AI+零售数字化解决方案引发现场热潮
  • 【2025最新】gitee+pycharm完成项目的上传与管理
  • “ES7+ React/Redux/React-Native snippets“常用快捷前缀
  • Vue 生命周期详解
  • com.fasterxml.jackson.dataformat.xml.XmlMapper把对象转换xml格式,属性放到标签<>里边
  • 部署Superset BI(四)连接sql server数据库
  • CNG汽车加气站操作工岗位职责
  • 2025医疗信息化趋势:健康管理系统如何重构智慧医院生态
  • 李沐《动手学深度学习》 | 多层感知机
  • WEB前端表单及表格标签综合案例
  • World of Warcraft [CLASSIC][80][Deluyia] [Fragment of Val‘anyr]
  • Dify智能体平台源码二次开发笔记(8)- OpenAvatarChat数字人项目+dify智能体完美融合
  • 升级 Azure Kubernetes 服务群集的关键注意事项
  • Spring Cloud LoadBalancer (负载均衡)
  • Kubernetes生产实战:NodePort端口范围的隐藏规则与调优指南
  • C——数组和函数实践:扫雷
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】电商数据分析案例-9.4 可视化报告输出
  • 两台服务器之前共享文件夹
  • 第十五章,SSL VPN
  • 一文了解氨基酸的分类、代谢和应用
  • Spring Web MVC基础理论和使用
  • Missashe考研日记-day36(改版说明)
  • AWS之数据分析类产品
  • 算法与数据结构 - 二叉树结构入门