在嵌入式系統開發中,串口通訊是常見的數據傳輸方式。由於串口數據流的不確定性,如何判斷一幀數據是否接收完畢是關鍵問題。本文介紹一個基於超時機制的串口接收檢測函數 Rxdsuc_test(),該函數通過監測字符間隔時間來確定數據幀結束。
該函數採用「字符間超時」判斷策略:當接收到第一個字符後,啟動一個計時器(預設 10 個 5ms 週期,即 50ms)。若在計時歸零前持續收到新字符,計時器重置;若計時器歸零仍未收到新字符,則判定該幀數據接收完畢。
unsigned char Rxdsuc_test()
{
unsigned char noRxd_time = 10; // 等待 10*5ms 無新字符視為結束
if(newRxd_flag) // 檢測到新字符到達標志
{
while(noRxd_time)
{
if(noRxd_flag) // 當前 5ms 週期內無新字符
{
delay5ms(1);
if(noRxd_flag) noRxd_time--; // 連續兩次確認無數據才遞減
}
else // 週期內收到新字符
{
noRxd_time = 10; // 重置超時計數
noRxd_flag = 1; // 重新進入等待狀態
}
}
RxdPoint = 0; // 緩衝區指針歸零
newRxd_flag = 0; // 清除新數據標志
rxdsuc_flag = 1; // 設置接收成功標志
return 1; // 返回接收完成標志
}
return 0; // 暫無新數據
}
newRxd_flag:串口中斷服務程序中置 1,表示有新字符進入緩衝區。noRxd_flag:定時器中斷(5ms)中置 1,表示本週期無新字符;收到字符時由中斷清零。delay5ms(1):精確延時 5ms,配合定時器中斷實現週期檢測。此函數適用於定長或不定長、但字符間間隔固定的協議(如 Modbus RTU)。調用時機通常放在主循環或定時任務中。需注意:波特率越高,字符間隔越小,noRxd_time 初值需根據波特率和幀間隔調整;若通訊線路干擾大,可能導致誤判幀結束,建議結合校驗和幀頭幀尾特徵碼雙重保障。