在不定長串口數(shù)據(jù)接收方面,有多種方式可供選擇。以下是幾種常見的方法:1. 基于幀頭幀尾:通過在數(shù)據(jù)幀的開頭和結尾添加特定的幀頭和幀尾標識來確定數(shù)據(jù)的起始和結束。在接收端,通過檢測幀頭和幀尾來截取完整的數(shù)據(jù)幀。這種方法需要約定好幀頭和幀尾的標識,并在接收端進行相應的處理。例如,可以使用特定的字符或字節(jié)序列作為幀頭和幀尾標識。
#define FRAME_HEAD 0xAA#define FRAME_TAIL 0x55
uint8_t rxBuffer[100];uint8_t rxIndex = 0;uint8_t frameStarted = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { if (rxData == FRAME_HEAD) { frameStarted = 1; rxIndex = 0; } else if (rxData == FRAME_TAIL && frameStarted) { // 完整的數(shù)據(jù)幀接收完成,進行處理 // rxBuffer 中保存了完整的數(shù)據(jù)幀 // 可以進行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
2. 基于定長數(shù)據(jù):如果數(shù)據(jù)包的長度是固定的,可以通過設定一個固定的字節(jié)數(shù)來接收數(shù)據(jù)。在達到指定的字節(jié)數(shù)后,即可認為接收到了完整的數(shù)據(jù)。這種方式適用于數(shù)據(jù)包長度固定且已知的情況。
#define DATA_LENGTH 10
uint8_t rxBuffer[DATA_LENGTH];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { // 完整的數(shù)據(jù)包接收完成,進行處理 // rxBuffer 中保存了完整的數(shù)據(jù)包 // 可以進行后續(xù)的數(shù)據(jù)解析和處理操作
HAL_UART_Receive_IT(&huart1, rxBuffer, DATA_LENGTH); }}
3. 基于超時機制:在串口接收時,可以設置一個超時時間,如果在規(guī)定的時間內沒有接收到數(shù)據(jù),即認為當前數(shù)據(jù)接收結束。通過不斷檢查接收狀態(tài)和計時器,可以實現(xiàn)超時機制。這種方式適用于數(shù)據(jù)包長度不確定且無法使用幀頭幀尾方式的情況。
#define TIMEOUT_MS 100
uint8_t rxBuffer[100];uint8_t rxIndex = 0;uint32_t startTime = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { if (rxIndex == 0) { startTime = HAL_GetTick(); }
rxBuffer[rxIndex++] = rxData;
if (rxIndex >= 2 && HAL_GetTick() - startTime >= TIMEOUT_MS) { // 接收超時,數(shù)據(jù)接收結束 // 進行數(shù)據(jù)處理操作 rxIndex = 0; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
4. 基于特定字符:可以通過在數(shù)據(jù)中插入特定的字符來表示數(shù)據(jù)的開始和結束。接收端可以根據(jù)特定的字符來判斷數(shù)據(jù)的起始和結束。例如,可以使用換行符('\n')或回車符('\r')作為數(shù)據(jù)的起始和結束標識。
#define START_CHAR '\n'#define END_CHAR '\r'
uint8_t rxBuffer[100];uint8_t rxIndex = 0;uint8_t frameStarted = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { if (rxData == START_CHAR) { frameStarted = 1; rxIndex = 0; } else if (rxData == END_CHAR && frameStarted) { // 完整的數(shù)據(jù)接收完成,進行處理 // rxBuffer 中保存了完整的數(shù)據(jù) // 可以進行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
5. 基于計數(shù):可以在接收端設置一個計數(shù)器,根據(jù)接收到的數(shù)據(jù)逐步增加計數(shù)器的值。當達到指定的計數(shù)值時,即認為接收到了完整的數(shù)據(jù)。這種方式適用于在接收到固定數(shù)量的數(shù)據(jù)后即認為數(shù)據(jù)接收完成的情況。
#define FRAME_LENGTH 10
uint8_t rxBuffer[FRAME_LENGTH];uint8_t rxIndex = 0;uint8_t frameStarted = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { if (frameStarted) { rxBuffer[rxIndex++] = rxData; if (rxIndex == FRAME_LENGTH) { // 完整的數(shù)據(jù)接收完成,進行處理 // rxBuffer 中保存了完整的數(shù)據(jù) // 可以進行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } } else { // 如果接收到起始字符,則開始計數(shù) if (rxData == START_CHAR) { frameStarted = 1; rxIndex = 0; } }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
-
數(shù)據(jù)
+關注
關注
8文章
7255瀏覽量
91817 -
串口
+關注
關注
15文章
1588瀏覽量
79906
發(fā)布評論請先 登錄
智嵌物聯(lián)串口轉光纖轉換器-延長串口通信距離,增強抗干擾性能

【RA-Eco-RA4M2開發(fā)板評測】使用RA4M2的串口實現(xiàn)任意任意類型任意長度的數(shù)據(jù)接收,并將接收到的數(shù)據(jù)顯示在串口助手上
【RA-Eco-RA4M2開發(fā)板評測】定時器輔助串口不定長數(shù)據(jù)接收
【RA-Eco-RA4M2開發(fā)板評測】+UART測試實驗
如何使用DMA進行USART不定長度接收

評論