您当前的位置:首页 > 电脑百科 > 软件技术 > 软件技术

串口接收不定长数据的几种方法

时间:2022-09-21 14:34:14  来源:今日头条  作者:嵌入式Linux

串口作为单片机开发的一个常用的外设,应用范围非常广。大部分时候,串口需要接收处理的数据长度是不定的。那么怎么才能判断一帧数据是否结束呢,今天就以STM32单片机为例,介绍几种接收不定长数据的方法。

首先,我们需要打开一个串口,使用STM32CubeMx来配置,如下:

 

然后打开串口中断、添加发送和接收的DMA,DMA参数设置为默认即可,如下图。(DMA可根据自身需求选择是否打开)

 

 

配置一下时钟等,点击生成代码,这样就可以使用串口了。首先我们定义一个串口接收的结构体,并定义一个结构体变量,如下:

#define  RX_MAXLEN  200  //最大接收数据长度


typedef struct{
      uint8_t  RxBuf[RX_MAXLEN];//接收缓存
      uint16_t RxCnt;    //接收数据计数
      uint16_t RxLen;    //接收数据长度
      uint8_t RxStart;    //开始接收标志
      uint8_t RxFlag;    //一帧数据接收完成标志
}Uart_Tpye_t;


Uart_Tpye_t Uart1;

下面介绍几种接收数据的方法:

1.空闲中断

空闲中断可以配合接收中断或DMA来使用。

当使用DMA+空闲中断时,需要在初始化完成后手动打开空闲中断和DMA接收。

__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打开串口空闲中断 
HAL_UART_Receive_DMA(&huart1, Uart1.RxBuf, RX_MAXLEN); //串口DMA接收数据

编写空闲中断函数,如下:

//串口空闲中断
void UART_IDLECallBack(UART_HandleTypeDef *huart)
{
    uint32_t temp;  
  /*uart1 idle processing function*/
    if(huart == &huart1)
    {
      if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
      {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
        /*your own code*/
        HAL_UART_DMAStop(&huart1);//停止DMA
        Uart1.RxLen = RX_MAXLEN - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中传输的数据个数
        Uart1.RxFlag = 1;
        HAL_UART_Receive_DMA(&huart1,Uart1.RxBuf,RX_MAXLEN); //开启下次接收
      }
    }
}

在主程序中判断接收完成标志,并处理数据:

if(Uart1.RxFlag == 1)//接收完一帧数据
{
  printf("Rev %d Bytesrn",Uart1.RxLen);
  Uart1.RxFlag = 0;
}

最后,别忘了在串口中断函数中调用自己编写的空闲中断函数。

 

运行程序测试,结果如下:

 

使用接收中断+空闲中断与DMA类似,只不过需要打开接收中断:

__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//打开串口空闲中断  
HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据

编写接收中断回调函数,每次接收一个字节:

uint8_t RevByte;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{    
  if(huart->Instance==USART1)
  {
    Uart1.RxBuf[Uart1.RxCnt]=RevByte;
    Uart1.RxCnt++;
    if(Uart1.RxCnt==RX_MAXLEN)
    {
      Uart1.RxCnt = RX_MAXLEN-1;
    }
    HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据
  }
}

编写空闲中断回调函数,与DMA的方式类似,只是数据长度判断方式不一样:

//串口空闲中断
void UART_IDLECallBack(UART_HandleTypeDef *huart)
{
  uint32_t temp;  
  /*uart1 idle processing function*/
  if(huart == &huart1)
  {
    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
    {
      __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
      Uart1.RxFlag = 1;
      Uart1.RxLen = Uart1.RxCnt;
      Uart1.RxCnt = 0;
    }
  }
}

同样,在主程序中判断一帧数据的接收完成并处理。

 

2.特点协议判断帧头帧尾及长度

有时候我们需要自己定义协议传输数据,这时候就可以在通讯协议里添加特点的帧头帧尾以及数据长度字节,通过判断这些字节来判断数据的开始和结束。假设定义一个简单的传输协议如下:

帧头

数据长度,1字节

数据,N字节

