目录
stm32 串口通讯 和 USART学习 二(HEX和文本数据包收发)
一、HEX和文本数据包的收发
1)数据包格式
- 通常使用包头包尾来区分数据包
- 如何防止数据中出现包头包尾导致误判
- 对数据进行限幅,避免相同
- 固定数据包的长度
- 增加包头包尾长度,使其尽量为载荷数据无法出现的样子
- 要根据实际场景设计数据包,HEX计算方便,文本更易读
- Hex和文本数据包的格式
2)数据包收发逻辑
- 发送数据包容易,接受困难
- 使用 状态机+标志位 可以很好的实现收发逻辑
- Hex和文本数据包的收发逻辑
二、实验
1)串口收发HEX数据包
- 关键代码:
// 接收信息中断部分 void USART1_IRQHandler(void){ u8 i = 0; static u8 RxState = 0; if(USART_GetITStatus(USART1, USART_IT_RXNE)){ u8 RxData = USART_ReceiveData(USART1); if(RxState == 0){ if(RxData == 0xFF){ RxState = 1; } }else if(RxState == 1){ Serial_RxPacket[i++] = RxData; if(i == 4){ RxState = 2; i = 0; } }else if(RxState == 2){ if(RxData == 0xEF){ RxState = 0; RxFlag = 1; } } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }
2)串口收发文本数据包
- 关键代码:
// 主函数循环部分 while(1) { if(Serial_RxFlag == 1){ OLED_ShowString(4, 1, " "); OLED_ShowString(4, 1, Serial_RxPacket); if(strcmp(Serial_RxPacket, "LED_ON") == 0){ LED1_ON(); Serial_SendString("LED_ON_OK\r\n"); OLED_ShowString(2, 1, " "); OLED_ShowString(2, 1, "LED_ON_OK"); }else if(strcmp(Serial_RxPacket, "LED_OFF") == 0){ LED1_OFF(); Serial_SendString("LED_OFF_OK\r\n"); OLED_ShowString(2, 1, " "); OLED_ShowString(2, 1, "LED_OFF_OK"); }else{ Serial_SendString("ERROR_COMMAND\r\n"); OLED_ShowString(2, 1, " "); OLED_ShowString(2, 1, "ERROR_COMMAND"); } Serial_RxFlag = 0; } }