You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 Flash编程:为何需将32位地址强转为16位存储16位数据?

STM32 Flash半字编程的地址类型转换原因

这里的类型转换和volatile修饰是完全必要的,核心原因和STM32 Flash硬件的编程规则、编译器优化逻辑直接相关:

  • 硬件访问宽度必须匹配
    代码里已经配置了FLASH_PSIZE_HALF_WORD,这个位告诉Flash控制器要执行16位(半字)的编程操作。此时必须用16位宽度的内存访问来触发编程——如果强制转成uint32_t*做32位写入,硬件会检测到访问宽度和配置的PSIZE不匹配,直接导致编程失败,甚至触发总线错误。

  • 防止意外破坏数据
    若用uint32_t*写入,你的16位Data会被自动扩展成32位(无符号的话高位补0),这会把当前地址的高16位也覆盖成0,直接破坏Flash中原本存储在该地址上半部分的数据。而uint16_t*的转换只会修改指定地址的16位,完全符合半字编程的需求。

  • volatile(__IO)禁止编译器优化
    __IO是STM32标准库定义的宏,本质就是volatile。Flash编程是硬件层面的操作,编译器如果发现这个写入操作后没有后续读取,可能会直接优化掉这条指令,导致Flash根本没被编程。volatile强制编译器每次都直接操作内存地址,确保写入指令被执行。

  • 地址对齐检查
    STM32的Flash半字编程要求地址是16位对齐的(地址最低位为0)。uint16_t*的类型转换会让编译器在编译阶段(如果开启对齐检查)就识别出非对齐地址的错误,而uint32_t*要求32位对齐,用它转换半字地址会触发硬件对齐异常。

附上参考代码:

static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_FLASH_ADDRESS(Address));
  
  /* If the previous operation is completed, proceed to program the new data */
  CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  FLASH->CR |= FLASH_PSIZE_HALF_WORD;
  FLASH->CR |= FLASH_CR_PG;

  *(__IO uint16_t*)Address = Data;
}

内容的提问来源于stack exchange,提问作者Paulson Raja L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:17:17