0x5A,0xA5

数据部分的字节数

有效数据

可以使用中断方式接收数据:

HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据

接收中断函数如下:

//串口接收中断回调函数
uint8_t RevByte;
uint16_t RevTick = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  static uint16_t Rx_len;


  if(huart->Instance==USART1)
  {
    Uart1.RxBuf[Uart1.RxCnt]=RevByte;
    switch(Uart1.RxCnt)
    {
      case 0:
        if(Uart1.RxBuf[Uart1.RxCnt] == 0x5A)//帧头1正确
          Uart1.RxCnt++;
        else
          Uart1.RxCnt = 0;
        break;
      case 1:
        if(Uart1.RxBuf[Uart1.RxCnt] == 0xA5)//帧头2正确
          Uart1.RxCnt++;
        else
          Uart1.RxCnt = 0;
        break;
      case 2:
        Rx_len = Uart1.RxBuf[Uart1.RxCnt];
        Uart1.RxCnt++;
        break;
      default:
        Uart1.RxCnt++;
        if((Rx_len+3) == Uart1.RxCnt)//数据接收完成
        {
          Uart1.RxFlag = 1;
          Uart1.RxLen = Uart1.RxCnt;
          Uart1.RxCnt = 0;
        }
        break;
    }
    HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据
  }
}

同样,在主程序中判断一帧数据的接收完成并处理,运行测试结果如下:

 

3.超时判断

超时判断其实与空闲中断的原理类似,只不过是通过定时器来取代空闲中断来判断一帧数据的结束,一般采样接收中断+超时判断的方式。之前的文章Freemodbus移植就是采样这种方式。

超时判断的时间跟波特率有关,假设串口起始位和结束位各1位,那么接收一个字节就需要8+2=10位,在9600波特率下,一秒钟就能接收9600/10=960字节。也就是一个字节需要1.04ms,那么超时时间最小可以设置为1.5倍的单字节接收时间,或者更长。

超时判断可以使用硬件定时器或软件定时器来实现。硬件定时器的方式可以参考之前的Freemodbus移植部分的程序。软件定时器定义一个计时变量,该变量在systick中断中+1实现计时,可以节省硬件资源,但计时最小分辨率跟systick中断有关。

编写中断接收函数:

//串口接收中断回调函数
uint8_t RevByte;
uint16_t RevTick = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if(huart->Instance==USART1)
  {
    Uart1.RxBuf[Uart1.RxCnt]=RevByte;
    Uart1.RxCnt++;
    Uart1.RxStart = 1;//开始接收标志
    RevTick = 0;//计时清零
    if(Uart1.RxCnt==RX_MAXLEN)
    {
      Uart1.RxCnt = RX_MAXLEN-1;
    }
    HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据
  }
}

编写超时判断函数,在Systick中断中调用:

//串口接收超时判断,该函数在Systick中断(1ms中断一次)中调用
void UartTimeOut()
{
  if(Uart1.RxStart == 1)
  {
    RevTick++;
    if(RevTick > 2)
    {
      Uart1.RxLen = Uart1.RxCnt;
      Uart1.RxCnt = 0;
      Uart1.RxStart = 0;
      Uart1.RxFlag = 1;
    }
  }
}

使用时只要打开接收中断即可,不再需要空闲中断。

HAL_UART_Receive_IT(&huart1, &RevByte, 1); //串口中断接收数据

同样,在主程序中判断一帧数据的接收完成并处理。测试结果就不贴了。

4.总结

上面几种方式都可以实现串口接收不定长数据,各有优缺点,可根据实际需求选择用哪种。需要注意的是,上面的例程只是简单地接收数据,实际应用中,还需要考虑连续接收多帧数据的情况,是缓存之后处理,还是舍弃后面的数据,都需要自己写程序实现。

文章链接:
https://mp.weixin.qq.com/s/N9_37bwnquM5rMbNMf_Sjg

转载自:Mr张工 嵌入式技术开发

文章来源:串口接收不定长数据的几种方法

版权申明:本文来源于网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。



