欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOCX文档下载  

    stm32 HAL库 串口DMA接收不定长度数据及粘包处理.docx

    • 资源ID:4925130       资源大小:297.84KB        全文页数:23页
    • 资源格式: DOCX        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    stm32 HAL库 串口DMA接收不定长度数据及粘包处理.docx

    串口接收不定长度数据及数据粘包解析的实现1、如何让串口接收不定长度数据想让Stm32串口接收不定长度数据,这就需要我们开启串口空闲中断(IDLE) 方式,所谓串口空闲中断指的是stm32的数据总线在接收数据的过程中,如果总 线在接收一个字节所需要的时间内没有再接收到数据,单片机就会判定此时数据 已经接收完成了,这时单片机会自动触发空闲中断IDLE标志位,引发空闲中断, 我们只需要进入中断取数据就可以了。使用IDLE空闲中断我们就可以用串口接 收任意长度的数据了。2、串口接收不定长度数据的实现思路我们实现串口接收不定长度数据的思路是:首先我们要定义一个接收数据的 缓冲区,一般用数组接收数据,在串口初始化时要开启串口的空闲中断和接收中 断。然后在有中断产生时,我们需要在串口中断函数里判断是空闲中断还是正常 接收一个字节数据引起的接收中断,如果是正常接收字节的中断,那么我们需要 把接收到的这个字节数据存放到缓冲数组中,如果是IDLE空闲中断,表示串口 数据已经接收完成了,我们需要在IDEL中断处理函数中设置一个数据接收完成 标志位表示已经完整的接收到一帧数据了,如:RecFlag=1;3、数据粘包解析的实现思路数据粘包是多个数据包发送时由于线路延时,或者发送端发送多个数据包的 时间延时很小,导致几个数据包几乎同时到达接收端(数据包到达接收端的时间 间隔小于一个字节时间),这样单片机接收数据时就会将这几个数据包当做一帧 数据来接收存放。那么我们如何将这几个数据包合成的一帧数据拆解成几个数据 包呢?其实,实现的方法也很简单,这就需要我们在发送端和接收端的数据格式 上做一个统一的约定,约定了统一的数据发送格式在发送数据时就严格按照这个 格式来发送。一般来说约定的格式我们要明确规定数据头和数据长度。然后我们 再根据定义的数据头是什么数据,在这一帧数据中逐个去判断当前数据是不是数 据头,如果是就说明这个是一个小数据包的开始位置,在根据数据长度就可以解 析出一个数据包了。例如,我们约定发送的数据格式为:数据头(2byte)+发送 者 ID(1byte)+ 接收者 ID(1byte)+ 命令码(1byte)+ 数据长度(1byte)+CRC 校验(2byte)。这样我们定义了标准的数据格式就容易拆包了。4、下面我们就根据约定的数据发送格式来定义具体的数据头,例如我们定义一 个数据包命令来查询接收命令的单片机PH值传感器1的数据是多少。数据包定义如下:数据头:0XAA55发送者ID: 0x01接收者ID: 0x02命令码:0x01 查询PH值传感器1命令 随意约定命令代码0x02 /响应PH查询命令0x03 设置传感器PH值上限命令0x10 设置成功数据长度:xxCRC 校验:0xB1B5 / CRC 16 Modbus那么发送端发送的查询数据为:aa 55 01 02 01 00 b5 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个字节的数据,再加上CRC的2 个字节,我们就需要在RecBufi+5之后还要取出4个字节的数据,才能完整的取 出这个小数据包:aa 55 02 0102 02 00 07 12 91需要注意的是我们再拆包的过程中要重复考虑其中存在的问题,比如:数据长度错误时的数量,找不到数据头时循环变量的修正等。5、基于cubemx HAL库的实现方法(1)新建cubemx工程 选择stm32f103ze芯片(2)开启外部高速时钟HSE,配置好系统时钟树Pinout & ConfigurationClock ConfigurationAdditional Softwarev PinoutR.CC Mode an<i ConfigurationCategoriesA->ZModeSystem Core vMAGPIQIWDGWICV SYSWWDGHi-gh Speed CIoc:要aFCeamiResLaw Speed Clock (LSE) Disable Master Clock OutputHMbUHH LjIULB. IUUM>To I ADO i1«He|* -.(3)配置串口 1T?PLirFC;LH#»<i|S|-u»» C»«U HUjEVKl. :i*ci,启用DMA传输,使能中断ConnEciityCo nfigu rationCAN FSMC I2C1 2C2 SDIO SFII SPI2 SPI3 UART4 UARTT5DMA1 channel global interruptDMA1 channels global interrupt USART1 global inierruptNVIC Interupt Tsble | Qnab1 edPreemption PriontyResei Configuralian, 'IVIC Stting DMA Swings GPIO Siting# Paramatgr Sellings User Constants& US ART 1DMA接收配置成循环模式,数据位宽默认为8位USART1Cata WidthPeripheral To MemoryLowMemcry T& PeripheralLawDMA1 Channel 5DMA1 Channel 4Merruiy/DMARequest SettingsCircularPeripheralIncrement Address ConfiguralianRestt Configuialien MA RequestChannelDirectionPriorityDelete* Parameter Sett ngs * User Constants NVIC Settings DMA Settings GPIO SettingsDMA发送配置成正常模式,数据位宽默认为8位ModeDara WidthMemory-'Peripheral To MemoryLowMemory To PeripheralLowPeripheralIncrcTirt Address USART1 RX/DMA Request Sett bigsMA1 Charnel 5MAJ Charnel Parameter Settings User Constants NVIC Settings I DFvIA Actings GPIO SellingsDirecHonPriorityD slotsChannelDMA Request(4)设置好工程名称和保存位置,选择自己用的开发工具和版本,然后生成工程代码就可 以开始编写我们自己的代码了。Project SettingsProject NameProjectReceivie variable length dataProject LocationC:U § wp nt ylDw § ktopk u 台白 exLij sartApplication StructureBasicv Do nt>t generateToolchain Folder LocationCode GeneratorC:UserssentyDesktopkcubemxusartReceiwe variable length dataToolchain l 旧EMin VersionMD-K-ARM1 |V5二-STM32CuDe MCU packages and embedded saftware packsQ Dopy all used libraries into the project fiolderProjectCode Generator® Dop/ only the necegsar/ library filesO Add necessary library files as reference in the toolchain project configuration file-Generated filesQ Generate periphsral initialiization as a. pmi'.c/.h' ,jles par peripheralI I Backup prei/iously generated files when re-generatingQ Keep User Code when re-generating De ete previ&usly generated files v/hen not re-generated6、我们先看结果首先,我们先测试单个命令发送(没有粘包)命令 1:查询 PH 指令 aa 55 01 02 01 00 b5 bl收到查询指令后,进行解析然后执行查询命令,向主机返回PH数据【返回数据】:aa 55 02 010202 00 07 12 91 /返回PH值等于7lit:, SSCQM V5.13.1串口/网锁据调试器,作者:大虾T丁日S805BOq,一通映口串口设宣显示游寥字符串小王具蒂瓦联茎作者 PCB打样降至每款5元顺丰包邮可选杂色! t嘉立倒官网】【数据】: aa E5 U1 02 Ul 00 LE bl【折包其成 】日 矗02 -.一叮 F 5 1 土口 5 1- 1- nl.wiEra .a警机回CRT到柬912端口号 |CDMU USE-SEEIAL CH340 二蝶 关讶串口 |巧更妾串口设置I匚HE!显示 保存数据|厂搂收数据到文件|7 HE1发送 r加时间概和分包显示,做 ms第"宝节筐r RTS r DTR 波特:|1152OO Jg 55 01 02 01 00 b5 bl为了更好地发展昵匚伽软件止mi 请您注册嘉立削?结尾客户k一巫.里r升级到SSCDM5.13.1 *FCB打样降至每兼日兀,免颜色最,顺丰包邮!提供SMT贴片服务。的-丁也www.da3cia.co-m £:3R:22&|COW 11 BJJJT IISOOLpa.l.None,Mone青豚窗口I打开文件II发谖文件停止I青发送E命令2:设置PH值上限指令aa 55 01 02 03 02 00 0b 57 5b 设置PH上限为11【返回数据】:aa 55 02 011000 49 a5 /返回设置成功指令0x10惬SSCOM V5.13.1串口,网骚据调试器.作者;大虾T丁花190狷街,“- 通g 口串口设置显示发送矜字符串小工且拜助睬紊作者 PC日打样降至每款5元顺丰包邮可选杂色!嘉立创盲网】醪朝5.S&头正确】【数据】:徂 55 01 02 03 02 00 Ob 57 51)邙C校验正确. . .】盾感器1 FH上限命令据】:aa 55 0Z 011000 43aS有除窗口 打开文件岌谖文件但止青发送E端口号三更多串口设置|詹关闭串口 &r RTS r DTR波特本:11边。皿显示 保存数据I厂搔欧教据到文件I区四)( 加时间戳和分包显示-超时时间:叵aa 55 01 02 03 02 00 Ob 57 Shms为了更好地发展3SCCW件 请您注册嘉立创F站尾客户t升级到SSC0H5. 13. 1】丈匚上打样降至每款玩,免颜色噩,顺丰包揶!提供E贴片服务。*RT-Thiwuvw.daxia.GomS;10R;249COIM11 既开 nSOObpsAl.None.None接下来,我们测试一下数据粘包的情况我们把之前的2个命令合在一起发送出去,红色数据用来模拟有干扰的情况下,数据出错了。a2 55 aa 55 01 02 01 00 b5 bl 32 15 8e 20 aa 55 01 02 03 02 00 0b 57 5b 68 21结果如下:在串口收到这一帧数据后,调用拆包函数进行数据解析,按照数据头逐个进行比较只要 找到正确的数据头,就按照约定的数据长度去取数据,取到一个小包数据后进行CRC校验, 校验正确后才执行命令。第一个小包执行完成后接着去取下一个包,然后执行,直到把接收 到的数据解析并执行完成。临 SSCO M V5.13.1 $ n网茫数据涸才地作考:大SFT丁, 261S058qq.cam. QQ: 5 £5 02445皱成,- 匚 通fl潴口串口设萱鄢示发送参字苻M小工耳笔助庶票作霍 PCB打样降至鱼教5顽主垃邮可为杂色!奇立创宣网】|t戮据】£ 95 0103 02 Ou DL_57 5Lllml£脸止魂感器1 H二眼命令.1 : g EE 02 01 10QU 49青睁诡口r度底划牛I信止|清发孟区|厂最前厂Eng"保存端二号 | :OW11 TEI-MRIAL CKE4Dr】E:晅示俱符牧据厂 副理据刘丈件p g发送 宝讨虚这:1碰 z炊r此关诃串口仓史多吊口 1兰置加时函和分包显示.超拒间加曲剥1 m斗至1天尾垣顼竖hg三厂nrc r dti丘特全1 IF III _TK /3 为 口 K 口1 页 K 11| 嚣 1C " £口 * G 口1 ZC K M tD甘四 21.* 了知子地&辰睥.叫 尚蹈:训阵匡客方其诺1r脚到迎皿.13门 雄签打样降至每赢无,免颔邑墨,II断包邮!提供皿贴田萌m濂自中国的开源免墨商用物用vvw.daKia.ccmS:26R587COM 11 巳打开 115 200bps.3 J, None. IN on e中断接收方式:采用中断方式,只需要在宏定义#define UsartDMA 0/1配置成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停止typedef structuint8_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);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_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 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(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)/数 据从缓冲区溢出NetDat->CFraLen=lastTemp+sizeof (NetDat->RecBuf)-temp;/W溢出了 修正接收到的 字节数if(temp!=sizeof (NetDat->RecBuf)/缓存没满 满的时候temp等于缓冲区大小NetDat->InAllLen =sizeof (NetDat->RecBuf) - temp;/总计数减去未传输的数据个数, 得到已经接收的数据个数elseNetDat->InAllLen =sizeof (NetDat->RecBuf);/缓存刚好满时修正总数为缓存大小 NetDat->ReadNBytes=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;_HAL_UART_CLEAR_IDLEFLAG(NetDat->huart);/ 清除标志位#elseuint8_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_I T_SOURCE(NetDat->huart,UART_IT_IDLE)!=RESET)NetDat->CFraLen = num; 发生空闲中断,将数据长度写入到结构体 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(myuart->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 为 RDRelsetemp=(uint8_t)(myuart->huart->Instance->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->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 = EnableHAL_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 "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#define Enable 1#endif#ifndef Disable#define Disable 0#endif#define debug 1#define DebugPrint if(debug)printf typedef structunsigned char Head2;unsigned char SendDevID;unsigned char RecDevID;unsigned char Cmd;unsigned char len;unsigned char dataMax_Mess_LEN;NetPackge_Type;unsigned char NetDataUnpack(void *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->ReadPtrNetPackge_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 char *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*)&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 待解析数据*描述:按照协议头将串口接收的数据进行拆包解析,解析后数据由*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=SavePackge,*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 字节移到高位 HeadAddr=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;elseDatHead=(*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)/*(ptr+5)是 存放数据长度的位置DebugPrint ("信息长度大于%d,已超出约定范围! ! !n",Max_Mess_LEN);recdata->ReadPtr+;/读指针增加到此处读指针已经指向0x55这个字节,退出函数后再次拆包时直接取下一个数进行判断数据头,因此读指针要+1 if(RptrAddr-bufBaseAddr>=sizeof (recdata->RecBuf)/指 针溢出 recdata->ReadPtr=recdata->RecBuf;/修 正指针位置到数组首位recdata->ReadNBytes-=sizeof (recdata->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;/修 正指针位置到数组首位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->ReadPtr=&recdata->RecBufrecdata->ReadNBytes;/修 正指针位置到实际接收位置,并指向下一个待存数据内存单元if(RptrAddr-bufBaseAddr = r

    注意事项

    本文(stm32 HAL库 串口DMA接收不定长度数据及粘包处理.docx)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开