STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制 STM32 HAL 库实现乒乓缓存加空闲中断的串口 DMA 收发机制,轻松跑上 2M 波特率。 STM32 中一般的 DMA 传输方向有内存->内存、外设->内存、内存->外设。通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),在嵌入式开发中一般称为串口,通常用于中、低速通信场景,波特率低有 6400 bps,高能达到 4~5 Mbps。 在 STM32 中使用 DMA 收发数据,可以节约可观的 CPU 处理时间。特别是在高速、大数据量的场景中,DMA 是必须的,而双缓冲区、空闲中断以及 FIFO 数据缓冲区也是非常重要的成分。 在本文中,我们将使用 STM32CubeMX 配置串口,首先使能高速外部时钟,然后设置时钟树。接下来配置串口,选择一个串口,设置模式为 Asynchronous,设置波特率、帧长度、奇偶校验以及停止位长度。然后添加接收和发送的 DMA 配置,注意在 RX 中将 DMA 模式改为 Circular,这样 DMA 接收只用开启一次,缓冲区满后 DMA 会自动重置到缓冲区起始位置,不再需要每次接收完成后重新开启 DMA。 在串口收到数据之后,DMA 会逐字节搬运到 RX_Buf 中。当搬运到一定的数量时,就会产生中断(空闲中断、半满中断、全满中断),程序会进入回调函数以处理数据。全满中断和半满中断都很好理解,就是串口 DMA 的缓冲区填充了一半和填满时产生的中断。而空闲中断是串口在上一帧数据接收完成之后在一个字节的时间内没有接收到数据时产生的中断,即总线进入了空闲状态。 现在网络上大部分教程都使用了全满中断加空闲中断的方式来接收数据,不过这存在了一定的风险:DMA 可以独立于 CPU 传输数据,这意味着 CPU 和 DMA 有可能同时访问缓冲区,导致 CPU 处理其中的数据到中途时 DMA 继续传输数据把之前的缓冲区覆盖掉,造成了数据丢失。所以更合理的做法是借助半满中断实现乒乓缓存。 乒乓缓存是指一个缓存写入数据时,设备从另一个缓存读取数据进行处理;数据写入完成后,两边交换缓存,再分别写入和读取数据。这样给设备留足了处理数据的时间,避免缓冲区中旧数据还没读取完又被新数据覆盖掉的情况。 但是出现了一个小问题,就是 STM32 大部分型号的串口 DMA 只有一个缓冲区,要怎么实现乒乓缓存呢?没错,半满中断。现在,一个缓冲区能拆成两个来用了。看这图我们再来理解一下上面提到的三个中断:接受缓冲区的前半段填满后触发半满中断,后半段填满后触发全满中断;而这两个中断都没有触发,但是数据包已经结束且后续没有数据时,触发空闲中断。 举个例子:向这个缓冲区大小为 20 的程序传送一个大小为 25 的数据包,它会产生三次中断,如下图所示。程序实现原理介绍完成,感谢 ST 提供了 HAL 库,接下来再使用 C 语言实现它们就很简单了。首先开启串口 DMA 接收。 #define RX_BUF_SIZE 20 uint8_t USAR_RX_Buf[RX_BUF_SIZE]; 在上面的例子中,我们定义了一个大小为 20 的缓冲区 USAR_RX_Buf,並将其设置为串口 DMA 的接收缓冲区。然后,我们可以使用 HAL 库提供的函数来开启串口 DMA 接收。 HAL_UART_Receive_DMA(&huart1, USAR_RX_Buf, RX_BUF_SIZE); 在串口收到数据之后,DMA 会逐字节搬运到 RX_Buf 中。当搬运到一定的数量时,就会产生中断(空闲中断、半满中断、全满中断),程序会进入回调函数以处理数据。在回调函数中,我们可以将数据写入 FIFO 中供应用读取。 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 将数据写入 FIFO 中 FIFO_Put(USAR_RX_Buf, RX_BUF_SIZE); } 在上面的例子中,我们使用 HAL 库提供的回调函数 HAL_UART_RxCpltCallback 来处理数据。在这个函数中,我们将数据写入 FIFO 中供应用读取。这样,我们就可以轻松地实现高速的串口收发机制。 使用 STM32 HAL 库可以轻松地实现高速的串口收发机制,轻松跑上 2M 波特率。同时,我们还可以使用乒乓缓存和空闲中断来避免数据丢失和提高系统的可靠性。
2025-04-04 19:14:28 1.22MB stm32
1
2M传输介绍以及案例
2022-11-09 14:16:18 51KB 2M传输介绍以及案例
1
基站建设与维护
2022-10-31 09:05:52 7.12MB 基站建设 基站 5G
通信网络2M接口介绍
2022-10-24 13:07:15 439KB 通信网络2M接口介绍
1
cpu s905l3a和 a-b 内存2+8,e900v22c 刷机前确认盒子cpu是s905l3a-b s905L3A b863av3.2m(江苏版) e900v22d(江苏版) e900v22c(广东版)
2022-07-31 14:03:58 101B 机顶盒
1
MAC地址在1E0000位置,PIN码在1E0010位置,使用WinHex软件搜索到修改后保存即可,此编程器固件用在MW150R_V8.4(2M flash)路由器上亲测可以使用。
2022-06-03 00:46:38 2MB 路由器 MW155R AR9331 2Mflash
1
host端FFT的IPC通信,开辟CMEM192M空间的2M空间为共享内存,2M空间分成四个512K分区。 1、App.c和App.h 2、AppCommon.h 3、cmem.c和cmem.h
2022-05-04 21:01:17 23KB FFT IPC 核间通信 messageQ
1
本文所介绍的误码测试系统采用以大规模现场可编程逻辑器件FPGA及外围接口芯片构成,文中详细介绍了系统硬件架构中EI接口电路以及FPGA内核中序列发生模块和序列接收模块中核心内容的设计方法,并给出了部分模块的仿真波形。
2022-03-17 13:43:23 1.29MB FPGA 2M误码测试仪 传输系统 文章
1
很小的矢量字体文件,不到2M的大小。很适合在arm上配合QT来使用。 字体是腾翔睿黑简,在显示屏上看起来也很舒服,有点方正的感觉,但是也不完全是。
2022-02-11 14:09:38 1.91MB arm 2M 矢量字体
1
本软件用于提取大小为2M的 TP-link/水星/迅捷的Vwroks固件中的EEPROM(无线校准文件)、ART 文件,并且补全为64KB,用以备份和用不死Uboot或者breed刷入。
2021-10-29 16:48:44 241KB ART/EEPROM 提取
1