Tags:串口   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
串口服务器能实现B接口功能吗?
想了解串口服务器能不能实现B接口功能,首先我们得明白串口服务器的工作原理串口服务器串口服务器提供串口转网络功能,能够将RS-232/485/422串口转换成TCP/IP协议网络接口,实现R...【详细内容】
2023-11-09  Search: 串口  点击:(241)  评论:(0)  加入收藏
Openharmony南向研究—Linux驱动框架-串口
​驱动开发 -串口和串行总线基本知识一般情况下,设备间的通信方式可以划分为串行通行方式和并行通信方式两种。在Linux字符设备、块设备、网络设备分类方式下,该外设分类划分...【详细内容】
2023-03-09  Search: 串口  点击:(361)  评论:(0)  加入收藏
利用UART串口实现数据的收发
cortex-A7核通过UART串口实现数据的收发1.简单理解总线 总线即为各个部位之间通信的一种媒介,芯片内部的总线控制的是内部各个控制器和核之间的通信,例如SOC通过AHB4总...【详细内容】
2022-10-05  Search: 串口  点击:(421)  评论:(0)  加入收藏
一个串口通讯的简单项目分析
项目描述:串口是一个比较常见的通讯形式,本项目使用一个单片机作为串口数据发送装置的模拟,另外一个单片机作为串口接收的模拟。单片机使用传统的8051单片机,软件开发工具使用mi...【详细内容】
2022-10-02  Search: 串口  点击:(403)  评论:(0)  加入收藏
串口接收不定长数据的几种方法
串口作为单片机开发的一个常用的外设,应用范围非常广。大部分时候,串口需要接收处理的数据长度是不定的。那么怎么才能判断一帧数据是否结束呢,今天就以STM32单片机为例,介绍几...【详细内容】
2022-09-21  Search: 串口  点击:(749)  评论:(0)  加入收藏
GD32 虚拟串口通讯速度测试
GD32 虚拟串口通讯速度测试硬件说明: MCU: GD32C103 120M,128K,32k RAM. 输入:USB 5V. OBD功能口定义:OBD(2,10)VPWM、OBD 7(K线)、OBD 6(CAN H)、OBD 14(CAN L)、OBD 15(L...【详细内容】
2022-09-14  Search: 串口  点击:(767)  评论:(0)  加入收藏
对串口接收FIFO处理机制的解读
一、FIFO是First Input First Output的缩写,先入先出队列。使用的场景:一般是在不同的时钟域之间的数据传输(简单理解即:一个(读\写)快,另外的一个(读\写)慢的场景中。)本质操作:就是将...【详细内容】
2022-09-14  Search: 串口  点击:(1107)  评论:(0)  加入收藏
win10串口单片机烧录开启失败解决方法
in10串口单片机烧录开启失败的问题今天和大家一起来分享下。不少的用户在安装了这个软件之后,首次开启使用的时候都有遇到这样的问题。原因可能是相关的程序串口被占用了,我们...【详细内容】
2022-09-01  Search: 串口  点击:(575)  评论:(0)  加入收藏
串口服务器的概念及主要作用
在物联网中,串口服务器大家想必都是耳熟能详的一个词,但是网上对这个产品的概念讲的比较明白的,没多少,碰巧在网上看到一篇对于串口服务器概念讲解比较明了的文章,如下:串口服务器...【详细内容】
2022-08-26  Search: 串口  点击:(541)  评论:(0)  加入收藏
串口服务器有什么作用?什么是文件服务器
一、串口服务器作用①串口服务器就是能够连接计算机端口和其他嵌入式的计算机设备,并记录端口设备的具体型号数据信息。②串口服务器所需连接的使用指定的服务器端口,在此型号...【详细内容】
2022-04-22  Search: 串口  点击:(543)  评论:(0)  加入收藏
▌简易百科推荐
如何在Windows 10中查看电脑的名称?这里提供详细步骤
你想在有多台计算机组成的网络上查找你的计算机吗?一种方法是找到你的电脑名称,然后在网络上匹配该名称。下面是如何在Windows 10中使用图形和命令行方法查看你的计算机名称。...【详细内容】
2024-04-10  驾驭信息纵横科技    Tags:Windows 10   点击:(2)  评论:(0)  加入收藏
移动版 Outlook 解锁新技能,可验证登录 OneDrive 等微软服务
IT之家 4 月 9 日消息,微软公司近日发布新闻稿,宣布用户可以使用 Outlook 手机应用,轻松登录 Teams、OneDrive、Microsoft 365 以及 Windows 等微软账号服务。移动端 Outlook...【详细内容】
2024-04-09    IT之家  Tags:Outlook   点击:(3)  评论:(0)  加入收藏
Win10/Win11和 macOS用户反馈:谷歌云服务“捆绑”系统 DNS 设置
IT之家 4 月 6 日消息,谷歌公司承认旗下的 Google One 订阅服务中存在问题,在 Windows 10、Windows 11 以及 macOS 系统上会更改系统 DNS 设置,变更为 8.8.8.8 地址。Google On...【详细内容】
2024-04-08    IT之家  Tags:Win10   点击:(7)  评论:(0)  加入收藏
电脑卡顿怎么重装系统,快看这篇
电脑卡顿时,重装系统确实是一种可能的解决方案。以下是重装系统的详细步骤:备份重要数据:首先,你需要将电脑中的重要文件和数据备份到外部存储设备(如U盘、移动硬盘或云存储)中,以...【详细内容】
2024-04-04  科技数码前锋    Tags:重装系统   点击:(2)  评论:(0)  加入收藏
如何检查电脑的最近历史记录?这里提供详细步骤
如果你怀疑有人在使用你的计算机,并且你想查看他们在做什么,下面是如何查看是否有访问内容的痕迹。如何检查我的计算机的最近历史记录要检查计算机的最近历史记录,应该从web浏...【详细内容】
2024-03-30  驾驭信息纵横科技    Tags:历史记录   点击:(1)  评论:(0)  加入收藏
关于Windows中AppData的相关知识,看这篇文章就可以了
如果AppData文件夹占用了你电脑上的太多空间,则需要清理AppData文件夹。下面是一些帮助你在Windows计算机上进行AppData清理的方法。什么是AppData文件夹AppData文件夹是保存...【详细内容】
2024-03-30  驾驭信息纵横科技    Tags:AppData   点击:(3)  评论:(0)  加入收藏
微软 Edge 浏览器将迎来“内存限制器”功能,用户可自主控制 Edge 内存占用
IT之家 3 月 28 日消息,微软即将为其 Edge 浏览器带来一项实用新功能,据悉该公司正在测试一项内置的内存限制器,这项功能可以让用户限制 Edge 所占用的内存,防止浏览器超出内存...【详细内容】
2024-03-29    IT之家  Tags:Edge   点击:(15)  评论:(0)  加入收藏
一寸照片的大小如何压缩?四个实测效果很好的方法
一寸照片作为生活中常见的尺寸之一,常用于各类证件照与证明文件的制作。然而,受限于其较为狭小的尺寸,上传及打印过程中很容易出现尺寸超限的情况。所以,这个时候就需要对其体积...【详细内容】
2024-03-18  宠物小阿涛    Tags:压缩   点击:(14)  评论:(0)  加入收藏
手机投屏到电脑/电视的方法
方法一:Win10自带的投影功能1、将手机和电脑连接同一个无线网络。2、选择【开始】>【设置】>【系统】>【投影到此电脑】3、将默认的始终关闭的选项更改为所有位置都可用。4、...【详细内容】
2024-03-18    老吴讲I  Tags:投屏   点击:(17)  评论:(0)  加入收藏
微软商店怎么卸载应用 一分钟快速看懂!
微软商店怎么卸载应用 一分钟快速看懂!微软公司(Microsoft Corporation)是一家全球领先的科技企业,总部位于美国华盛顿州的雷德蒙德。成立于1975年,由比尔·盖茨和保罗&mid...【详细内容】
2024-02-27  婷婷说体育    Tags:微软商店   点击:(38)  评论:(0)  加入收藏
站内最新
站内热门
站内头条