STM32 串列埠列印 NaN的原因分析!!!

Aliang2020發表於2024-12-04
 /** 
 ***************************************************************************
 * @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情況,有些就有。經過對比,發現不新增延時函式就會發生。

是使用裸機跑系統,三個串列埠函式都在執行,估計是哪裡發生衝突。裸機跑稍微複雜的東西很容易卡死或者出問題 。需要加標誌位或者延時給程式足夠的執行資源才行。

最好還是上作業系統比較保險

相關文章