江科大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;  //防止数据乱码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
科大STM32笔记是关于STM32单片机的学习笔记,其中涵盖了一些关于按键初始化和按键读取的代码示例。在这些代码中,通过引用中的Key_Init函数来对按键进行初始化,然后通过引用中的Key_GetNum函数来获取按键按下的键码值。代码中使用了STM32的GPIO模块来配置引脚的工作模式和读取引脚的电平状态。此外,引用中提到STM32内部集成了硬件收发电路,可以通过写入控制寄存器CR和数据寄存器DR来实现与外设的通信,并通过读取状态寄存器SR来了解外设电路的当前状态。这些寄存器的使用可以实现对外设的控制和监测,减轻CPU的负担。因此,科大STM32笔记主要是介绍了STM32单片机的相关知识和编程技巧。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [STM32学习笔记 -- I2C(科大)](https://blog.csdn.net/weixin_61244109/article/details/131002266)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [STM32科大学习笔记](https://blog.csdn.net/weixin_38647099/article/details/128337708)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值