今天在調(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閃
}
}
打印出來(lái)的結(jié)果令人匪夷所思
rssi數(shù)據(jù)可以正常輸出,但是snr打印出來(lái)是空的,就是浮點(diǎn)類型轉(zhuǎn)換有問(wèn)題,也不至于輸出空的,起碼是一個(gè)亂的數(shù)才對(duì)。于是跟進(jìn)了RTT的源代碼,進(jìn)一步發(fā)現(xiàn),原來(lái)RTT的打印處理函數(shù)中沒有處理%f的邏輯。
接下來(lái),如果我們想要打印這個(gè)浮點(diǎn)數(shù)據(jù)的話,就需要自己稍加處理,思考了一下,應(yīng)該可以用兩種方法來(lái)實(shí)現(xiàn)。第一, 自己先將float類型轉(zhuǎn)換成字符串,然后通過(guò)RTT進(jìn)行字符串打印。第二,直接修改RTT源代碼,增加對(duì)浮點(diǎn)數(shù)據(jù)的打印支持。我對(duì)比了一下這兩種方式的代碼量,最終還是決定修改RTT的源代碼來(lái)兼容打印浮點(diǎn)數(shù)據(jù)的功能。以下是對(duì)比細(xì)節(jié),對(duì)比過(guò)程中不改變其他代碼,只涉及浮點(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);
以上代碼通過(guò)sprintf來(lái)進(jìn)行浮點(diǎn)到字符串的轉(zhuǎn)換,這里會(huì)用到C的微庫(kù),編譯后的代碼大小如下:
修改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 到-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);
LOG("rf_snr: %fn", Snr_value);
這樣就可以正常的輸出結(jié)果,編譯的代碼大小如下圖
對(duì)比代碼大小可以看出,直接修改RTT源代碼的方案生成的代碼更小,因此,我更新了自己常用的RTT工具包,以后使用就方便了。