uart——串口数据帧处理

这篇具有很好参考价值的文章主要介绍了uart——串口数据帧处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在串口上,我们经常要对传过来的数据进行处理与解析。

最经典的就是处理数据帧,数据帧是什么呢?数据帧在我看来就是一连串的数据单元。数据帧定义了一些基本的协议。例如,数据帧一般会定义出帧头、帧尾、校验位、数据位、数据长度、命令字节(CMD)命令。

串口是进行处理串口数据帧的方式:一般我们通过对数据帧的处理判断接受到的数据是否符合协议上的要求,解析到数据帧的格式符合要求则执行我们要执行的操作,否则丢弃这一帧的数据包,等待下一次的数据传输过来。

那么,要怎么判断接受的数据帧是正确的格式呢,我认为可以通过一个字节一个字节轮番接受,并且每个字节的判断。即当帧头接受到时,判断帧头的格式,当帧头正确时就再次接受下一个字节,当接受到的字节判断错误时则丢弃数据包。这就是使用了一个简单的状态机思想去对数据进行解析。

环境:hal库处理数据帧

状态机

那么什么才是状态机呢?在我认为状态机就是一种具有多个状态事件的一种模型。

就拿一个简单的例子来说,在学习单片机时按键是最常见的一种外设。
按键有按下和弹起两种状态,事件上有长按和短按或者其他的一些事件。
在状态机上当我们没有按下按键的时候按键是不是就处于一种弹起状态,反之,当我们按下按键的时候状态是不是就从弹起切换到按下状态。状态是互斥的不可能同时触发。事件也是和状态一样的想法。

在本文中就拿一种简单的状态机思想去处理数据帧。

数据解析代码分析

在本文中处理的数据帧格式为:帧头 + 数据长度 + CMD + 头校验 + 数据位 + 数据校验 + 帧尾的方式进行处理数据帧。

处理数据帧方式:

  • 定义一个枚举类型定义状态机的每一种状态
  • 定义一个结构体存放接受到的数据帧
  • 定义一个数组进行存放接受到的数据帧
  • 定义一个数组下标进行每一位的数据帧的切换读取
  • 通过状态机对接受到每一位的数据帧进行解析

1、状态机的状态

这里定义的状态机的状态就是对每一个字节的判断。即:帧头、帧尾、数据长度等等的状态进行判断。

typedef enum
{
	HEAD_CHECK1,
	HEAD_CHECK2,
	DATA_LENGTH1,
	DATA_LENGTH2,
	CMD1,
	CMD2,
	HEAD_CHECKSUM,
	DATA,
	DATA_CHECKSUM,
	FOOT_CHECK1,
	FOOT_CHECK2,
	FRAME_ERROR,
} parse_state_t;

2、结构体定义存放的数据帧

这里定义了一个结构体就是为了和接收到的数据帧进行判断,无论我们接受到的是什么数据,都将其存入到对应的结构体成员当中。然后对接受到的字节进行判断,当存放的结构体成员和接收到的数据是完全对应上的时候说明接受到的是正确的数据,则进行下一个数据的判断,反之,丢弃所有的数据,对结构体的所有结构体成员进行清空。

typedef struct
{
	uint16_t header; // 帧头
	uint16_t length; // 数据长度
	uint16_t cmd;	 // 命令字
	uint8_t check1;	 // 头校验
	uint8_t *data;	 // 数据指针
	uint8_t check2;	 // 数据校验
	uint16_t footer; // 帧尾
} Data_Frame;

3、定义了一个数组进行存放数据帧

这里就是简单的代码上的hal库对代码的接受处理了,就不多啰嗦了,不明白的可以看看官方的uart的demo例程。

HAL_UART_Receive_IT(&UART_Config, &RX_buf[rx_pos], 1);

4、状态机解析数据

这里就来到重头戏了,对数据帧的解析,解析上我们在串口的中断回调函数上进行处理。即对每一个字节进行判断处理。代码如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	uint8_t byta = RX_buf[rx_pos++];
	// static uint8_t rx_state = 0;
	static uint8_t CON = 0;

	switch (parse_state)
	{
	case HEAD_CHECK1:
		if (byta == 0xAA)
		{
			LOG_I("head1");
			parse_state = HEAD_CHECK2;
		}
		else
		{
			parse_state = FRAME_ERROR;
			LOG_I("head1 erroc");
		}
		break;
	case HEAD_CHECK2:
		if (byta == 0x55)
		{
			recv_frame.header = 0xAA55;
			parse_state = DATA_LENGTH1;
			LOG_I("head2");
		}
		else
		{
			parse_state = FRAME_ERROR;
			LOG_I("head2 erroc");
		}
		break;
	case FRAME_ERROR:
	{
		recv_frame.check1 = 0;
		recv_frame.check2 = 0;
		recv_frame.cmd = 0;
		recv_frame.data = NULL;
		recv_frame.footer = 0;
		recv_frame.header = 0;
		recv_frame.length = 0;
		parse_state = HEAD_CHECK1;
		rx_pos = 0;
		HAL_UART_Transmit(&UART_Config, "error\r\n", 7, 1000);
		// RX_buf[BUF_SIZE] = {0};
	}
	break;
	default:
		break;
	}

	HAL_UART_Receive_IT(&UART_Config, &RX_buf[rx_pos], 1);
}

