加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 自行轉(zhuǎn)換字符串方式:
    • 修改RTT源碼方式:
    • 最后附上打印的結(jié)果
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

如何使用RTT進(jìn)行浮點(diǎn)數(shù)據(jù)的打印

09/11 10:15
1947
閱讀需 6 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

今天在調(diào)試一個(gè)射頻通信的時(shí)候,需要測(cè)試一下SNR,這個(gè)參數(shù)是一個(gè)float類型的數(shù)據(jù),開始沒注意,直接使用RTT進(jìn)行LOG 打印。

教你如何使用SEGGER RTT優(yōu)雅的實(shí)現(xiàn)日志系統(tǒng)

void OnSlave(void){  uint8_t i = 0;  if (rf_get_recv_flag() == RADIO_FLAG_RXDONE)  {    rf_set_recv_flag(RADIO_FLAG_IDLE);    Rssi_dBm = RxDoneParams.Rssi; // RSSI 的測(cè)量范圍是-60 到-140    Snr_value = RxDoneParams.Snr; // snr float類型    for (i = 0; i < RxDoneParams.Size; i++)    {      rx_test_buf[i] = RxDoneParams.Payload[i];    }    LOG("rf_rssi:%dn",Rssi_dBm);    LOG("rf_snr: %fn", Snr_value);    rf_enter_single_timeout_rx(15000); //重新進(jìn)入接收模式    LedToggle();                       // LED閃  }    }

打印出來的結(jié)果令人匪夷所思

rssi數(shù)據(jù)可以正常輸出,但是snr打印出來是空的,就是浮點(diǎn)類型轉(zhuǎn)換有問題,也不至于輸出空的,起碼是一個(gè)亂的數(shù)才對(duì)。于是跟進(jìn)了RTT的源代碼,進(jìn)一步發(fā)現(xiàn),原來RTT的打印處理函數(shù)中沒有處理%f的邏輯。

接下來,如果我們想要打印這個(gè)浮點(diǎn)數(shù)據(jù)的話,就需要自己稍加處理,思考了一下,應(yīng)該可以用兩種方法來實(shí)現(xiàn)。第一, 自己先將float類型轉(zhuǎn)換成字符串,然后通過RTT進(jìn)行字符串打印。第二,直接修改RTT源代碼,增加對(duì)浮點(diǎn)數(shù)據(jù)的打印支持。我對(duì)比了一下這兩種方式的代碼量,最終還是決定修改RTT的源代碼來兼容打印浮點(diǎn)數(shù)據(jù)的功能。以下是對(duì)比細(xì)節(jié),對(duì)比過程中不改變其他代碼,只涉及浮點(diǎn)打印部分。

自行轉(zhuǎn)換字符串方式:

    Rssi_dBm = RxDoneParams.Rssi; // RSSI 的測(cè)量范圍是-60 到-140    Snr_value = RxDoneParams.Snr;    for (i = 0; i < RxDoneParams.Size; i++)    {      rx_test_buf[i] = RxDoneParams.Payload[i];    }    LOG("rf_rssi:%dn",Rssi_dBm);
    sprintf(buffer, "%.2f", Snr_value);  // 手動(dòng)將float轉(zhuǎn)換為字符串    LOG("rf_snr: %sn", buffer);

以上代碼通過sprintf來進(jìn)行浮點(diǎn)到字符串的轉(zhuǎn)換,這里會(huì)用到C的微庫,編譯后的代碼大小如下:

 

修改RTT源碼方式:

修改代碼部分內(nèi)容:

case 'f':{    float fv = (float)va_arg(*pParamList, double);    // 取出輸入的浮點(diǎn)數(shù)值    if(fv < 0) _StoreChar(&BufferDesc, '-');          // 判斷正負(fù)號(hào)    v = abs((int)fv);                                 // 取正整數(shù)部分    _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);  //顯示整數(shù)    _StoreChar(&BufferDesc, '.');                                        //顯示小數(shù)點(diǎn)    v = abs((int)(fv * 100));                   v = v % 100;    _PrintInt(&BufferDesc, v, 10u, 2, FieldWidth, FormatFlags);  //顯示小數(shù)點(diǎn)后兩位    break;}

打印輸出部分就可以直接按照%f進(jìn)行輸出了。

Rssi_dBm = RxDoneParams.Rssi; // RSSI 的測(cè)量范圍是-60 到-140Snr_value = RxDoneParams.Snr;for (i = 0; i < RxDoneParams.Size; i++){  rx_test_buf[i] = RxDoneParams.Payload[i];}LOG("rf_rssi:%dn",Rssi_dBm);LOG("rf_snr: %fn", Snr_value);

這樣就可以正常的輸出結(jié)果,編譯的代碼大小如下圖

對(duì)比代碼大小可以看出,直接修改RTT源代碼的方案生成的代碼更小,因此,我更新了自己常用的RTT工具包,以后使用就方便了。

最后附上打印的結(jié)果

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

多年硬件從業(yè)經(jīng)驗(yàn),專注分享從研發(fā)到供應(yīng)鏈,再到精益制造過程中的經(jīng)驗(yàn)和感悟!