版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、精选优质文档-倾情为你奉上串口接收不定长度数据及数据粘包解析的实现1、 如何让串口接收不定长度数据想让Stm32 串口接收不定长度数据,这就需要我们开启串口空闲中断(IDLE)方式,所谓串口空闲中断指的是stm32的数据总线在接收数据的过程中,如果总线在接收一个字节所需要的时间内没有再接收到数据,单片机就会判定此时数据已经接收完成了,这时单片机会自动触发空闲中断IDLE标志位,引发空闲中断,我们只需要进入中断取数据就可以了。使用IDLE空闲中断我们就可以用串口接收任意长度的数据了。2、 串口接收不定长度数据的实现思路我们实现串口接收不定长度数据的思路是:首先我们要定义一个接收数据的缓冲区,一般
2、用数组接收数据,在串口初始化时要开启串口的空闲中断和接收中断。然后在有中断产生时,我们需要在串口中断函数里判断是空闲中断还是正常接收一个字节数据引起的接收中断,如果是正常接收字节的中断,那么我们需要把接收到的这个字节数据存放到缓冲数组中,如果是IDLE空闲中断,表示串口数据已经接收完成了,我们需要在IDEL中断处理函数中设置一个数据接收完成标志位表示已经完整的接收到一帧数据了,如:RecFlag=1;3、 数据粘包解析的实现思路数据粘包是多个数据包发送时由于线路延时,或者发送端发送多个数据包的时间延时很小,导致几个数据包几乎同时到达接收端(数据包到达接收端的时间间隔小于一个字节时间),这样单片
3、机接收数据时就会将这几个数据包当做一帧数据来接收存放。那么我们如何将这几个数据包合成的一帧数据拆解成几个数据包呢?其实,实现的方法也很简单,这就需要我们在发送端和接收端的数据格式上做一个统一的约定,约定了统一的数据发送格式在发送数据时就严格按照这个格式来发送。一般来说约定的格式我们要明确规定数据头和数据长度。然后我们再根据定义的数据头是什么数据,在这一帧数据中逐个去判断当前数据是不是数据头,如果是就说明这个是一个小数据包的开始位置,在根据数据长度就可以解析出一个数据包了。例如,我们约定发送的数据格式为:数据头(2byte)+发送者ID(1byte)+接收者ID(1byte)+ 命令码(1byt
4、e)+ 数据长度(1byte)+CRC校验(2byte)。这样我们定义了标准的数据格式就容易拆包了。4、 下面我们就根据约定的数据发送格式来定义具体的数据头,例如我们定义一个数据包命令来查询接收命令的单片机PH值传感器1的数据是多少。数据包定义如下:数据头:0xAA55发送者ID:0x01接收者ID:0x02命令码:0x01 /查询PH值传感器1命令 随意约定命令代码 0x02 /响应PH查询命令 0x03 /设置传感器PH值上限命令 0x10 /设置成功数据长度:xx CRC校验:0xB1B5 / CRC 16 Modbus那么发送端发送的查询数据为:aa 55 01 02 01 00 b5
5、 b1 接收查询命令响应的数据发送格式也要按照约定的数据格式发送出去:响应数据为:aa 55 02 01 02 02 00 07 12 91 如此约定了数据格式,如果真的发生粘包的情况,解析数据也很方便了,我们只需要找到数据头的标志0xAA55,然后读取该数据包代表数据长度的字节存放的存储位置,就可以得到数据长度,比如数据包:aa 55 02 01 02 02 00 07 12 91数据长度的位置就在AA这个字节之后的第五个字节,假设此时AA字节在缓冲数组的位置为RecBufi,那么长度字节存放的位置就是RecBufi+5,取出RecBufi+5中的数据为2,说明该字节之后有2个字节的数据,再
6、加上CRC的2个字节,我们就需要在RecBufi+5之后还要取出4个字节的数据,才能完整的取出这个小数据包:aa 55 02 01 02 02 00 07 12 91需要注意的是我们再拆包的过程中要重复考虑其中存在的问题,比如:数据长度错误时的数量,找不到数据头时循环变量的修正等。5、 基于cubemx HAL库的实现方法(1) 新建cubemx工程 选择stm32f103ze芯片(2) 开启外部高速时钟HSE,配置好系统时钟树(3) 配置串口1 ,启用DMA传输,使能中断DMA 接收配置成循环模式,数据位宽默认为8位DMA 发送配置成正常模式,数据位宽默认为8位(4)设置好工程名称和保存位置
7、,选择自己用的开发工具和版本,然后生成工程代码就可以开始编写我们自己的代码了。6、 我们先看结果首先,我们先测试单个命令发送(没有粘包)命令1: 查询PH指令 aa 55 01 02 01 00 b5 b1 收到查询指令后,进行解析然后执行查询命令,向主机返回PH数据【返回数据】:aa 55 02 01 02 02 00 07 12 91 / 返回PH值等于7命令2:设置PH值上限指令 aa 55 01 02 03 02 00 0b 57 5b /设置PH上限为 11 【返回数据】:aa 55 02 01 10 00 49 a5 / 返回设置成功指令 0x10接下来,我们测试一下数据粘包的情况
8、我们把之前的2个命令合在一起发送出去,红色数据用来模拟有干扰的情况下,数据出错了。a2 55 aa 55 01 02 01 00 b5 b1 32 15 8e 20 aa 55 01 02 03 02 00 0b 57 5b 68 21结果如下:在串口收到这一帧数据后,调用拆包函数进行数据解析,按照数据头逐个进行比较只要找到正确的数据头,就按照约定的数据长度去取数据,取到一个小包数据后进行CRC校验,校验正确后才执行命令。第一个小包执行完成后接着去取下一个包,然后执行,直到把接收到的数据解析并执行完成。中断接收方式:采用中断方式,只需要在宏定义 #define UsartDMA 0/1 配置成
9、0 就可以了,数据处理结果跟用DMA方式一样,这里不再贴图。7、 代码实现(1) 编写myusart.h 文件在myusart.h 文件中我们主要定义串口数据接收的结构体类型#ifndef _MYUSART_H_#define _MYUSART_H_#include "main.h"#include "usart.h"#include "string.h"#include "stdio.h"#define UsartBufSize 512#define UsartDMA 1 / 是否启用串口DMA 1启用 0停止
10、typedef struct uint8_t *ReadPtr; /读书节指针uint8_t RecFlag; /接收标志uint8_t ProFinsh; /数据处理完成标志uint8_t RecBufUsartBufSize; /数据缓冲区uint16_t InAllLen; /缓冲区存放数据长度uint16_t CFraLen; /当前帧长度 最近接受的帧长度uint16_t ReadNBytes; /需要读取的字节数UART_HandleTypeDef *huart; /串口号 NetDat_TypeDef;void NetDateRec(NetDat_TypeDef *NetDat)
11、;void My_Usart_Init(UART_HandleTypeDef *huart,NetDat_TypeDef *NetDat);#endif(2) 编写myusart.c文件#include "myusart.h"#include "netdatpro.h"uint16_t temp,lastTemp=0;extern UART_HandleTypeDef huart1;extern DMA_HandleTypeDef hdma_usart1_rx;extern DMA_HandleTypeDef hdma_usart1_tx;NetDat_
12、TypeDef Usart1_NetDate;/重定向c库函数printf到USARTxstruct _FILE /标准库需要的支持函数 int handle; ;int fputc(int ch, FILE *f)while(huart1.Instance->SR&0X40)=0);/循环发送,直到发送完毕 huart1.Instance->DR = (uint8_t)ch ;return (ch);/网络数据接收函数void NetDateRec(NetDat_TypeDef *NetDat)#if UsartDMA = Enable /static uint16_t
13、temp=0,lastTemp=0;if(_HAL_UART_GET_FLAG(NetDat->huart,UART_FLAG_IDLE)/检测是否有IDE中断 NetDat->RecFlag = 1;/接受完成标志位置1/HAL_UART_DMAStop(NetDat->huart);/停止DMA接收,每次来新数据时都会从缓存起始地址开始存放lastTemp=temp;temp = hdma_usart1_rx.Instance->CNDTR;/获取DMA中未传输的数据个数,NDTR寄存器分析见下面if(lastTemp=0&&temp=sizeof(
14、NetDat->RecBuf)|lastTemp=temp)/lastTemp=temp 前2次都是一次接满缓冲区NetDat->CFraLen=sizeof (NetDat->RecBuf);else if(lastTemp=0)/首次进入NetDat->CFraLen=sizeof (NetDat->RecBuf) - temp;/计算当前接收的帧长度elseNetDat->CFraLen=lastTemp - temp;/计算当前接收的帧长度if(NetDat->CFraLen>sizeof (NetDat->RecBuf)/数据从缓
15、冲区溢出NetDat->CFraLen=lastTemp+sizeof (NetDat->RecBuf)-temp;/有溢出了 修正接收到的字节数if(temp!=sizeof (NetDat->RecBuf)/缓存没满 满的时候temp等于缓冲区大小NetDat->InAllLen =sizeof (NetDat->RecBuf) - temp;/总计数减去未传输的数据个数,得到已经接收的数据个数elseNetDat->InAllLen =sizeof (NetDat->RecBuf);/缓存刚好满时修正总数为缓存大小NetDat->ReadN
16、Bytes=NetDat->InAllLen;/计算需要读取的字节数if(NetDat->InAllLen < NetDat->CFraLen)/接收总长度小于当前帧长度时 缓冲区溢出NetDat->ReadNBytes=NetDat->InAllLen + sizeof (NetDat->RecBuf);/修正要需要读取的字节数HAL_UART_Receive_DMA(NetDat->huart,NetDat->RecBuf,sizeof(NetDat->RecBuf);/开启DMA接收NetDat->ProFinsh=0;_
17、HAL_UART_CLEAR_IDLEFLAG(NetDat->huart);/清除标志位#else uint8_t temp=0;static unsigned int num; /接收计数static uint8_t RecTimes=0; /查询是否发生了空闲中断if(_HAL_UART_GET_FLAG(NetDat->huart,UART_FLAG_IDLE)!=RESET&&_HAL_UART_GET_IT_SOURCE(NetDat->huart,UART_IT_IDLE)!=RESET)NetDat->CFraLen = num; /发生
18、空闲中断,将数据长度写入到结构体NetDat->ReadNBytes = num; /发生空闲中断,将数据长度写入到结构体num=0;RecTimes=0;NetDat->RecFlag = 1;NetDat->ProFinsh=0;/待处理 _HAL_UART_CLEAR_IDLEFLAG(NetDat->huart);/清除空闲中断else if(_HAL_UART_GET_IT_SOURCE(NetDat->huart,UART_IT_RXNE)!=RESET)/帧传输未完成,按字节接收 #ifdef STM32F0_HAL_UART_CLEAR_IT(my
19、uart->huart,UART_IT_RXNE); if(RecTimes=0 && myuart->recFlag=1)/如果上一帧数据未处理,新数据加在前一帧末尾num = myuart ->RecLen;RecTimes+;if(num <= UsartBufSize )/缓冲区未满myuart->UsartRxBufnum+=(uint8_t)(myuart->huart->Instance->RDR); /F0为RDR elsetemp=(uint8_t)(myuart->huart->Instance-&
20、gt;RDR);#elseif(RecTimes=0 && NetDat->ProFinsh=0)/如果上一帧数据未处理完成,新数据加在前一帧末尾num = NetDat->CFraLen;/RecTimes+;if(num < sizeof (NetDat->RecBuf) )/缓冲区未满NetDat->RecBufnum+=(uint8_t)(NetDat->huart->Instance->DR); /F0为RD else if(num=sizeof (NetDat->RecBuf)/循环存放num=0;NetDat-
21、>RecBufnum+=(uint8_t)(NetDat->huart->Instance->DR); #endif_HAL_UART_CLEAR_FLAG(NetDat->huart,UART_FLAG_RXNE);#endif/串口和接收指针初始化void My_Usart_Init(UART_HandleTypeDef *huart,NetDat_TypeDef *NetDat)NetDat->huart=huart;NetDat->ReadPtr=NetDat->RecBuf;/读数据指针赋值#if UsartDMA = EnableHA
22、L_UART_Receive_DMA(huart,NetDat->RecBuf,sizeof(NetDat->RecBuf);/打开DMA接收,数据存入Usart1_NetDate.RecBuf数组中。#else_HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); /使能接收中断#endif_HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);/使能空闲中断(3) 编写netdatpro.h文件#ifndef _NETDATPRO_H#define _NETDATPRO_H#include "
23、;crc16.h"#include "myusart.h"#include "stdlib.h"#include "string.h"#define MasterID 0x01#define SlaverID 0x02#define DateHead 0xaa55#define Head1 0xaa#define Head2 0x55#define FrameMinByte 8 /定义最小帧字节数 当数据位为空时 基本帧长度为最小帧字节数#define Max_Mess_LEN 100#ifndef Enable #defi
24、ne Enable 1#endif#ifndef Disable #define Disable 0#endif#define debug 1#define DebugPrint if(debug)printftypedef struct unsigned char Head2;unsigned char SendDevID;unsigned char RecDevID;unsigned char Cmd;unsigned char len;unsigned char dataMax_Mess_LEN;NetPackge_Type;unsigned char NetDataUnpack(voi
25、d *SavePackge ,NetDat_TypeDef *recdata);void NET_Data_Process(NetDat_TypeDef *netDat);void NET_Data_Package(uint8_t *sendData,uint8_t len);#endif(4) 编写netdatpro.c文件#include "netdatpro.h"#include "stdio.h"#include "usart.h"#define RptrAddr (uint32_t)recdata->ReadPtrNe
26、tPackge_Type NET_data;extern uint8_t DebugFlag;extern NetDat_TypeDef Usart1_NetDate;NetPackge_Type SendDat=0;uint8_t DevID=0x02;/* * 参数: cmd 传入指令 datlen 数据长度,不是帧长度而是数据长度标识字节 跟随多少个字节数据 *date 数据指针 * 描述: 将传入数据按照协议封装命令码并计算CRC * 返回值: 无 */void NetDatePack(unsigned char cmd,unsigned char datlen,unsigned ch
27、ar *date)unsigned int CRC_Value=0; SendDat.Head0=Head1;SendDat.Head1=Head2;SendDat.SendDevID=DevID;if(DevID=MasterID)/主机发送数据时SendDat.RecDevID=SlaverID;else/从机发送数据时SendDat.RecDevID=MasterID;SendDat.Cmd=cmd;SendDat.len=datlen;memcpy(&SendDat.data,date,datlen);CRC_Value = CRC16_Calculate(uint8_t*)&
28、amp;SendDat,datlen+6);/6 是计算CRC前的最小数据包基本组成的字节数(数据字节为 空,即没有数据字节)/DebugPrint("CRC_Value=%4xn",CRC_Value);SendDat.datadatlen = CRC_Value>>8;SendDat.datadatlen+1 = CRC_Value;/* * 函数名: NetDataUnpack(void *SavePackge ,NetDat_TypeDef *recdata) * 参数: *SavePackge 解析后接收保存变量 *recdata 待解析数据 * 描述
29、: 按照协议头将串口接收的数据进行拆包解析,解析后数据由*SavePackge 接收保存 * 返回值: packgenum 0 数据包解析完成 n 已经解析的数据包个数数据协议格式:协议头(2byte)+ 发送设备ID(1byte)+接收设备ID(1byte)+ 信息码(1byte)+数据长度(1 byte)+数据(n byte)+校验码(2byte) */unsigned char NetDataUnpack(void *SavePackge ,NetDat_TypeDef *recdata)/拆分数据包,粘包处理unsigned char *p=SavePackge,*pa=SavePac
30、kge,*ptr;unsigned int i=0,DatHead=0;/static unsigned char packgenum=0;uint32_t bufBaseAddr=(uint32_t)recdata->RecBuf,HeadAddr=0;if(recdata->RecFlag=1 &&recdata->ProFinsh=0)/收到新数据printf("开始解析第【%d】包数据.n",packgenum);DatHead=(*recdata->ReadPtr+)<<8;/取数据头0xaa 字节移到高位 He
31、adAddr=RptrAddr;for(i=0;i<recdata->ReadNBytes-(HeadAddr-bufBaseAddr);i+)/RptrAddr-bufBaseAddr 之前已经读取的个数 printf("数据头:%04xn",DatHead+*recdata->ReadPtr);if(DateHead=(DatHead+*recdata->ReadPtr)ptr=recdata->ReadPtr-1;/记录找到数据头时的指针起点DebugPrint("【数据头正确】n");break;elseDatHea
32、d=(*recdata->ReadPtr+)<<8;if(RptrAddr-bufBaseAddr>=sizeof (recdata->RecBuf)/指针溢出recdata->ReadPtr=recdata->RecBuf;/修正指针位置到数组首位recdata->ReadNBytes-=sizeof (recdata->RecBuf);/修正循环控制变量if(DateHead=(DatHead+*recdata->ReadPtr)/0xaa55packgenum+;if(*(ptr+5)>Max_Mess_LEN)/*(pt
33、r+5)是存放数据长度的位置DebugPrint ("信息长度大于 %d ,已超出约定范围!n",Max_Mess_LEN);recdata->ReadPtr+;/读指针增加 到此处读指针已经指向0x55 这个字节,退出函数后再次拆包时直接取下一个数进行判断数据头,因此读指针要 +1if(RptrAddr-bufBaseAddr>=sizeof (recdata->RecBuf)/指针溢出recdata->ReadPtr=recdata->RecBuf;/修正指针位置到数组首位recdata->ReadNBytes-=sizeof (re
34、cdata->RecBuf);/修正读字节数return packgenum;for(i=0;i<*(ptr+5)+FrameMinByte;i+) /接收一个数据包(小包) readbyte+5 数据长度在0xaa字节后 偏移 5if(i=0)*p+ = *(recdata->ReadPtr-1);/0xaaelse*p+ = *recdata->ReadPtr+;if(RptrAddr-bufBaseAddr>=sizeof (recdata->RecBuf)/指针溢出recdata->ReadPtr=recdata->RecBuf;/修正指
35、针位置到数组首位recdata->ReadNBytes-=sizeof (recdata->RecBuf);/修正读字节数p=SavePackge;DebugPrint(" n ");DebugPrint("【数据】:");for(i=0;i<*(pa+5)+FrameMinByte;i+)DebugPrint("%02x ",*p+);DebugPrint(" n ");if(RptrAddr-bufBaseAddr>recdata->ReadNBytes)/丢包了recdata-&
36、gt;ReadPtr=&recdata->RecBufrecdata->ReadNBytes;/修正指针位置到实际接收位置,并指向下一个待存数据内存单元if(RptrAddr-bufBaseAddr = recdata->ReadNBytes)/读完数据了printf ("n");printf ("【拆包完成.】n");printf ("n");recdata->ProFinsh=1;packgenum=0;#if UsartDMA = Disable recdata->ReadPtr=recda
37、ta->RecBuf;/读指针归位#endifreturn packgenum;return 0;void NET_Data_Process(NetDat_TypeDef *netDat) /网络数据处理extern uint16_t temp,lastTemp,lastLen;uint16_t i=0,pack;uint8_t cmd,Date5,*p,a="test transmit IT"if(Usart1_NetDate.RecFlag=1)while(Usart1_NetDate.ProFinsh=0)/还没拆完数据NetDataUnpack(&NE
38、T_data,netDat);/拆包if(CRC16_Checkout(uint8_t*)&NET_data, NET_data.len+FrameMinByte)=CRC_OK)/校验正确printf ("【CRC校验正确.】n");cmd=NET_data.Cmd;switch(cmd)case 0x01:printf ("收到查询PH传感器1命令.n");printf ("向主机发送传感器1 PH值.n");Date0=0x00;Date1=0x07;NetDatePack(0x02,0x02,Date);/#if Us
39、artDMA = Disable/HAL_UART_Transmit(&huart1,(uint8_t*)&SendDat,SendDat.len+FrameMinByte,1000);/#else/HAL_UART_Transmit_DMA(&huart1,(uint8_t*)&SendDat,SendDat.len+FrameMinByte);/#endifprintf ("【返回数据】:");p=(uint8_t*)&SendDat;for(i=0;i<SendDat.len+FrameMinByte;i+)printf
40、("%02x ",*p+);printf ("n");break;case 0x03:printf ("n");printf ("收到设置传感器1 PH上限命令.n");printf ("设置传感器1PH 上限.n");NetDatePack(0x10,0x00,Date);/#if UsartDMA = Disable/HAL_UART_Transmit(&huart1,(uint8_t*)&SendDat,SendDat.len+FrameMinByte,1000);/ #e
41、lse/HAL_UART_Transmit_DMA(&huart1,(uint8_t*)&SendDat,SendDat.len+FrameMinByte);/#endifprintf ("返回设置成功命令.n");printf ("【返回数据】:");p=(uint8_t*)&SendDat;for(i=0;i<SendDat.len+FrameMinByte;i+)printf ("%02x ",*p+);printf ("nn");break;default :break;mem
42、set (&NET_data,0,sizeof (NET_data);#if UsartDMA = Enableprintf("n");printf("lastTemp=%dn",lastTemp);printf("temp=%dn",temp);printf("len=%dn",Usart1_NetDate.CFraLen);printf("alllen=%dn",Usart1_NetDate.InAllLen);#endifUsart1_NetDate.RecFlag=0;(5) 编
43、写crc16.h#ifndef _CRC16_H_#define _CRC16_H_/#include "sys_config.h"#include "main.h"/#define CRC16_LOW_BETY_AHEAD#define CRC_OK 0#define CRC_FAIL -1unsigned int CRC16_Calculate(unsigned char *pDate, unsigned int len );int CRC16_Checkout(unsigned char *pDate, unsigned char len);voi
44、d CRC16_Pack(unsigned char *pDate, unsigned int *len);#endif(6) 编写crc16.c/crc16高字节在前驱动 #include "crc16.h"/* 8位CRC校验表 */ const unsigned char CRC16_HighByteTable256= 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00
45、,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x
46、81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40
47、,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0x
48、c0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81
49、,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 , 0x00 ,0xc1 ,0x81 ,0x40 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x01 ,0xc0 ,0x80 ,0x41 ,0x00 ,0xc1 ,0x81 ,0x40 , ;/*低8位CRC校验表*/const unsigned char CRC16_LowByteTable 256= 0x00 ,0xc0 ,0xc1
50、 ,0x01 ,0xc3 ,0x03 ,0x02 ,0xc2 ,0xc6 ,0x06 ,0x07 ,0xc7 ,0x05 ,0xc5 ,0xc4 ,0x04 , 0xcc ,0x0c ,0x0d ,0xcd ,0x0f ,0xcf ,0xce ,0x0e ,0x0a ,0xca ,0xcb ,0x0b ,0xc9 ,0x09 ,0x08 ,0xc8 , 0xd8 ,0x18 ,0x19 ,0xd9 ,0x1b ,0xdb ,0xda ,0x1a ,0x1e ,0xde ,0xdf ,0x1f ,0xdd ,0x1d ,0x1c ,0xdc , 0x14 ,0xd4 ,0xd5 ,0x15 ,0
51、xd7 ,0x17 ,0x16 ,0xd6 ,0xd2 ,0x12 ,0x13 ,0xd3 ,0x11 ,0xd1 ,0xd0 ,0x10 , 0xf0 ,0x30 ,0x31 ,0xf1 ,0x33 ,0xf3 ,0xf2 ,0x32 ,0x36 ,0xf6 ,0xf7 ,0x37 ,0xf5 ,0x35 ,0x34 ,0xf4 , 0x3c ,0xfc ,0xfd ,0x3d ,0xff ,0x3f ,0x3e ,0xfe ,0xfa ,0x3a ,0x3b ,0xfb ,0x39 ,0xf9 ,0xf8 ,0x38 , 0x28 ,0xe8 ,0xe9 ,0x29 ,0xeb ,0x2b
52、 ,0x2a ,0xea ,0xee ,0x2e ,0x2f ,0xef ,0x2d ,0xed ,0xec ,0x2c , 0xe4 ,0x24 ,0x25 ,0xe5 ,0x27 ,0xe7 ,0xe6 ,0x26 ,0x22 ,0xe2 ,0xe3 ,0x23 ,0xe1 ,0x21 ,0x20 ,0xe0 , 0xa0 ,0x60 ,0x61 ,0xa1 ,0x63 ,0xa3 ,0xa2 ,0x62 ,0x66 ,0xa6 ,0xa7 ,0x67 ,0xa5 ,0x65 ,0x64 ,0xa4 , 0x6c ,0xac ,0xad ,0x6d ,0xaf ,0x6f ,0x6e ,0
53、xae ,0xaa ,0x6a ,0x6b ,0xab ,0x69 ,0xa9 ,0xa8 ,0x68 , 0x78 ,0xb8 ,0xb9 ,0x79 ,0xbb ,0x7b ,0x7a ,0xba ,0xbe ,0x7e ,0x7f ,0xbf ,0x7d ,0xbd ,0xbc ,0x7c , 0xb4 ,0x74 ,0x75 ,0xb5 ,0x77 ,0xb7 ,0xb6 ,0x76 ,0x72 ,0xb2 ,0xb3 ,0x73 ,0xb1 ,0x71 ,0x70 ,0xb0 , 0x50 ,0x90 ,0x91 ,0x51 ,0x93 ,0x53 ,0x52 ,0x92 ,0x96 ,0x56 ,0x57 ,0x97 ,0x55 ,0x95 ,0x94 ,0x54 , 0x9c ,0x5c ,0x5d ,0x9d ,0x5f ,0x9f ,0x9e ,0x5e ,0x5a ,0x9a ,0x9b ,0x5b ,0x99 ,0x59 ,0x58 ,0x98 , 0x88 ,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 甘肃省天水市2027年高三3月份第一次模拟考试物理试卷(含答案解析)
- 2027届广西壮族自治区河池市高三冲刺模拟物理试卷(含答案解析)
- 厂区消防安全安全生产总结
- 季度安全生产标准化提质总结
- 跨境智算中心电算协同中跨国算力绿电联合调度跨境替代争议-基于国际替代争议解决机制算力绿电调度跨境调解与替代裁决规范分析
- 跨境算力中心与钢渣热闷余热协同中跨国热闷蒸汽波动算力-基于国际钢渣热闷余热协会算力中心蒸汽发电调度指南规范分析
- 户外出行夏季防暑安全常识
- 夏季熟食卤味夏季食用安全提醒
- 聚焦杭州理论知识试题及其答案
- 颈椎病的护理问题及措施
- 2026中国物流仓储行业现状调研与发展趋势分析报告
- 2026浙江金华市义乌市机关事业单位编外聘用人员招聘66人考试备考试题及答案详解
- 2025年党员发展理论考试题库及答案
- 四川天华化工集团股份有限公司招聘笔试题库2026
- 2026江西抚州市市属国有企业招聘员工72名模拟试卷及1套完整答案详解
- 2025湖北恩施州巴东弘发产业发展集团有限公司招聘工作人员及笔试事宜笔试历年参考题库附带答案详解
- 2026安徽黄山供元财税管理咨询有限公司招聘3人考试备考试题及答案详解
- DB32∕T4117-2021保温装饰板外墙外保温系统技术规程-无水印
- 控制工程-课件
- 逆转:舆情危机的预防与处置
- 主播艺人入职面试信息登记表
评论
0/150
提交评论