0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FIFO队列的串口数据收发方法

FPGA之家 来源:FPGA之家 作者:FPGA之家 2022-07-12 09:16 次阅读

01

前言

嵌入式软件的开发中,串口是十分常用且基础的功能。在需要批量发送数据的场合,可以使用while循环等待发送完成标志位的方式,但是这种方式会占据主循环,影响效率。也可以采用dma的方式,但是dma在发送数据时非常高效,但是批量接收数据时,就很不灵活,特别是一些在串口数据中解析某种协议格式时,很不方便。下面介绍一种利用串口中断结合FIFO队列的串口数据收发方法,结合了不阻塞批量发与灵活接收的优点,特别适用于串口协议收发的使用场景。

02

FIFO队列

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成。相比于一个同等缓存大小的数值,FIFO就是多管理了一个先进先出的功能,方便串口数据的存入和读出。

Fifo在带操作系统嵌入式软件中都有现成的实现,但是在基础的嵌入软件中,我们可以自己实现一个。

#define UART1_IN_FIFO_SIZE   100 //接收串口队列的深度#define UART1_OUT_FIFO_SIZE 250 //发送串口队列的深度
//头文件函数列表FIFO_EXT u8 uart1infifo_data[UART1_IN_FIFO_SIZE];#define uart1infifo_count (uart1infifo_GetCount())FIFO_EXT u16 uart1infifo_front;FIFO_EXT u16 uart1infifo_rear;FIFO_EXT void uart1infifo_Clear(void);FIFO_EXT void uart1infifo_DataIn(u8 d);FIFO_EXT u8 uart1infifo_DataOut(void);FIFO_EXT u16 uart1infifo_GetSpace(void);FIFO_EXT u16 uart1infifo_GetCount(void);
//获取串口1接收队列缓存数u16 uart1infifo_GetCount(void){  u16 countR,countF;  countR = uart1infifo_rear;  countF = uart1infifo_front;  if (countR >=  countF)  {    return(countR - countF);  }  else  {    return(UART1_IN_FIFO_SIZE + countR - countF);  }}//清空串口1接收队列void uart1infifo_Clear(void){  uart1infifo_front = UART1_IN_FIFO_SIZE -1;  uart1infifo_rear = uart1infifo_front;//  uart1infifo_count = 0;}//串口1接收队列入数据void uart1infifo_DataIn(u8 d){  if (uart1infifo_count < UART1_IN_FIFO_SIZE)  {    uart1infifo_rear = (uart1infifo_rear +1) % UART1_IN_FIFO_SIZE;      uart1infifo_data[uart1infifo_rear] = d;  }}//串口1接收队列出数据u8 uart1infifo_DataOut(void){  if (uart1infifo_rear !=  uart1infifo_front)  {    uart1infifo_front = (uart1infifo_front +1) % UART1_IN_FIFO_SIZE;    return(uart1infifo_data[uart1infifo_front]);  }  else  {    return(0xff);  }}

为了节省篇幅,串口1发送队列就不详细描述了,在接收队列的基础上稍加修改即可。

03

中断收发串口

//串口发送函数 void SendDataToUart1(u8 * pData, u16 len){  u8i;  //串口发送队列将慢,等待一下数据发送  while(1){  if(uart1outfifo_GetSpace()>len+5)  {        break;      }      else      {        i = 0;      }    }    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);  //关闭中断,防止队列的进出会同时进行    while (len --)    {          uart1outfifo_DataIn(*pData);      pData ++;    }      USART_ITConfig(USART1, USART_IT_TXE, ENABLE);}
//串口处理函数void USART1_IRQHandler(void){  if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE))  {    uart1infifo_DataIn(USART_ReceiveData(USART1));//接收数据并放入串口接收队列  //串口数据处理flag  }  else if (USART_GetFlagStatus(USART1, USART_FLAG_TXE))  {    if (uart1outfifo_count > 0)    {      USART_SendData(USART1, uart1outfifo_DataOut());//发队列取出数据放入串口发送寄存器}else {      USART_ITConfig(USART1, USART_IT_TXE, DISABLE);    }  }}

04

串口数据处理

不定长数据包超时处理

在上节的“串口数据处理flag”处,加入超时的标记g_uartTimeOut = n;并在定时器中断中倒计时g_uartTimeOut,减到0后,产生数据包处理标志gb_needDealUartPkg = 1。主循环扫到gb_needDealUartPkg是1后,读出uart1infifo中的全部数据进行解包处理。

不定长数据包按内容格式处理

在上节的“串口数据处理flag”处,加入比对数据包格式的函数,当格式满足要求时,将整个数据包存入数据包队列(参照前面的串口数据接收函数,写一个接收队列,接收的数据为数据包结构体)。主循环扫描数据包队列的缓存数,有就去处理。

定长数据包处理

主循环中扫描uart1infifo_count,当达到定长后,读出uart1infifo中的定长数据进行解包处理。

原文标题:嵌入式软件中的串口收发队列设计方法

文章出处:【微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

审核编辑:彭静

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 操作系统
    +关注

    关注

    37

    文章

    6293

    浏览量

    121921
  • fifo
    +关注

    关注

    3

    文章

    369

    浏览量

    43091
  • 串口数据
    +关注

    关注

    0

    文章

    30

    浏览量

    13797

