STM32 串口打印 NaN的原因分析!!!
/** *************************************************************************** * @name convertToDecimalString * @brief 将hex转成字符串。例如 0X61A8转成25.000 * @param input - 输入的数组 * * * @return 对应的字符串 ******************************************************************************* */ void convertToDecimalString(uint32_t input, char *output,uint16_t length) { char result[100]; sprintf(result, "%f", (float )input/length); // 将整数转换为字符串 strcpy(output, result); printf("output %s\r\n",output); }
上面的功能就是将整数数值根据小数点转出浮点型数,再转成字符串的子函数。
有时候会遇到 串口打印 nan,将原本的数值丢失的情况。
原因:程序中的浮点运算产生了 NaN (Not a Number)
Not a Number:Not a Number (NaN) 是一个用于表示数学上未定义或无法表示的结果的特殊浮点值。它通常在执行某些操作时产生,例如零除零、不合法的数学操作等。
常见的原因:
1.非法浮点运算:例如 0.0 / 0.0、sqrt(-1) 或其他未定义行为。
float result = 0.0 / 0.0; // 结果是 NaN printf(":=%f\n", result); // 打印 :=nan
2.未初始化的浮点变量:果浮点变量未初始化,可能会包含随机值,导致意外的浮点运算问题
float uninitialized; printf(":=%f\n", uninitialized); // 未初始化变量可能会输出 NaN
3.内存损坏:如果程序中有指针错误或数组越界,可能会覆盖浮点变量的内容,使其变成 NaN
4.错误的类型转换:非浮点数被错误地解释为浮点数,可能会产生 NaN。
uint32_t int_value = 0xFFFFFFFF; // 最大无符号整数 float float_value = *(float*)&int_value; // 强制类型转换 printf(":=%f\n", float_value); // 可能会输出 NaN
具体原因:
通过keil调试没有发现问题:使用printf大法,来标记打印定位
本该执行一次的函数,不知道为啥执行两次,第二次执行时所给的参数发生变化,导致在浮点计算时分母为0.

找了很多地方,都没发现是延时函数的问题:偶然发现有些case语句就没有NaN情况,有些就有。经过对比,发现不添加延时函数就会发生。

是使用裸机跑系统,三个串口函数都在运行,估计是哪里发生冲突。裸机跑稍微复杂的东西很容易卡死或者出问题 。需要加标志位或者延时给程序足够的运行资源才行。
最好还是上操作系统比较保险
2024年12月10日:
最终的问题找到了:串口中断优先级设计不对,最忙碌的串口我设置成优先级最高,一直在抢占资源,导致另外两个串口没能按预计的情况接收数据!!!!!修改好三个串口优先级后,所有问题都解决了@@@@
浙公网安备 33010602011771号