这里就简单的对帧头的处理和接收到错误的数据帧的处理方式。后面就根据自己的数据帧格式进行改动就行了。文章来源地址https://www.toymoban.com/news/detail-510164.html

到了这里,关于uart——串口数据帧处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何监听/抓取两个设备/芯片之间“UART串口”通信数据--监视TXD和RXD

    案例背景:全网仅此一篇!!! 两个 设备/芯片 之间采用 UART串口 通信。 我们如何实现 芯片1 TXD – 芯片2 RXD , 芯片2 TXD --  芯片1 RXD 两个单线链路上的数据抓取和监听? 这篇博客将告诉您。 目录 1 什么是UART串口 2 如何抓取和监听UART串口链路上的数据/信息 2.1 准备工作

    2024年02月08日
    浏览(35)
  • matlab发送串口数据,并进行串口数据头的添加,我们来看下pwm解析后并通过串口输出的效果

    uintt16位的话会在上面前面加上00,16位的话一定是两个字节,一共16位的数据 如果是unint8的话就不会, 注意这里给的是13,但是现实的00 0D,这是大小端的问题,在matlanb里设置,我们就默认用这个模式吧,没关系的,小端,小段的小数据在前,所以是00 0D。 下图是串口输出P

    2024年02月20日
    浏览(41)
  • Java使用Stream API对于数据列表经常处理

    先提供一些简单到复杂的常见例子,您可以根据这些例子进行进一步的开发和学习: 查询表中所有数据: 根据条件查询单个结果: 根据条件查询多个结果,并取前几条: 对查询结果进行排序: 过滤符合条件的结果: 对查询结果进行分页: 对查询结果进行统计: 对查询结

    2024年02月13日
    浏览(41)
  • STM32 串口接收不定长数据 HAL_UART_Receive_IT (帧头帧尾)

    最近使用sw4stm32调试串口时发现串口接收不定长数据很不方便,这里是帧头帧尾的接收方式,欢迎大佬指导。 这里要用串口中断接收的数据帧帧头为0xEB,帧尾为0XBE 这里是其中定义的变量  主函数里打开串口接收中断 然后串口接收处理部分全都写在的回调函数中。

    2024年01月19日
    浏览(44)
  • 异步串口和同步串口(USART和UART)

    串口是一种常见的用于数据传输的接口。在串行通信中,数据位逐个发送或接收。同步串口和异步串口是两种不同的数据传输方式。 同步串口和异步串口的区别在于同步串口需要某种时钟信号来同步数据传输,而异步串口不需要时钟信号。具体来说: 同步串口是在传输时使

    2024年02月12日
    浏览(36)
  • UART串口通讯乱码分析

    1:串口通讯乱码最主要的原因就是波特率不对,乱码的话请先检查波特率是否正确; 2:波特率正确的条件下,请检查设备两端电压是否稳定,电压不稳也会导致乱码; 3:当我们无法确认串口波特率的时候,可以参考下面的方式进行排查 大部分的通讯设备中间都是要经过电

    2024年02月09日
    浏览(32)
  • UART串口通信协议

    串行通信分为两种方式: 同步串行通信 和 异步串行通信 。 同步串行通信需要通信双方在同一时钟的控制下,同步传输数据。 异步串行通信是指通信双方使用各自的时钟控制数据的发送和接收过程。 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART)是一种 全双

    2024年02月03日
    浏览(36)
  • UART 串口通信

    第18.1讲 UART串口通信原理讲解_哔哩哔哩_bilibili 并行通信 一个周期同时发送8bit的数据,占用引脚资源多 串行通信 串行通信的通信方式: 同步通信 同一时钟下进行数据传输 异步通信 发送设备和接收设备的时钟不同 但是 需要约束波特率 (1s内传输的bit数) 串行通信的传输方

    2024年02月02日
    浏览(42)
  • 串口通信(UART)

    串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。 51单片机

    2024年02月07日
    浏览(42)
  • UART串口通信

    串口是“串行接口”的简称,即采用串行通信方式的接口。串行通信将数据字节分成一位一位的形式在一条数据线上逐个传送,其特点是通信线路简单,但传输速度较慢。因此串口广泛应用于嵌入式、工业控制等领域中对数据传输速度要求不高的场合。 Serial communication是一个

    2024年02月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包