原文标题:嵌入式软件中的串口收发队列设计方法

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    RT-Thread Nano入门:串口接收与消息队列

    本文主要介绍怎么用RT-Thread Nano的消息队列方式实现串口数据接收,结合串口接收中断和空闲中断,接收上位机发来的一帧数据
    的头像 发表于 11-22 11:07 1081次阅读
    RT-Thread Nano入门:<b class='flag-5'>串口</b>接收与消息<b class='flag-5'>队列</b>

    如何使用硬件FIFO来减少接收中断次数

    本文给介绍如何使用带FIFO串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一种特殊的串口数据发送
    发表于 11-06 12:22 291次阅读
    如何使用硬件<b class='flag-5'>FIFO</b>来减少接收中断次数

    STM32 HAL库串口收发是如何使用的?

    的一种库,它提供了一种简单易用的方法来使用STM32的各种外设。 本文将详细介绍如何使用STM32 HAL库来进行串口通信,包括初始化、发送数据和接收数据等方面。 1. 初始化
    的头像 发表于 10-26 17:42 748次阅读

    两个栈实现一个队列方法

    栈和队列是比较基础的数据结构。无论在工作中,还是在面试中,栈和队列都用的比较多。在计算机的世界,你会看到队列和栈,无处不在。 栈:一个先进后出的数据
    的头像 发表于 10-08 15:54 588次阅读

    基于STM32的串口环形队列IAP调试

    基于STM32的串口环形队列IAP调试心得
    的头像 发表于 09-18 15:33 870次阅读
    基于STM32的<b class='flag-5'>串口</b>环形<b class='flag-5'>队列</b>IAP调试

    基于循环队列FIFO缓存实现

    FIFO缓存是介于两个子系统之间的弹性存储器,其概念图如图1所示。它有两个控制信号,wr和rd,用于读操作和写操作。当wr被插入时,输入的数据被写入缓存,此时读操作被忽视。FIFO缓存的head一般
    的头像 发表于 09-11 10:12 458次阅读
    基于循环<b class='flag-5'>队列</b>的<b class='flag-5'>FIFO</b>缓存实现

    基于循环队列FIFO缓存设计实现

    FIFO缓存是介于两个子系统之间的弹性存储器,其概念图如图1所示。它有两个控制信号,wr和rd,用于读操作和写操作。
    发表于 09-08 09:06 264次阅读
    基于循环<b class='flag-5'>队列</b>的<b class='flag-5'>FIFO</b>缓存设计实现

    RTOS共享串口常见处理方法

    队列操作方法就是FIFO,先入先出的原理。比如:任务A要使用UART发送一串数据,将其加入队列; 接着任务B也要使用UART发送一串
    的头像 发表于 07-29 10:02 633次阅读

    使用IP核创建单时钟FIFO

    被写入FIFO中,然后FPGA再以UART串口通信依次将数据发送出去。因为传感器采集数据的速度很快,比如当传感器使用SPI通信协议,以2M的SPI
    的头像 发表于 07-23 11:47 401次阅读
    使用IP核创建单时钟<b class='flag-5'>FIFO</b>

    FreeRTOS消息队列介绍

    项目。队列所能保存的最大数据项目数量叫做队列的长度,创建队列的时候会指定数据项目的大小和队列的长
    的头像 发表于 07-06 16:58 505次阅读
    FreeRTOS消息<b class='flag-5'>队列</b>介绍

    STM32 HAL库串口收发如何使用

    使用 STM32CubeMX 做好初始化,就可以直接使用了。 但是最近在某些产品上使用串口同时收发的时候,发现有时候串口会收不到数据了,但是发送正常,而且这个问题再
    的头像 发表于 06-22 10:38 4084次阅读
    STM32 HAL库<b class='flag-5'>串口</b><b class='flag-5'>收发</b>如何使用

    如何实现串口数据的接收呢?

    UART接收数据部分是接收另一个串口设备发送的数据,缓存到接收FIFO中。FIFO快要写满时,产生中断通知CPU拿取
    的头像 发表于 06-05 15:24 2787次阅读
    如何实现<b class='flag-5'>串口</b><b class='flag-5'>数据</b>的接收呢?

    同步FIFO设计(上)

    FIFO,First In First Out,先入先出队列,顾名思义,即第一个到达的数据也将会是第一个离开。
    的头像 发表于 06-05 14:39 594次阅读
    同步<b class='flag-5'>FIFO</b>设计(上)

    详解单片机串口高效收发数据的实现方法

    摘要:本文在探讨传统数据收发不足之后,介绍如何使用带FIFO串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一
    的头像 发表于 05-10 09:37 1470次阅读
    详解单片机<b class='flag-5'>串口</b>高效<b class='flag-5'>收发</b><b class='flag-5'>数据</b>的实现<b class='flag-5'>方法</b>

    一种高效的串口收发思路及方案

    摘要:本文在探讨传统数据收发不足之后,介绍如何使用带FIFO串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一
    的头像 发表于 05-08 14:46 474次阅读
    一种高效的<b class='flag-5'>串口</b><b class='flag-5'>收发</b>思路及方案