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 NumberNot a Number (NaN) 是一个用于表示数学上未定义或无法表示的结果的特殊浮点值。它通常在执行某些操作时产生,例如零除零、不合法的数学操作等。

 

常见的原因:

1.非法浮点运算:例如 0.0 / 0.0sqrt(-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日:

最终的问题找到了:串口中断优先级设计不对,最忙碌的串口我设置成优先级最高,一直在抢占资源,导致另外两个串口没能按预计的情况接收数据!!!!!修改好三个串口优先级后,所有问题都解决了@@@@

 

posted on 2024-12-04 21:59  Aliang2020  阅读(528)  评论(0)    收藏  举报