STM32 串口收发数据包

devtools/2025/2/7 14:56:48/

接线图

HEX数据包接收

文本数据包接收

代码配置

发送HEX数据包

//存储发送或接收的载荷数据
uint8_t TX_Packet[4];
uint8_t RX_Packet[4];void Serial_SendPacket(void)
{Serial_SendByte(0xFF);//发送包头Serial_SendArray(TX_Packet, 4);//发送4个载荷数据Serial_SendByte(0xFE);//发送包尾}

主函数

#include "USART.h"
int main(void)
{OLED_Init();USART_Config();TX_Packet[0] = 0x01;TX_Packet[1] = 0x02;TX_Packet[2] = 0x03;TX_Packet[3] = 0x04;Serial_SendPacket();while(1){}}

接收HEX数据包

需要在中断函数里写

//存储发送或接收的载荷数据
uint8_t TX_Packet[4];
uint8_t RX_Packet[4];//中断函数
void USART1_IRQHandler(void)
{static uint8_t RX_State = 0;static uint8_t pRX_Packet = 0;//判断中断标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET){RX_Data = USART_ReceiveData(USART1);//读取数据寄存器,并存放在数据变量里if(RX_State == 0){//如果接收到了包头if(RX_Data == 0xFF){RX_State = 1;pRX_Packet = 0;}}else if(RX_State == 1){RX_Packet[pRX_Packet] = RX_Data;//将RX_Data存在接收数组里pRX_Packet++;if(pRX_Packet >= 4){RX_State = 2;}}else if(RX_State == 2){//判断是不是包尾if(RX_Data == 0xFE){RX_State = 0;RX_Flag = 1;//标志位置1}}//清除标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}}

主函数

#include "USART.h"
int main(void)
{OLED_Init();USART_Config();TX_Packet[0] = 0x01;TX_Packet[1] = 0x02;TX_Packet[2] = 0x03;TX_Packet[3] = 0x04;Serial_SendPacket();while(1){if(Serial_GetRXFlag() == 1){OLED_ShowHexNum(1, 1, RX_Packet[0], 2);OLED_ShowHexNum(1, 4, RX_Packet[1], 2);OLED_ShowHexNum(1, 7, RX_Packet[2], 2);OLED_ShowHexNum(1, 10,RX_Packet[3], 2);}}}

按键控制

int main(void)
{KEY_Init();OLED_Init();USART_Config();TX_Packet[0] = 0x01;TX_Packet[1] = 0x02;TX_Packet[2] = 0x03;TX_Packet[3] = 0x04;OLED_ShowString(1, 1, "TXPacket");OLED_ShowString(3, 1, "RXPacket");while(1){if(KEY_Scanf(GPIOB, GPIO_Pin_0) == 1){TX_Packet[0]++;TX_Packet[1]++;TX_Packet[2]++;TX_Packet[3]++;Serial_SendPacket();OLED_ShowHexNum(2, 1, TX_Packet[0], 2);OLED_ShowHexNum(2, 4, TX_Packet[1], 2);OLED_ShowHexNum(2, 7, TX_Packet[2], 2);OLED_ShowHexNum(2, 10,TX_Packet[3], 2);}if(Serial_GetRXFlag() == 1){OLED_ShowHexNum(4, 1, RX_Packet[0], 2);OLED_ShowHexNum(4, 4, RX_Packet[1], 2);OLED_ShowHexNum(4, 7, RX_Packet[2], 2);OLED_ShowHexNum(4, 10,RX_Packet[3], 2);}}

发送与接收文本数据包

char RX_Packet2[100];//中断函数
void USART1_IRQHandler(void)
{static uint8_t RX_State = 0;static uint8_t pRX_Packet = 0;//判断中断标志位if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET){RX_Data = USART_ReceiveData(USART1);//读取数据寄存器,并存放在数据变量里if(RX_State == 0){//如果接收到了包头if(RX_Data == '@' && RX_Flag == 0){RX_State = 1;pRX_Packet = 0;}}else if(RX_State == 1){//判断是不是第一个包尾if(RX_Data == '\r'){RX_State = 2;}else{RX_Packet2[pRX_Packet] = RX_Data;//将RX_Data存在接收数组里pRX_Packet++;}}else if(RX_State == 2){//判断是不是第二个包尾if(RX_Data == '\n'){RX_State = 0;RX_Packet2[pRX_Packet] = '\0';//加结束标志位RX_Flag = 1;//标志位置1}}//清除标志位USART_ClearITPendingBit(USART1, USART_IT_RXNE);}}

主函数:

int main(void)
{OLED_Init();LED_Init();USART_Config();OLED_ShowString(1, 1, "TXPacket");OLED_ShowString(3, 1, "RXPacket");while(1){if(RX_Flag == 1){OLED_ShowString(4, 1, "            ");OLED_ShowString(4, 1, RX_Packet2);if(strcmp(RX_Packet2, "LED_ON") == 0){LED2(0);Serial_SendString("LED_ON_OK\r\n");OLED_ShowString(2, 1, "           ");OLED_ShowString(2, 1, "LED_ON_OK");}else if(strcmp(RX_Packet2, "LED_OFF") == 0){LED2(1);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");}RX_Flag = 0;}}}


http://www.ppmy.cn/devtools/156844.html

相关文章

【归属地】批量号码归属地查询按城市高速的分流,基于WPF的解决方案

在现代商业活动中,企业为了提高营销效果和资源利用效率,需要针对不同地区的市场特点开展精准营销。通过批量号码归属地查询并按城市分流,可以为企业的营销决策提供有力支持。 短信营销:一家连锁餐饮企业计划开展促销活动&#xf…

rabbitMQ数据隔离

用户管理 点击Admin选项卡,就会呈现rabbitMQ控制台的用户管理界面 Name:sde,也就是用户名Tags:administrator,说明sde用户是超级管理员,拥有所有权限Can access virtual host: /,可…

Spring Boot常用注解深度解析:从入门到精通

今天,这篇文章带你将深入理解Spring Boot中30常用注解,通过代码示例和关系图,帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解: SpringBootApplication Confi…

Stable Diffusion的入门介绍和使用教程

Stable Diffusion是一个文本到图像的潜在扩散模型,由CompVis、StabilityAI和LAION的研究人员和工程师创建。它使用来自LAION-5B数据库子集的512x512图像进行训练。使用这个模型,可以生成包括人脸在内的任何图像,因为有开源的预训练模型&#…

基础项目实战——学生管理系统(c++)

目录 前言一、功能菜单界面二、类与结构体的实现三、录入学生信息四、删除学生信息五、更改学生信息六、查找学生信息七、统计学生人数八、保存学生信息九、读取学生信息十、打印所有学生信息十一、退出系统十二、文件拆分结语 前言 这一期我们来一起学习我们在大学做过的课程…

手写MVVM框架-实现简单v-bind

v-bind 有两种情况&#xff1a; 1.绑定的是一个简单的属性 <div :class"customClass">简单v-bind</div> 2.绑定的元素上面有表达式 <div :class"{customClass: a 1 > 2}">简单v-bind</div> 这一章我们先说第一种情况&…

Linux iostat 命令使用详解

简介 iostat 命令用于监控 Linux 系统输入/输出设备的加载情况。它提供有关CPU 统计信息以及设备和分区的输入/输出统计信息。通过显示 I/O 操作如何影响系统性能&#xff0c;它对于诊断性能瓶颈&#xff08;例如磁盘或网络活动缓慢&#xff09;特别有用。 安装 Debian/Ubun…

【前端】【面试】【复习详解】【react】react生命周期--函数式全解

在 React Hooks 引入之后&#xff0c;函数式组件可以使用 useEffect 等钩子来模拟类组件生命周期方法的功能。下面详细介绍如何用函数式组件实现类似类组件生命周期的效果。 挂载阶段 模拟 componentDidMount componentDidMount 在类组件中是在组件挂载到 DOM 之后立即调用&…