精华内容
下载资源
问答
  • 帧数据
    千次阅读
    2021-11-15 19:01:10

    本文介绍3种使用串口接受一帧完整数据包的方法,串口接收数据是字节接收的,串口每接收1字节数据,产生一个串口中断,我们在中断中将接收到的数据存放到buf中进行保存,但是数据的发送和接收都是按照帧为单位进行传输的,因此我们要在接收数据的同时判断当前接收的数据是否是完整的一帧。
    一般串口完整数据帧的定义:帧头(2字节,例如AA、BB) + 数据长度(2字节) + 数据 + CRC16校验(2字节) + 帧尾(2字节)
    帧头、帧尾表示一帧数据的开始和结尾,数据长度表示当前数据帧中负载数据大小,CRC16校验用来检查接收到的数据是否正确。
    第一种方法(根据帧头、帧尾进行判断):
    串口在接收数据时,我门在串口中断函数中对接收到的每一字节数据进行判断,如果检测到帧头数据(例如AA、BB),我们开始将接收到的数据存到buf中,同时记录下该帧数据的数据长度字段,然后一直接收,直到接收到的数据长度与我们记录下的数据长度字段值一致或接收到帧尾数据,到此一帧数据接收完成,将数据扔到消息队列,等待任务处理即可。
    假如接收的数据包格式如下 帧头(AA 、BB) + 数据长度 + 数据 + CRC校验 + 帧尾(CC、DD)
    void USART1_IRQHandler(void) //串口中断处理函数
    {
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
    buf[buf_size++] = USART_ReceiveData(USART1);
    if (buf_size >= 2)
    {
    if (buf[0] == 0xAA && buf[1] == 0xBB) //接收到帧头
    {
    //接收到帧尾
    if (buf[buf_size] == 0xCC && buf[buf_size-1] == 0xDD)
    {
    //此处为数据包处理逻辑
    buf_size = 0;
    memset(buf,0,BUF_SIEZ);
    }
    }
    else
    {
    buf_size = 0;
    memset(buf,0,BUF_SIZE);
    }
    }
    if(buf_size >= BUF_SIZE)
    {
    buf_size = 0;
    memset(buf,0,BUF_SIZE);
    }
    }
    }
    第二种方法(根据接收到的字符之间的间隔进行判断):
    串口数传输都是使用标准波特率,因此串口传输一帧数据时,字符与字符之间的时间间隔是一个固定值,我们可以根据串口的波特率去计算串口每个字符的间隔时间,在数据接收的过程中判断当字符间隔大于3.5个(modbus协议常用),则认为当前数据帧传输完毕,具体方法如下:
    我们先设置定时器超时时间为计算出的3.5字符间隔时间,然后在串口中断中每接收到一个字符,就将其保存至buf中,并刷新定时器计数值,如果串口接收到的数据时间间隔大于3.5个字符间隔,定时器就会进入超时中断,我们在定时器中断中判断当前buf中的数据是否完整,如果完整,则扔到消息队列中,等待任务去处理。
    //本例中,如果串口字符间隔大于3ms,我们认为一帧数据接收完毕,如果使用的协议是Modbus 协议,则时间间隔应该设置为3.5字符间隔时间。
    #define BUF_SIZE 128 // 定义串口接收buf 长度
    typedef enum {DISABLE = 0, ENABLE = !DISABLE} ; //定义枚举类型
    u16 buf_size = 0;
    u8 buf[BUF_SIZE] = {0}; //定义串口接收缓存区
    u16 TimerCount = 0;
    u8 TimerEnable = ENABLE; //定义定时器计数使能标志位
    void USART1_IRQHandler(void) //串口中断处理函数
    {
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断是否接收中断标志位置位
    {
    buf[buf_size++]= USART_ReceiveData(USART1); //将接收到的数据存入buf
    TimerCount=0;
    TimerEnable = ENABLE; //置位定时器计数使能标志位
    if(buf_size >= BUF_SIZE)
    {
    buf_size = 0; //接收数据缓冲区溢出,重新开始接收
    memset(buf,0,BUF_SIZE);
    }
    }
    }
    void TIM1_IRQHandler(void) //定时器中断处理函数 每1ms产生一次中断
    {
    u8 cnt = 0;
    if(TIM_GetITStatus(TIM1 , TIM_IT_Update) != RESET )
    {
    TIM_ClearITPendingBit(TIM1 , TIM_FLAG_Update); //清除定时器中断标志位
    if(TimerEnable == ENABLE)
    {
    TimerCount++;
    if(TimerCount > 3) //大于3ms,则判断为一帧数据接收完成
    {
    TimerCount = 0;
    Timer.Enable = DISABLE;
    //此处为数据包处理逻辑
    buf_size = 0;
    memset(buf,0,BUF_SIZE);
    }
    }
    }
    }
    第三种方法(使用串口帧空闲中断,推荐使用):
    串口IDLE中断,串口接收完完整的一帧数据自身产生的中断,配置使能该中断后,串口会判断总线上一个字节的时间间隔内有没有再次接收到数据,如果没有则当前一帧数据接收完成,产生IDLE中断。
    使用方法,原串口配置不变,添加下列语句,开启IDLE中断:
    #define BUF_SIZE 128 // 定义串口接收buf 长度
    u16 buf_size = 0;
    u8 buf[BUF_SIZE] = {0}; //定义串口接收缓存区
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启串口帧空闲中断
    void USART1_IRQHandler(void) //串口中断服务函数
    {
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
    buf[buf_size++] = USART_ReceiveData(USART1);
    }
    if(buf_size >= BUF_SIZE )
    {
    buf_size = 0; //接收缓冲区溢出,重新开始接收
    memset(buf,0,BUF_SIZE);
    }
    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //当前为接收到一帧完整的数据包
    {
    USART1->SR; //先读SR
    USART1->DR; //再度DR 清除帧空闲中断标志位
    //此处为数据包处理逻辑
    buf_size = 0;
    memset(buf,0,BUF_SIZE);
    }

    更多相关内容
  • STM32串口接收一帧数据的写法,数据包括帧头,功能帧,数据帧,校验位!
  • stm32支持接受单个数据或者一帧数据,若配置单个数据接收中断的话,会出现接收包丢包,数据不完整的情况!因此在stm32的串口中断中,还有一个IDLE中断,用来产生串口接受一帧数据而产生的中断,比如说串口发来n个...

    stm32支持接受单个数据或者一帧数据,若配置单个数据接收中断的话,会出现接收包丢包,数据不完整的情况!因此在stm32的串口中断中,还有一个IDLE中断,用来产生串口接受一帧数据而产生的中断,比如说串口发来n个数据,会产生n次接收中断和一次IDLE中断,因此方便使用者来接收主机发送或者从机返回的数据!

    原文链接:https://blog.csdn.net/qq_35341807/article/details/79157437

    1、配置串口中断

    void USART1_Configuration(void)
    {
    	USART_InitTypeDef USART_InitStructure;
    	GPIO_InitTypeDef GPIO_InitStructure;
    	/* Configure USART1 Rx (PA.10) as input floating */
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		  //¸¡¿ÕÊäÈëģʽ	   
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	/* Configure USART1 Tx (PA.09) as alternate function push-pull */
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;			  //¸
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	USART_InitStructure.USART_BaudRate = 9600;						//
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b;		//
    	USART_InitStructure.USART_StopBits = USART_StopBits_1;			//
    	USART_InitStructure.USART_Parity = USART_Parity_No;				//
    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //
    	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;					
    	/* Configure USART1 */
    	USART_Init(USART1, &USART_InitStructure);							
    	/* Enable USART1 Receive and Transmit interrupts */
    	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                    //
    	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//
    	/* Enable the USART1 */
    	USART_Cmd(USART1, ENABLE);	                  //
    }
    

    关键

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//没收到一个字节进入一次中断
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启串口空闲中断,每收到一帧数据进入一次中断
    

    2、串口中断函数

    处理一帧数据中所需要的内容

    一帧数据原始内容:
    在这里插入图片描述
    我要提取出这帧数据中的31.93

    char rece_buffer[BUFSIZ];
    int RxCounter;
    
    void USART1_IRQHandler(void)	
    {
    	 u8 clear=clear;
    	 USART_ClearFlag(USART1,USART_FLAG_TC);
     //接收一帧数据
    	 if(USART_GetITStatus(USART1,USART_IT_RXNE)!=Bit_RESET)        
    	   {
     
               rece_buffer[RxCounter++]=USART1->DR;
    	   }
    		 
    	 else if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=Bit_RESET)
    	        {					
                    clear=USART1->SR;
                    clear=USART1->DR;						
    	              RxCounter=0;
    						
    						//温度传感器的一帧数据,对需要的内容进行提取
    						if((rece_buffer[0]=='o')&&(rece_buffer[1]=='b')&&(rece_buffer[2]=='j'))
    						{
    								if(rece_buffer[9]=='-')  //¸ºÊý
    								{
    								;
    								}
    						else
                {
    								if(rece_buffer[10]=='.')   //x.xx
    								{
    								obj=(rece_buffer[9]-0x30)*100+(rece_buffer[11]-0x30)*10+(rece_buffer[2]-0x30);
    								}
    								if(rece_buffer[11]=='.')   //xx.xx
    								{
    								obj=(rece_buffer[9]-0x30)*1000+(rece_buffer[10]-0x30)*100+(rece_buffer[12]-0x30)*10+(rece_buffer[13]-0x30);
    								}
    								if(rece_buffer[12]=='.')   //xxx.xx
    								{
    								obj=(rece_buffer[9]-0x30)*10000+(rece_buffer[10]-0x30)*1000+(rece_buffer[11]-0x30)*100+(rece_buffer[13]-0x30)*10+(rece_buffer[14]-0x30)*10;
    								}
    								
    						    obj_T=obj/100;
    						}
    						printf("目标温度:%f",obj_T);
    						}
    						//printf("%s",rece_buffer);
                    }	
    					
    }
    

    最终获得需要是数据
    在这里插入图片描述

    展开全文
  • 帧数据接收方法

    千次阅读 2020-09-03 20:58:19
    最近在做485数据通讯,遇到一些通讯问题,特意去查找资料,一帧数据接收有三种方法,现分享如下: 第一种方法:根据帧头和帧尾进行校验, 串口发送2字节例如(AA ,BB),然后程序对每2个字节进行判断,例如设定一个...

    最近在做485数据通讯,遇到一些通讯问题,特意去查找资料,一帧数据接收有三种方法,现分享如下:
    第一种方法:根据帧头和帧尾进行校验,
    串口发送2字节例如(AA ,BB),然后程序对每2个字节进行判断,例如设定一个起始位例如AA,当程序收到AA,起始条件成立,开始接收数据,在设定一个终止位BB,当程序收到BB,终止条件成立,程序停止接受数据,然后把收到的数据放到一个数组里面,对收到的数据进行CRC校验,校验成立,则对收到的数据进行处理
    程序如下:

    if(USART_GetITStatus(RS485_USART_SOURCE, USART_IT_RXNE) != RESET)
    	{
    		USART_ClearITPendingBit(RS485_USART_SOURCE, USART_IT_RXNE);
    		
    		if(USART_GetFlagStatus(RS485_USART_SOURCE, USART_FLAG_ORE) != RESET) //Òç³ö´íÎó±ê־λ
    		{
    			USART_ClearFlag(RS485_USART_SOURCE, USART_FLAG_ORE);
    		}
    		
    		temp_rec = USART_ReceiveData (RS485_USART_SOURCE);
    	
    		switch(temp_rec)
    		{		
    			case __Start://ÊÕµ½Æðʼ룬½ÓÊÕÊý¾Ý¿ªÊ¼
    				if(!CommuSta.bRecOn)
    				{
    					CommuSta.bRecOn = SET;// ±íʾÕýÔÚ½ÓÊÕÊý¾Ý
    					len = 0;
    					aRxBuf[len++] = temp_rec;
    				}
    				break;
    
    			case __Stop://ÕÒµ½ÖÕֹ룬½ÓÊÕÊý¾Ý½áÊø
    				if(CommuSta.bRecOn)
    				{
    					CommuSta.bRecOn = RESET; // ½ÓÊÕÊý¾Ý½áÊø
    					CommuSta.bRecEnd = SET;  // Ò»Ö¡Êý¾ÝÊÕÍê
    
    					aRxBuf[len] = temp_rec;
    					gRecBufLen = ++len;
    					len = 0;
    				}
    				break;
    

    但是程序出问题了,原因是发送过来的指令起始位与终止位之间有字节与起始位或终止位相同,l例如7E(起始位) 01 B4 03 +CRC校验(CD 7E)+7F(终止位),CRC校验的7E与起始位相同,程序接收数据又重新开始,所以出错,因为是一个字节一个字节的接收数据,所以对帧头和帧尾进行判定有时会出错。
    第二种方法:使用串口帧空闲中断
    使能串口帧空闲中断,当接收一帧数据后,串口会产生一次中断,根据是否产生中断来判断是否接收一串完整的数据,这种方法不存在方法1的问题,推荐使用
    第三种方法:根据接收到的字符之间的间隔进行判断
    串口数传输都是使用标准波特率,因此串口传输一帧数据时,字符与字符之间的时间间隔是一个固定值,我们可以根据串口的波特率去计算串口每个字符的间隔时间,在数据接收的过程中判断接收的两个字节之间间隔大于3.5个字符间隔时间,则认为当前数据帧传输完毕

    展开全文
  • PPP帧数据部分

    千次阅读 2021-12-26 15:31:24
    计算机网络ppp数据帧 一个PPP数据部分(用十六进制写出)是7D 5E FE 27 7D 5D 7D 5D 65 7D 5E。试问真正的数据是什么(用十六进制写出)? 答:在ppp部分,0x7E(7D,5E) 0x7D(7D,5D)替换数据帧部分得到真正数据:...

    计算机网络ppp数据帧
    一个PPP帧的数据部分(用十六进制写出)是7D 5E FE 27 7D 5D 7D 5D 65 7D 5E。试问真正的数据是什么(用十六进制写出)?
    答:在ppp帧部分,0x7E(7D,5E) 0x7D(7D,5D)替换数据帧部分得到真正数据:7E FE 27 7D 7D 65 7E

    计算机网络第七版习题

    展开全文
  • 使用stm32串口发送一帧数据,具体程序如下,相关知识点请自行脑补。 1、串口发送字符串 /***************** 发送一个字节 **********************/ //myUSARTx:具体串口 //ch: 一个8位的字节 void Debug_SendByte...
  • STM32串口中断接收一帧数据

    千次阅读 2021-01-03 22:52:57
    STM32串口中断接收一帧数据 IDLE即串口空闲中断,串口收到一帧数据后,发生的中断。比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。因为只有接收...
  • 1、在Activity界面代码中: private var mCamera: Camera? = null private val mWidth = GwApplication.DEFAULT_REMOTE_WIDTH_EXT private val mHeight = GwApplication.DEFAULT_REMOTE_HEIGHT_EXT ...
  • 关于STM32串口3的使用,接收并解析一帧数据

    万次阅读 多人点赞 2020-06-03 10:21:38
    关于STM32串口3的使用,接收并解析一帧数据 当stm32的串口1被使用时,我们可以使用其他串口来使用。 步骤: 串口3定义、初始化; 串口3中断服务函数(接收的一帧数据并判断是否正确); 主函数使用; 首先,我们要将...
  • Qt获取摄像头画面的每一帧数据

    千次阅读 热门讨论 2019-01-08 12:52:38
    继承自QAbstractVideoSurface,实现它的一些虚函数,可以在实现的虚函数 present 中获取到摄像头画面的一帧数据,拿到数据之后就可以转换处理了,这里拿到数据之后,绘制在主窗口上了。 主要代码: 首先在 .pro 中...
  • android获取摄像头视频帧数据

    万次阅读 热门讨论 2018-09-28 10:25:11
    此回调函数public void onPreviewFrame(byte[] data, Camera camera)每回调一次就是获取到摄像头的一原始数据即data字节数组。 三.这个字节数组经过YuvImage类包装压缩成特定类型图片。 2.代码...
  • 让串口可以自动分辨一帧数据

    千次阅读 2018-01-02 10:39:49
    串口接收完整一帧数据处理方式 原文地址:让串口可以自动分辨一帧数据作者:李冬冬 有时我们希望串口接收到数据后,在该帧数据的末尾加上一些标志,比如这是第几帧或接收的时间等等。那么我们就需要知道什么...
  • 串口接收一帧数据及解析

    万次阅读 多人点赞 2018-05-25 11:28:16
    3. 下位机中的数据接收和协议解析 下位机接收数据也有两种方式,一、等待接收,处理器一直查询串口状态,来判断是否接收到数据。二、中断接收。两种方法的优缺点在此前的一篇关于串口通信的文章中详细讨论过。得出...
  • 否则,将会影响下一帧数据的同步和接收用前面提到的序列“0x00 0xAA 0xAA 0x55…”进行测试,随着串口接收中断收到新的字节帧同步队列中的数据依次为:[0xFF,→[0x00,→[0xAA,→[0xAA,→[0x55,此时,该算法检测...
  • FPGA和其他设备进行通信的时候,如果传输的是大量数据,肯定需要打包(组帧)进行传输,而且都需要有帧头和校验位来确保帧数据传输正确。今天说一下最近自己做的一个项目涉及到的这个问题。 当FPGA作为接收端去接收...
  • H.264裸流文件中获取每一帧数据

    万次阅读 2018-07-27 15:54:01
    测试解码器性能时,最常用的无非是向解码器中推送码流。  之前封装了一个avc的解码器,想做一个测试,读取H.264裸流文件将码流定期...提取H.264码流调用接口推送数据  1. 了解H.264逻辑文件  根据H.264协议,a...
  • 这样就可以在不改动图像模型的情况下实现视频流数据的处理工作,当然视频流数据也可以采用视频的处理方法来直接处理,这里今天主要是实践一下视频流数据的预处理工作,即:将视频流数据切割为图像帧数据,实践内容很...
  • [FPGA]以太网帧数据UDP报文解析接收

    千次阅读 多人点赞 2019-05-06 21:20:38
    前言:做的项目需要读取网口发来的数据,发现做一遍真的是对这几种格式熟悉了一遍。 网口发来的格式是以太网格式,上一层使用IP协议,传输的UDP报文。 系统:WIN10, 开发平台:ISE 14.7 编程语言:VHDL 硬件...
  • 通过串口接受一帧数据请参考的我博客中的文章——教你如何使用stm32接收一帧数据! 一:在.h首先定义一个结构体。 typedef struct { uint8_t H1; uint8_t F1; uint8_t A[7]; uint8_t AN;
  • CAN总线多帧即连续帧数据发送 拆包与重装

    万次阅读 多人点赞 2017-09-13 20:42:31
    1939协议支持多帧数据发送即数据超过8个的帧发送 用户可以通过ID来识别当前帧是否为多帧发送(连续帧),如果是多帧发送ID,举例:1C EC F4 56 其中 F4和56为目标地址和源地址,重点关注1C和EC,通过ID的这两个字节...
  • 录像一帧数据大小

    千次阅读 2016-07-08 15:09:07
    帧数据:1600*1200*3=5M 不压缩是5M 录像一秒会是15帧或者20帧,这里不压缩就要相乘,一般的不管图片是视频,在传到屏或者存储到本地,生产图片或者视频,头要经过压缩的。 视频的图片的压缩技术分:MPEG 即...
  • d盘有一个test.264文件,我们需要从这个h264文件中提取出一数据,所以直接采用ffmpeg来做。 #include <iostream> #include <stdio.h> #include <string.h> #include <errno.h> #...
  • stm32串口中断接收一帧数据

    万次阅读 多人点赞 2017-02-18 17:11:53
    最近用到stm32的串口,中断一个字符一个字符接收好心累,网上度了一下发现了一篇好的...今天说一下STM32单片机的接收不定长度字节数据的方法。由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数...
  • 一、本文重点说明 本文基于 android camera2 实现视频预览,暂未兼容 camera1 API,基础实现可以...谷歌例子中没有具体指明预览的获取,即 camera1 setPreviewCallback 类似功能实现,具体是通过 ImageReader 中...
  • 有时候需要在视频上画图,所以需要能获取到每一视频数据。 以前从视频文件或视频流中得到,一般都是使用qt + ffmpeg或qt + vlc。 qt对显示处理视频大体有以下方法: 1. QMediaPlayer + QVideoWidget 这种...
  • Camera摄像头帧数据转为bitmap

    千次阅读 2019-02-18 10:31:10
    Camera摄像头帧数据转为bitmap 文章目录Camera摄像头帧数据转为bitmap帧数据转为bitmap关于YuvImage**compressToJpeg 方法** 帧数据转为bitmap Android下摄像头预览数据默认为 ImageFormat.NV21 格式的,通过...
  • 串口发送一帧数据时,两个字节的间隔时间是多少?
  • 否则,将会影响下一帧数据的同步和接收用前面提到的序列 “ 0x00 0xAA 0xAA 0x55 …” 进行测试,随着串口接收中断收到新的字节帧同步队列中的数据依次为: [0xFF , 0xFF] → [0x00 , 0xFF] → [0xAA , 0x00] ...
  • 51单片机串口通信的帧数据接收

    千次阅读 2015-12-12 21:35:42
    首先定义一个数据帧格式,Header...数据的格式就是上面的定义 Header 为头 标记一个数据帧的开始,type 为类型 用来识别数据的类型 ,Length为长度标记 用来识别是否收完一数据; 这次的目的是为了获取来自PC端串
  • 802.11帧数据详细讲解

    万次阅读 2015-12-20 19:55:03
    4. 802.11标准中的数据安全加密协议     1. 802.11标准简介 IEEE 802.11是现今无线局域网通用的标准,它是由国际电机电子工程学会(IEEE)所定义的无线网络通信的标准。 其中定义了媒体访问控制层...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 437,692
精华内容 175,076
关键字:

帧数据