江科大STM32 串口收发数据包(笔记)

  • 一.串口收发HEX数据包

  • 1-1发送HEX数据包(固定包长)

 包头包尾和数据载荷重复的问题,传输的数据本身是FF和FE,可能引起误判
解决:限制载荷数据的范围,限幅(例如只发送0~100)
如果无法避免数据与包头包尾重复,则尽量使用固定长度的数据包
增加包头包尾的数量,尽量是其呈现出载荷数据出现不了的状态

extern uint8_t Serial_TxPacket[];  //声明外部可调用

uint8_t Serial_TxPacket[4];	

void Serial_SendPacket(void)
{
	Serial_SendByte(0xFF);
	Serial_SendArray(Serial_TxPacket, 4); //发送四个字节
	Serial_SendByte(0xFE);
}

主函数使用

 外部设备现象

 1-2接受HEX数据包

中断状态机流程图

uint8_t Serial_RxPacket[4];
uint8_t Serial_RxFlag;

void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0; //静态变量  只能在本函数使用 函数进入只会初始化一次 
	static uint8_t pRxPacket = 0; //记录接受的数量
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0) //等待包头
		{
			if (RxData == 0xFF)  //包头
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1) //接收数据
		{
			Serial_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= 4)  //接受四个载荷数据
			{
				RxState = 2;
			}
		}
		else if (RxState == 2) //等待包尾
		{
			if (RxData == 0xFE)  //包尾RXData==0xFE
			{
				RxState = 0;
				Serial_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

使用
 

	

        if (Serial_GetRxFlag() == 1)
		{
			OLED_ShowHexNum(4, 1, Serial_RxPacket[0], 2);
			OLED_ShowHexNum(4, 4, Serial_RxPacket[1], 2);
			OLED_ShowHexNum(4, 7, Serial_RxPacket[2], 2);
			OLED_ShowHexNum(4, 10, Serial_RxPacket[3], 2);
		}

使用现象:

二.串口接受文本数据包

2-1发送文本数据包

中断状态机流程图

 接受缓存区

char Serial_RxPacket[100];				//"@MSG\r\n" 接收缓存区
void USART1_IRQHandler(void)
{
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
		
		if (RxState == 0)
		{
			if (RxData == '@' && Serial_RxFlag == 0)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			if (RxData == '\r')
			{
				RxState = 2;
			}
			else  //接受数据
			{
				Serial_RxPacket[pRxPacket] = RxData; 
				pRxPacket ++;
			}
		}
		else if (RxState == 2)
		{
			if (RxData == '\n')
			{
				RxState = 0;
				Serial_RxPacket[pRxPacket] = '\0';  //添加结束标志位
				Serial_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

使用代码

现象 (发送区输入@ABC“换行”)

#include "string.h"



if (strcmp(Serial_RxPacket, "LED_ON") == 0)  //strcmp 判断字符串是否相等
			{
				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;  //防止数据乱码

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值