STM32 LL库 串口DMA发送接收配置教程

这篇具有很好参考价值的文章主要介绍了STM32 LL库 串口DMA发送接收配置教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在STM32开发中,串口是一种常见的通信方式。为了提高数据传输效率,我们可以利用STM32的DMA(Direct Memory Access)功能来实现串口的DMA发送和接收。在本篇文章中,我将详细介绍如何使用STM32的LL库进行串口DMA发送和接收的配置,并提供相应的代码示例。

STM32CubeMX配置

首先,我们需要打开STM32CubeMX软件进行配置。以下是配置步骤:

  1. 配置时钟树:根据您的具体型号(例如:STM32F407VGT6),将主频设置为168MHz。

  2. 串口配置:波特率采用默认的115200,不做修改。

  3. DMA配置:配置DMA发送和接收,可根据需求选择正常模式或循环模式。

  4. 开启中断:别忘了在配置中打开中断设置。

完成上述配置后,STM32CubeMX会自动生成相应的初始化代码。

代码初始化

在STM32CubeMX初始化完成后,我们可以开始进行发送和接收功能的配置。首先,我们需要封装一个函数用于初始化串口,例如`Debug_Init()`:

void Debug_Init(void) {
    MX_USART1_UART_Init(); // 硬件初始化
}

然后,在`Debug_Init()`函数中调用STM32CubeMX生成的初始化函数:

void Debug_Init(void) {
    MX_USART1_UART_Init(); // 硬件初始化
    
    // 配置串口方向,这里是发送和接收都要
    LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX);
    
    /* 接收配置 */
    // 使能空闲中断
    LL_USART_EnableIT_IDLE(USART1);
    // 设置内存地址,即接收数据的存放位置
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_2, (uint32_t)buf);
    // 设置接收最大数据长度
    LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_2, MAX_SIZE);
    // 设置外设地址,即串口数据寄存器的地址
    LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_2, (uint32_t)&USART1->DR);
    // 使能DMA2发送完成中断
    LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_2);
    // 使能接收的DMA2 STREAM_2
    LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
    // 使能DMA串口接收
    LL_USART_EnableDMAReq_RX(USART1);
    /* 发送配置 */
    // 设置外设地址,因为这个是DMA串口发送,
    LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_7, (uint32_t)&USART1->DR);
    // 使能DMA串口发送
    LL_USART_EnableDMAReq_TX(USART1);
    // 使能DMA2发送完成中断
    LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_7);
}

请注意,以上代码中的`DMA2`、`LL_DMA_STREAM_2`和`LL_DMA_STREAM_7`是根据STM32CubeMX的配置来设置的,移植时需修改为实际的配置。

以上配置完成后,我们可以编写相应的DMA串口发送和接收功能代码。

发送功能

串口发送功能很简单,由于我们在配置中已经设置了发送的外设固定为`USART1->DR`

所以我们只需要配置内存地址和数据长度,然后使能DMA Stream即可进行发送。以下是发送功能的代码示例:

void UART_DMA_Send(USART_TypeDef *USARTx, uint8_t *str, uint16_t size) {
    // 配置内存地址
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_7, (uint32_t)str);
    // 配置数据长度
    LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_7, size);
    // 使能DMA STREAM,即开始发送数据
    LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_7);
}

为什么要在发送函数中设置`LL_DMA_EnableStream`?

首先,让我们来看一下这个函数的定义:

__STATIC_INLINE void LL_DMA_EnableStream(DMA_TypeDef *DMAx, uint32_t Stream){
  SET_BIT(((DMA_Stream_TypeDef *)((uint32_t)((uint32_t)DMAx + STREAM_OFFSET_TAB[Stream])))->CR, DMA_SxCR_EN);
}

很明显,这个函数的作用是配置`DMA_SxCR_EN`,我们查阅参考手册可以得知,当`DMA_SxCR_EN=1`时,数据长度寄存器、外设地址寄存器和内存地址寄存器均为只读状态。因此,`LL_DMA_EnableStream()`函数仅在所有设置完成后使用,以便发送数据。

然而,又出现了一个新问题:我们在发送函数中设置了`DMA_SxCR_EN=1`,但它不会自动复位为0,那我们该如何处理呢?实际上,在配置发送时我们已经设置了DMA发送完成中断:

// 使能DMA2发送完成中断
LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_7);

因此,我们可以在中断处理函数中添加一个用于复位的函数,例如:

void DMA2_Stream7_IRQHandler(void) {
    if(LL_DMA_IsActiveFlag_TC7(DMA2)) {
        // 清除Stream7 TC中断
        LL_DMA_ClearFlag_TC7(DMA2);
        // 关闭DMA2 Stream7
        LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_7);
    }
}

其中,`LL_DMA_IsActiveFlag_TC7`中的`TC7`代表Stream7,所以请根据实际情况进行修改。

最后,我对发送功能进行了封装,方便调用:

int uart_printf(USART_TypeDef *USARTx, const char *fmt, ...) {
    va_list arg;
    int cnt;
    char buffer[FIFO_MAX_SIZE];
    va_start(arg, fmt);
    cnt = vsprintf(buffer, fmt, arg);
    va_end(arg);
    UART_DMA_Send(USARTx, (uint8_t*)buffer, strlen(buffer));
    return cnt;
}

接收功能

接收功能的代码示例如下:

void USART1_IRQHandler(void) {
    if (LL_USART_IsActiveFlag_IDLE(USART1)) {
        // 清除空闲中断
        LL_USART_ClearFlag_IDLE(USART1);
        // 获取接收数据的长度(剩余内存大小)
        rx_len = MAX_SIZE - LL_DMA_GetDataLength(DMA2, LL_DMA_STREAM_2);
    }
}

至此,我们完成了STM32 LL库的串口DMA发送和接收的配置。通过本教程,您学会了如何正确配置串口DMA,并实现高效的数据传输。希望这篇文章能对您在STM32开发中使用串口DMA有所帮助。

如果有任何问题,请随时提问。谢谢阅读!

关键词:STM32, LL库, 串口, DMA, 发送, 接收, 配置, 教程文章来源地址https://www.toymoban.com/news/detail-689631.html

到了这里,关于STM32 LL库 串口DMA发送接收配置教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GD32F4单片机实现接收超时中断+DMA实现串口的不定长接收和DMA发送

    环形缓冲区+定时器超时中断的方式 优点 环形缓冲区可以接收多帧数据 数据帧超时间隔可以设置 缺点 设备任务比较繁重时,使用中断接收可能会丢失数据。尤其是在长时间关闭中断或者串口中断优先级不高时 频繁进出中断。在使用RTOS的系统中,每收到一个数据就会进行一

    2024年02月15日
    浏览(52)
  • STM32实现DMA接收串口数据

    一..首先我们得配置DMA和USARAT,我们的原理是DMA1的通道5为USART1的RX引脚。  1.USART1的配置 2.DMA的配置 二.中断进行数据处理(stm32f10x_it.c) 我们可以串口打印出数组中的数据,验证DMA是否正常工作。可以到数据处理那个地方进行处理。USART1在初始化中就已经波特率为115200.我们可以

    2024年02月16日
    浏览(36)
  • STM32F4_HAL库_串口阻塞/中断/DMA三种方式发送数据的配置

    串口阻塞发送的意思就是,发送一段数据,在没有发送完所有数据之前,一直停留在此发送函数(可设定阻塞时间),这个过程中会阻塞别的程序运行; HAL库的配置分为两个层次,一个是HAL库内部调用的、与MCU硬件相关的初始化xxx_MspInit,一个是我们外部调用的初始化xxx_In

    2023年04月25日
    浏览(44)
  • STM32 串口 DMA 接收任意长度数据

    DMA 传输完成会产生中断告知 CPU,这对于固定长度的数据是没什么问题的。但是对于不定长的数据就不行了,DMA 一定要接收到足够多(设定的长度)的数据时才产生完成中断,如果接收到的数据量小于设定的长度,这个时候 CPU 就无法通过中断方式取处理这点数据了。那 CPU

    2024年02月11日
    浏览(37)
  • STM32 —— DMA 发送与接收数据详解

    DMA(Direct Memory Access) :直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU ,即在传输数据的时候,CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH DMA传

    2024年02月13日
    浏览(31)
  • 【STM32】CUBEMX之串口:串口三种模式(轮询模式、中断模式、DMA模式)的配置与使用示例 + 串口重定向 + 使用HAL扩展函数实现不定长数据接收

    目录   总览 使用CUBEMX创建工程的基本配置 CUBEMX中的配置 Keil中的配置 实物连接 串口轮询模式 轮询模式HAL库函数 特点 实验一:发送数据给单片机并让其返回相同值 串口重定向 串口中断模式 在CUBEMX中打开串口中断 中断模式HAL库函数 特点 实验二:使用中断回调完成实验一

    2024年04月10日
    浏览(44)
  • STM32-串口通信(串口的接收和发送)

    本文在于记录自己的学习过程中遇到的问题和总结,各种情况下串口通信在STM32的实际使用方面占有很大的比重,本文主要对 串口通信 做一个简要的总结。 在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输 并行数据 ,是 全双工 , 异步时钟控制 ,设备之间是

    2024年02月03日
    浏览(59)
  • STM-32:USART串口协议、串口外设—数据发送/数据发送+接收

    通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统。比如STM32芯片里面集成了很多功能模块,如定时器计数、PWM输出、AD采集等等,这些都是芯片内部的电路,它们的配置寄存器、数据寄存器都在芯片里面,操作简单,直接读写就行。但是有些功能STM32内部没有

    2024年02月04日
    浏览(47)
  • STM32 F4串口空闲中断 + DMA实现数据发送

    最近在做 STM32 + ROS车的项目,STM32与ROS之间通信由于数据量大,所以在 STM32端 使用 空闲中断 + DMA 的方案来减轻 CPU 的压力。 一、空闲中断 空闲中断 顾名思义为空了,闲了,没事了进的中断,在 没有数据流 的时候会进入进行读取。 在我们串口进行发送时实则为连续发送,两

    2024年02月16日
    浏览(53)
  • STM32串口通信—串口的接收和发送详解

    目录 前言: STM32串口通信基础知识: 1,STM32里的串口通信 2,串口的发送和接收 串口发送: 串口接收: 串口在STM32中的配置: 1. RCC开启USART、串口TX/RX所对应的GPIO口 2. 初始化GPIO口 3. 串口初始化 4. 串口使能 5. 串口发送数据 串口接收的两种实现方式: 1,轮询方式: 2,中断

    2024年04月08日
    浏览(95)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包