网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 电子/半导体 > 控制/MCU >

【笔记】接收不定长串口数据的方式(附代码)

时间:2023-06-07 10:00

人气:

作者:admin

标签:

导读:在不定长串口数据接收方面,有多种方式可供选择。以下是几种常见的方法:1.基于帧头帧尾:通过在数据帧的开头和结尾添加特定的帧头和帧尾标识来确定数据的起始和结束。在接收端...


在不定长串口数据接收方面,有多种方式可供选择。以下是几种常见的方法:1. 基于帧头帧尾:通过在数据帧的开头和结尾添加特定的帧头和帧尾标识来确定数据的起始和结束。在接收端,通过检测帧头和帧尾来截取完整的数据帧。这种方法需要约定好帧头和帧尾的标识,并在接收端进行相应的处理。例如,可以使用特定的字符或字节序列作为帧头和帧尾标识。

#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) { // 完整的数据帧接收完成,进行处理 // rxBuffer 中保存了完整的数据帧 // 可以进行后续的数据解析和处理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}

2. 基于定长数据:如果数据包的长度是固定的,可以通过设定一个固定的字节数来接收数据。在达到指定的字节数后,即可认为接收到了完整的数据。这种方式适用于数据包长度固定且已知的情况。

#define DATA_LENGTH 10
uint8_t rxBuffer[DATA_LENGTH];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ if (huart->Instance == USART1) { // 完整的数据包接收完成,进行处理 // rxBuffer 中保存了完整的数据包 // 可以进行后续的数据解析和处理操作
HAL_UART_Receive_IT(&huart1, rxBuffer, DATA_LENGTH); }}

3. 基于超时机制:在串口接收时,可以设置一个超时时间,如果在规定的时间内没有接收到数据,即认为当前数据接收结束。通过不断检查接收状态和计时器,可以实现超时机制。这种方式适用于数据包长度不确定且无法使用帧头帧尾方式的情况。

#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) { // 接收超时,数据接收结束 // 进行数据处理操作 rxIndex = 0; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}

4. 基于特定字符:可以通过在数据中插入特定的字符来表示数据的开始和结束。接收端可以根据特定的字符来判断数据的起始和结束。例如,可以使用换行符('\n')或回车符('\r')作为数据的起始和结束标识。

#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) { // 完整的数据接收完成,进行处理 // rxBuffer 中保存了完整的数据 // 可以进行后续的数据解析和处理操作 frameStarted = 0; } else if (frameStarted) { rxBuffer[rxIndex++] = rxData; }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}

5. 基于计数:可以在接收端设置一个计数器,根据接收到的数据逐步增加计数器的值。当达到指定的计数值时,即认为接收到了完整的数据。这种方式适用于在接收到固定数量的数据后即认为数据接收完成的情况。

#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) { // 完整的数据接收完成,进行处理 // rxBuffer 中保存了完整的数据 // 可以进行后续的数据解析和处理操作 frameStarted = 0; } } else { // 如果接收到起始字符,则开始计数 if (rxData == START_CHAR) { frameStarted = 1; rxIndex = 0; } }
HAL_UART_Receive_IT(&huart1, &rxData, 1); }}

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信