Flash擦除后数据为什么会变NaN
一句话: Flash 擦除后全是 0xFF当 float 读出来是 NaN。NaN 转整型行为未定义——可能是 0也可能是满量程。如果这个值直接写 DAC 控制电流或电压器件可能在几秒内烧毁。适合谁读用 Flash 存配置参数、模拟 EEPROM 的嵌入式开发者。0xFF 是怎么变成 NaN 的Flash 擦除后每位都是 1。四个字节连起来是0xFFFFFFFF。如果代码里把这块 Flash 当成float来读float fVal *(float*)flash_data; // 0xFFFFFFFF → NaNIEEE 754 标准里0xFFFFFFFF正好落在 NaN 的编码范围内。读出来不是 0不是很大的数是不存在的东西。NaN 的意思是 Not a Number——它确实不是任何数字。转整型的灾难如果接下来把 NaN 转成整型写 DACuint16_t dacCode (uint16_t)(fVal * SCALE); // NaN * anything ?NaN 参与的运算结果还是 NaN。NaN 强转整型的行为在 C 标准里是未定义的。ARMCC 可能给 0GCC 可能给一个很大的数同一编译器换优化等级结果都可能不一样。如果是 0——万幸DAC 输出 0安全。如果是满量程 4095——DAC 输出满量程电流器件可能几秒烧毁。测十次十次都是 0第十一次换个优化等级就炸。这不是 Bug是未定义行为。不止 FlashNaN 陷阱不限于 Flash。任何数据还没初始化就被读的场景都可能触发场景怎么产生 NaN后果Flash 擦除后未写0xFFFFFFFF → NaN随机 DAC 值结构体未初始化就读取栈上残留值随机配置参数通信超时没收到数据缓冲区旧值过期的命令参数传感器断线ADC 读到浮空值虚假的测量值本质上都是同一个问题把不确定的值当成有效值用了。怎么防1. Flash 预写安全默认值上板第一步往所有配置区写最小安全值。就算意外读取输出也在阈值以下。2. 读出来先判有效性float fVal ReadFlashFloat(addr); if (isnan(fVal) || isinf(fVal)) { fVal SAFE_DEFAULT; // 读坏了用默认值 }isnan()和isinf()是math.h标准函数一行的事。3. 任何从 Flash 读出的值先做范围检查if (dacCode MIN_VALID || dacCode MAX_VALID) { dacCode SAFE_DEFAULT; }三条规则五秒写完。比烧一颗器件便宜。有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。