我正在$0,S1,B2,Kffffffffffff,T61*34使用此代碼通過 UART接收此幀。
//Receive Data
for(uint8_t i = 0; i < size; i ){
receivedFrame[i] = EUSART1_Read();
if(receivedFrame[i] == '*'){
size = i 3;
}
}
幀的開始總是$和結束總是*在后面的兩個位元組保存前一個位元組的校驗和(ex 34)。
幀長度不固定,但它的最小長度為 26(從$到*) 2 個位元組的校驗和,最大長度為 62 以及 2 個位元組的校驗和。
但這不是最好的使用方法,因為很多情況可能會導致這種情況不穩定,例如如果*沒有到達,這將使我閱讀的每一幀都是錯誤的。
我搜索了通過 UART 接收資料的更好方法,但沒有找到任何東西。我正在尋找更好的方法來處理這樣的接收幀。
uj5u.com熱心網友回復:
該解決方案基于沒有尾隨 CR 或 LF 的假設,但在這種情況下,它也可以通過跳過 CR 和 LF 直到$找到它來作業。
我建議將您的演算法與$將位置重置為 0 并將$位置存盤在 0 處的檢查結合起來。這將忽略不包含*在預期位置的幀。
您可能應該size在進入回圈之前初始化為最大值,并確保size在*接收太晚的情況下不會增加。
另外,'$'如果這不是真的,我會確保第一個字符是而不是增加索引。
對于索引的這種有條件的遞增,while回圈更適合。
未經測驗的提議:
unsigned char receivedFrame[64];
uint8_t size = sizeof(receivedFrame);
uint8_t i = 0;
while(i < size)
{
unsigned char ch = EUSART1_Read();
if(ch == '$')
{
// in case i was > 0, ignore wrong frame, start from beginning
i = 0;
}
else if(receivedFrame[i] == '*'){
uint8_t new_size = i 3;
if(new_size < size)
{
size = new_size;
}
}
receivedFrame[i] = ch;
// stay at the first position if the character is not '$'
if((i > 0) || (ch == '$'))
{
i ;
}
}
附加提示:要在 PC 上測驗演算法,您可以替換EUSART1_Read為fgetc或getchar。請注意,這些函式回傳一個int值,EOF在將其轉換為unsigned char.
uj5u.com熱心網友回復:
如果您對特殊的資料包標記感興趣,那么尋找它們:等到開始 ($),然后記錄并計數所有內容,直到結束 (*),然后再讀取兩個字符。
在記錄和計數時,檢查空間以防止溢位。根據您預期的錯誤數量,按照@Bodo 的建議,在收到“*”時重置計數可能是一個不錯的主意。
有沒有辦法知道 EUSART1_Read() 是否真的找到了一個字符?或者它永遠等待(危險)?最好不要等待太多,并且知道有更多字符要讀取。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/378666.html
上一篇:有沒有辦法從C字串中提取注釋?
下一篇:帶有if條件的意外輸出
