单片机
返回首页

STM32 Flash对齐技巧详解

2025-10-17 来源:bilibili

这行代码 uint32_t aligned_address = (address + 3) & ~0x03; 是一个经典的位运算技巧,用于将任意地址值向上取整为 4 的倍数。下面从原理到示例详细解释:


一、核心目标:向上对齐到 4 的倍数

对齐需求:STM32 的 32 位 Flash 写入要求地址必须是 4 的倍数(如 0x08010000、0x08010004)

向上取整:无论输入地址是否已经对齐,都返回大于等于该地址的最小 4 的倍数

例如:

输入 0x08010001 → 输出 0x08010004

输入 0x08010004 → 输出 0x08010004(已对齐,保持不变)


二、位运算拆解:(address + 3) & ~0x03

1. ~0x03 的含义

0x03 的二进制是 0000 0011

按位取反后 ~0x03 变为 1111 1100(即 0xFFFC)

作用:这是一个掩码,用于清除二进制数的最后两位(最低 2 位)

2. address + 3 的作用

加 3 的目的:将地址值向上偏移,确保后续取整的正确性

对于未对齐的地址(如 0x08010001),加 3 后会进入下一个 4 的倍数区间

对于已对齐的地址(如 0x08010004),加 3 后仍在下一个 4 的倍数区间的边界内

3. & ~0x03 的作用

通过与 1111 1100 按位与,清除地址的最低 2 位(即模 4 的余数部分)

清除后,地址必然是 4 的倍数


三、示例验证

示例 1:输入 0x08010001(未对齐)

加 3:0x08010001 + 3 = 0x08010004

按位与:0x08010004 & 0xFFFC = 0x08010004

二进制过程:

0x08010004 → 0000 1000 0000 0001 0000 0000 0000 0100

0xFFFC     → 1111 1111 1111 1100

-----------------------------------

结果      → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004

示例 2:输入 0x08010004(已对齐)

加 3:0x08010004 + 3 = 0x08010007

按位与:0x08010007 & 0xFFFC = 0x08010004

二进制过程:

0x08010007 → 0000 1000 0000 0001 0000 0000 0000 0111

0xFFFC     → 1111 1111 1111 1100

-----------------------------------

结果      → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004

示例 3:输入 0x08010003(边界值)

加 3:0x08010003 + 3 = 0x08010006

按位与:0x08010006 & 0xFFFC = 0x08010004

二进制过程:

0x08010006 → 0000 1000 0000 0001 0000 0000 0000 0110

0xFFFC     → 1111 1111 1111 1100

-----------------------------------

结果      → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004


四、数学原理

对于任意整数 x,向上取整到 n 的倍数可以表示为:


ceil(x / n) * n

位运算技巧:当 n 是 2 的幂(如 4、8、16)时,可以简化为:


(x + (n-1)) & ~(n-1)

推导过程:


n-1 的二进制形式是低位全 1(如 0x03 → 0000 0011)

~(n-1) 的二进制形式是低位全 0,高位全 1(如 0xFFFC → 1111 1100)

(x + (n-1)) 将值偏移到下一个区间

& ~(n-1) 清除低位,得到对齐结果


五、通用公式

对齐目标代码实现示例(输入→输出)
4 字节对齐(x + 3) & ~0x035 → 8, 8 → 8
8 字节对齐(x + 7) & ~0x0710 → 16, 16 → 16
16 字节对齐(x + 15) & ~0x0F20 → 32, 32 → 32


六、在 STM32 Flash 编程中的应用

当你需要在任意地址写入 32 位数据时,可先对齐地址:


uint32_t address = 0x08010001;  // 未对齐的地址

uint32_t aligned_addr = (address + 3) & ~0x03;  // 对齐到0x08010004


// 安全写入

FLASH_ProgramWord(aligned_addr, 0x12345678);


七、注意事项

仅适用于 2 的幂对齐:该技巧只对 n=2^k 有效(如 4、8、16)

数据类型匹配:32 位对齐适用于 FLASH_ProgramWord(),16 位对齐适用于 FLASH_ProgramHalfWord()

溢出风险:如果 address 接近 UINT32_MAX,加 3 可能导致溢出(实际应用中 Flash 地址远小于此值,通常安全)

掌握这种位运算对齐技巧,能帮助你高效处理 STM32 Flash 编程中的地址约束问题。


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章