在不定長串口數(shù)據(jù)接收方面,有多種方式可供選擇。以下是幾種常見的方法:1. 基于幀頭幀尾:通過在數(shù)據(jù)幀的開頭和結(jié)尾添加特定的幀頭和幀尾標(biāo)識(shí)來確定數(shù)據(jù)的起始和結(jié)束。在接收端,通過檢測幀頭和幀尾來截取完整的數(shù)據(jù)幀。這種方法需要約定好幀頭和幀尾的標(biāo)識(shí),并在接收端進(jìn)行相應(yīng)的處理。例如,可以使用特定的字符或字節(jié)序列作為幀頭和幀尾標(biāo)識(shí)。
#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ù)幀接收完成,進(jìn)行處理 // rxBuffer 中保存了完整的數(shù)據(jù)幀 // 可以進(jìn)行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
2. 基于定長數(shù)據(jù):如果數(shù)據(jù)包的長度是固定的,可以通過設(shè)定一個(gè)固定的字節(jié)數(shù)來接收數(shù)據(jù)。在達(dá)到指定的字節(jié)數(shù)后,即可認(rèn)為接收到了完整的數(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ù)包接收完成,進(jìn)行處理 // rxBuffer 中保存了完整的數(shù)據(jù)包 // 可以進(jìn)行后續(xù)的數(shù)據(jù)解析和處理操作
HAL_UART_Receive_IT(&huart1, rxBuffer, DATA_LENGTH); }}
3. 基于超時(shí)機(jī)制:在串口接收時(shí),可以設(shè)置一個(gè)超時(shí)時(shí)間,如果在規(guī)定的時(shí)間內(nèi)沒有接收到數(shù)據(jù),即認(rèn)為當(dāng)前數(shù)據(jù)接收結(jié)束。通過不斷檢查接收狀態(tài)和計(jì)時(shí)器,可以實(shí)現(xiàn)超時(shí)機(jī)制。這種方式適用于數(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í),數(shù)據(jù)接收結(jié)束 // 進(jìn)行數(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é)束標(biāo)識(shí)。
#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ù)接收完成,進(jìn)行處理 // rxBuffer 中保存了完整的數(shù)據(jù) // 可以進(jìn)行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
5. 基于計(jì)數(shù):可以在接收端設(shè)置一個(gè)計(jì)數(shù)器,根據(jù)接收到的數(shù)據(jù)逐步增加計(jì)數(shù)器的值。當(dāng)達(dá)到指定的計(jì)數(shù)值時(shí),即認(rèn)為接收到了完整的數(shù)據(jù)。這種方式適用于在接收到固定數(shù)量的數(shù)據(jù)后即認(rèn)為數(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ù)接收完成,進(jìn)行處理 // rxBuffer 中保存了完整的數(shù)據(jù) // 可以進(jìn)行后續(xù)的數(shù)據(jù)解析和處理操作 frameStarted = 0; } } else { // 如果接收到起始字符,則開始計(jì)數(shù) if (rxData == START_CHAR) { frameStarted = 1; rxIndex = 0; } }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
6715瀏覽量
88308 -
串口
+關(guān)注
關(guān)注
14文章
1533瀏覽量
75457
發(fā)布評論請先 登錄
相關(guān)推薦
評論