串口使用DMA数据接收和发送

  串口DMA部分在这里我一共分3个部分进行介绍,第一部分介绍什么是DMA第二部分是介绍串口DMA+空闲中断实现不定长数据的收发。第三部分是串口DMA中断实现数据收发。

第一部分DMA介绍

一、基本概念

  DMA是直接寄存器,这是指一种高速的数据传输操作,允许在外部设备和存储器和寄存器与寄存器之间直接读写数据,既不通过CPU,也不需要CPU干预。整个数据传输操作在一个称为"DMA控制器"的控制下进行的。CPU除了在数据传输开始和结束时做一点处理外,在传输过程中CPU可以进行其他的工作,不需要CPU的参与。这样,在大部分时间里,CPU和输入输出都处于并行操作。因此,使整个计算机系统的效率大大提高。DMA12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道),每个通道都支持软件触发和特定的硬件触发,对于STM32F103C8T6 DMA资源:DMA1(有7个通道)

  1.DMA框图

 

2.DMA基本结构

我们要想使用DMA了我们就需要按照如图所示进行dma的配置,也开始dma的初始化

  

 

 

 

3.DMA请求

  stm32f103c8t6DMA一共有7个通道,分配如下:

 

例如,我们想使用串口1的DMA进行数据接收和发送,了我们对于表上来看我们就是使用了dma的通道4和通道5.。如下所示

 

 

 

 

二、工作原理  

1,DMA 控制器

  1.DMA 操作通常由一个 DMA 控制器来协调。DMA 控制器是一个特殊的硬件芯片,它可以独立于 CPU 工作。
  2.当一个设备(如硬盘)需要进行数据传输时,它向 DMA 控制器发送请求。
  3.DMA 控制器接收到请求后,与 CPU 进行交互,获得对系统总线(包括数据总线、地址总线和控制总线)的控制权。

2.数据传输过程

  1. 首先,DMA 控制器根据设备的需求设置内存地址、传输字节数等参数。
  2. 然后,设备开始直接向内存写入数据(在数据输出的情况下,如硬盘向内存写入数据)或者从内存读取数据(在数据输入的情况下,如网络适配器从内存读取要发送的数据)。
  3. 在整个数据传输过程中,CPU 可以继续执行其他指令,只要这些指令不涉及正在被 DMA 传输所使用的内存区域。一旦数据传输完成,DMA 控制器会通知设备和 CPU 传输已经结束,然后释放系统总线的控制权。
  4. 例如当DMA使用串口进行数据接收时,不需要CPU的参与,CPU可以去干其他的事情。当数据接收完成后CPU就会通过串口中断设置一个标志位告诉CPU数据接收完成,然后CPU进行处理。就不需要CPU一直在这里等待数据接收完成之后去处理数据了。可以大大的提高CPU的利用率。

第二部分串口DMA+空闲中断实现不定长数据的收发

一、空闲中断

  1.基本概念

  在串口通信中,当串口接收完一帧数据后,如果在一段时间内没有新的数据接收,此时就会产生串口空闲中断。这个中断可以让微控制器或处理器在没有持续数据传输时被通知,以便进行相应的处理。如下图所示,当串口接收完一帧数据后,如果在一段时间内没有新的数据接收,此时就会产生串口空闲中断,在中断里面去通知CPU进行相应的数据处理。不需要cpu反复的进入中断查看数据是否接收完成,大大减小了cpu的负担。也实现了不定长数据包的接收提供了更好的方法。

  

2.工作原理

 

    1. 串口监测:串口持续监测接收线上的数据。
    2. 空闲判断:当串口在一段时间内未检测到任何数据的起始位时,就认为处于空闲状态。
    3. 中断触发:一旦判断为空闲状态,就会触发串口空闲中断信号,通知处理器进行相应的操作。

 

3.作用

  1数据帧识别 

    在接收数据时,可以通过串口空闲中断来确定一个完整的数据帧已经接收完毕。因为当连续的数据传输之间出现空闲状态时,很可能意味着一个数据帧的结束。

    例如,在接收多个长度不固定的数据帧时,利用串口空闲中断可以准确地识别出每个数据帧的边界,从而方便后续的数据处理。

   2.提高系统效率

    避免处理器持续查询串口状态,节省处理器资源。如果没有串口空闲中断,处理器可能需要不断地查询串口是否有新数据到来,这会消耗大量的处理器时间和能量。

    当有大量数据需要处理或者系统资源有限时,串口空闲中断可以显著提高系统的效率和响应速度

  3.异常检测

    可以检测到串口通信中的异常情况。例如,如果在预期的数据传输过程中出现了长时间的空闲,可能意味着通信出现了问题,如发送端故障、传输线路中断等。

    此时,处理器可以通过串口空闲中断及时发现问题,并采取相应的措施,如进行错误处理、重新建立连接等。

 

例:在我们想使用串口空闲中断时我们必须打开串口空闲中断,如果下图所示通过这个函数开启串口的空闲中断。

 

二,串口空闲中断加DMA实验

  1,首先我们要初始化相关的串口。我这里使用串口USATRT1。代码如下

  

上面我们进行了串口的相关初始化,并且打开了串口接收中断和串口空闲中断,接下来我们就应该配置DMA部分的初始化代码了。

 

2.DMA,这里我们通过查看DMA的通道确定了串口1使用的是DMA1的通道4和5,所以在这里我们相应配置DMA通道的4通道和5通道。如下所示

 到这里我们就已经配置好了串口加DMA的相关初始化部分,接下来就是配置相关串口接收中断和串口空闲中断的相关处理了

 

 

 如上图所示,我们可以看见我们这里有2个标志位获取函数。分别是1代表的是串口空闲中断的判断2是串口接收中断的判断。在这里我们需要注意一下在进入串口中断后,我们需要清除一下中断标志位,如4所示,如果我们是要想清除接收中断标志位或者发送中断标志位我们都需要使用USART_ClearITPendingBit()函数来进行标志位的清除。在这里注意一下如果是要想清除串口空闲中断的标志位哇就不可以使用USART_ClearITPendingBit()这个函数来进行清除在这里是无效的有,要想清除我们必须先读一下SR寄存器再读一下DR寄存器这样我们就清除了相应的串口的空闲中断标志位。

 

后面部分代码如下所示,在这里注意一下当我们发送完成后,我们需要使用memset(uart1RecvData, '\0', sizeof(uart1RecvData));清除一下接收缓冲区,使下一次数据是从第一位开始存下的,也防止数据溢出。

 

这部分的讲解就到这里了。大概讲解了一下,还有很多细节部分没有讲清楚。

 

 第三部分串口DMA中断实现数据收发

    上面我们已经讲解了DMA使用串口空闲中断实现不定长数据的收发,现在我们来讲解一下关于串口使用DMA中断实现定长数据的收发。

下面直接进行代码的讲解,在这里和上面有一些不一样,在使用DMA中断时,顾名思义我们使用的是DMA的中断,所以在这里我们就不需要配置串口的相关中断配置,只需要配置DMA部分的中断。

如上面所示,我们没有配置串口相关的中断,只是开启了DMA相关的中断配置。

 

 下面是DMA的中断处理函数

 

总结

总体而言,2部分相差不大,在配置方面一个是使用了串口的串口空闲中断进行数据的收发,一个是直接使用了DMA的发送和接收中断进行了数据的收发。一个是可以实现不定长数据的收发,一个不可以实现,差别就在这里。

 

posted @   小赵小赵0117  阅读(2235)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示