STM32 Flash对齐技巧详解
这行代码 uint32_t aligned_address = (address + 3) & ~0x03;
是一个经典的位运算技巧,用于将任意地址值向上取整为 4 的倍数。下面从原理到示例详细解释:
一、核心目标:向上对齐到 4 的倍数
0x08010001
→ 输出 0x08010004
0x08010004
→ 输出 0x08010004
(已对齐,保持不变)二、位运算拆解:(address + 3) & ~0x03
1. ~0x03
的含义
0x03
的二进制是 0000 0011
~0x03
变为 1111 1100
(即 0xFFFC
)2. address + 3
的作用
0x08010001
),加 3 后会进入下一个 4 的倍数区间0x08010004
),加 3 后仍在下一个 4 的倍数区间的边界内3. & ~0x03
的作用
1111 1100
按位与,清除地址的最低 2 位(即模 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) & ~0x03 |
5 → 8 , 8 → 8 |
8 字节对齐 | (x + 7) & ~0x07 |
10 → 16 , 16 → 16 |
16 字节对齐 | (x + 15) & ~0x0F |
20 → 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 编程中的地址约束问题。
作者:weixin_58038206