在不定長串口數(shù)據(jù)接收方面,有多種方式可供選擇。以下是幾種常見的方法:1. 基于幀頭幀尾:通過在數(shù)據(jù)幀的開頭和結(jié)尾添加特定的幀頭和幀尾標識來確定數(shù)據(jù)的起始和結(jié)束。在接收端,通過檢測幀頭和幀尾來截取完整的數(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ī)定的時間內(nèi)沒有接收到數(shù)據(jù),即認為當前數(shù)據(jù)接收結(jié)束。通過不斷檢查接收狀態(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ù)接收結(jié)束 // 進行數(shù)據(jù)處理操作 rxIndex = 0; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
4. 基于特定字符:可以通過在數(shù)據(jù)中插入特定的字符來表示數(shù)據(jù)的開始和結(jié)束。接收端可以根據(jù)特定的字符來判斷數(shù)據(jù)的起始和結(jié)束。例如,可以使用換行符('\n')或回車符('\r')作為數(shù)據(jù)的起始和結(jié)束標識。
#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文章
7349瀏覽量
95055 -
串口
+關注
關注
15文章
1627瀏覽量
83398
發(fā)布評論請先 登錄
單片機中的串口通訊串行同步通信與串行異步通信
請問CW32L的UART是不是沒有空閑中斷?
串口空閑中斷與串口超時中斷介紹
rt-thread 在使用串口DMA模式的時候,接收數(shù)據(jù)接收不到00,為什么?
串口DMA接收數(shù)據(jù)包丟失怎么解決?
串口通信有哪些方式
串口接收的bufferSize由1024變更為3072后數(shù)據(jù)接收出錯,為什么?
求助,關于串口設備驅(qū)動fifo問題
【RA4M2-SENSOR】—— 13.串口實現(xiàn)循環(huán)隊列
【RA4M2-SENSOR】—— 12.串口接收不定長度數(shù)據(jù)
CYT2B7串口接收會漏接數(shù)據(jù)怎么解決?
STM32407使用串口閑時中斷+DMA方式接收最大接收字節(jié)是多少?
智嵌物聯(lián)串口轉(zhuǎn)光纖轉(zhuǎn)換器-延長串口通信距離,增強抗干擾性能
【筆記】接收不定長串口數(shù)據(jù)的方式(附代碼)
評論