关于可变帧长度数据的解析

关于可变帧长度数据的解析
在项目中需要解析另一主机的数据,而该主机数据是由积木式拼搭而成的可变的数据帧格式,每个积木所包含的数据长度不定,但是都小于10;
这里说明一下我在实际应用中的解决方法:
首先是和另一主机定义好数据帧格式协议,定义格式如下表:

帧头命令字帧长度参数校验和
0x5AInstructionLengthParameter1, Parameter2,Parameter3…….Check Sum

帧头: 收到0x5A表示有数据到达;
命令字:每个命令字代表本帧数据的含义;
帧长度:表示本条帧数据的长度,Length = 参数长度;
参数: 除了命令字外,补充其他更详细的信息,这里包括可变的积木数据;
校验和:Check Sum = Instruction + Length + Parameter1 + Parameter2 + 。。。+ ParameterN
下表是命令字的相关说明:
命令字的相关说明

参数说明:由于每个模块参数都有所不同,所以数据帧中不同ID,相同位置代表的含义也不同,在这里做个总结
数据举例
数据解析
此表格不完全…

具体的C代码解析
串口中将数据转存,同时置一个标志位:

CTRL_FLAG.BLOCK_FIRST_ROW_RECEIVE_OK_FLAG = TRUE ;///数据接收并校验完成标志位
		CTRL_COUNT.BLOCK_CNT = UART_RX3_BUF[UART_RX3_BUF[2] + 2] ;///BB的个数
		for(i=0;i<UART_RX3_CNT;i++)
		{
			UART_RX3_FIRST_ROW_DATA_BUF[i]=UART_RX3_BUF[i];///将接收的数据转存
		}

然后在程序中判断数据接收标志位是否进行解析,解析函数如下:

if (CTRL_FLAG.BLOCK_FIRST_ROW_RECEIVE_OK_FLAG == TRUE)///数据接收并校验完成标志位
{
	block_data_receive_finish_ack(0x03);///数据接收完成  后告知开始模块   0822	   ;
	for(i=0;i<CTRL_COUNT.BLOCK_CNT ;i++)///直到所有的数据都处理完成才退出
	{
		single_block_data_handle(i,UART_RX3_FIRST_ROW_DATA_BUF,block_sequence,1);///第1个BB,数据数组,数组起点(当前BB ID)
		BLOCK_SEQUENCE[i] = UART_RX3_FIRST_ROW_DATA_BUF[block_sequence];	///第1个BB的ID
		block_length_data = UART_RX3_FIRST_ROW_DATA_BUF[block_sequence-1];		///第1个BB 的数据长度
		block_sequence = block_sequence + block_length_data + 1;		///计算下一个BB的ID数组位置(将这个BB长度+5)  供下一次传参使用
	}

}

根据积木参数的数据进行解析,一个函数搞定:

/*
u8 sequence 			当前是第几个积木的数据
u8 *UART_RX3_FIRST_ROW_DATA_BUF	接收到的数据区,待处理
u8 number					当前处理的这个积木在数据区的开始
u8 row 						是哪一行的数据

*/
void single_block_data_handle(u8 sequence ,u8 *DATA_BUF , u8 number,u8 row)///处理当前单积木模块的数据
{
	u8 i = 0 ;
//	PARAMETER	*PARAMETER_DATA ;
	switch( DATA_BUF[number])///判断当前是那个模块
	{
//			case 1:///不存在1模块
//				break;
		case 2:				///模块2	---3参数
		case 5:				///模块5	---3参数
			for(i = 0 ; i< 3 ; i ++)
			{
				if(row ==1)
					BLOCK_DATA[sequence][i] =  DATA_BUF[number+i+1];//
				else if(row ==2)
					BLOCK_SECOND_DATA[sequence][i] =  DATA_BUF[number+i+1];///
				else if(row ==3)
					BLOCK_THIRD_DATA[sequence][i] =  DATA_BUF[number+i+1];///
			}
			break;
		case 3:				///模块3	---2参数
		case 4:				///模块4	---2参数
		case 7:				///模块7	---2参数
			for(i = 0 ; i< 2 ; i ++)
			{
				if(row ==1)
					BLOCK_DATA[sequence][i] =  DATA_BUF[number+i+1];///
				else if(row ==2)
					BLOCK_SECOND_DATA[sequence][i] =  DATA_BUF[number+i+1];///
				else if(row ==3)
					BLOCK_THIRD_DATA[sequence][i] =  DATA_BUF[number+i+1];///
			}
			break;
		case 6:				///模块6			---1参数
		case 8:				///模块8 左	---1参数
			if(row ==1)
				BLOCK_DATA[sequence][0] =  DATA_BUF[number+1];///
			else if(row ==2)
				BLOCK_SECOND_DATA[sequence][0] =  DATA_BUF[number+1];///
			else if(row ==3)
				BLOCK_THIRD_DATA[sequence][0] =  DATA_BUF[number+1];///
			break;
		case 9:				///模块9 右
			break;
		case 0x0B:				///舵机 抛球
			if(row ==1)
				BLOCK_DATA[sequence][0] =  DATA_BUF[number+1];///
			else if(row ==2)
				BLOCK_SECOND_DATA[sequence][0] =  DATA_BUF[number+1];///
			else if(row ==3)
				BLOCK_THIRD_DATA[sequence][0] =  DATA_BUF[number+1];///		
			break;
		
		default:
			break;			
	}
}

致此,积木的数据解析已经完成,
积木的数据存储在二位数组:BLOCK_DATA[][],
积木顺序存储在BLOCK_SEQUENCE[];
执行函数

/*
block_sequence	是第几个模块顺序
返回值:当前模块是否执行完成
*/
u8 block_data_deal(u8 block_sequence)///
{
	if((block_sequence!=last_block_sequence)&&(BLOCK_STATUS == 1))///数据回传,只回传一次  仅在是开始的时候执行
	{
		block_data_receive_finish_ack(0x02);
		last_block_sequence = block_sequence;
	}
	if (BLOCK_STATUS == 3) ///暂停
	{
		Pause_Stop();
	}
	else if(BLOCK_STATUS == 1)///开始  
	{
		switch (BLOCK_SEQUENCE[block_sequence])///判断是哪个积木模块ID
		{
			case 2:
				return (1);
			case 3:
				return (1);
			case 4:
				return (1);
			case 5:///模块
				return (1);
			case 6:///模块
				return (1);
			case 7:
				return (1);
			case 8:
				return (1);
			case 9:
				return (1);
			case 10:
				return (1);
			case 11:
				return (1);				
			default:
				break;
		}
	}
}

block_data_deal 负责执行数据中的命令,完成返回1,未完成返回0,用以顺序执行。
第一次写稿,只是想表述一种思想,不知道表述清楚与否,欢迎交流扣:50944-2881

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值