STM32CUBEMX(2)--USART通过DMA方式接收不定长数据

发布者:科技先锋最新更新时间:2025-10-15 来源: bilibili关键字:STM32CUBEMX  USART  DMA方式  不定长数据 手机看文章 扫描二维码
随时随地手机看文章

概述

    直接存储器访问(DMA)用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何CPU操作的情况下通过DMA快速传输传输。这样节省的CPU资源可供其它操作使用。

    DMA允许在后台执行数据传输,无需Cortex-MO处理器干预。在此操作过程中,主处理器可以执行其它任务,仅当整个数据块需要处理时,才会中断主处理器。这样即使传输大量数据也不会对系统性能造成太大影响。

    DMA主要用于为不同的外设模块实现集中数据缓冲存储(通常在系统SRAM中)。与分布式解决方案(其中每个外设都需要实现自己的本地数据存储)相比,DMA解决方案在硅片成本和功耗方面的成本较低。

    根据使用的产品型号的不同,有一个或两个DMA模块。

    STM32F0XX DMA控制器总共有5个通道用于DMA1,每个通道都专门管理来自一个或多个外设的存储器访问请求。它具有一个仲裁器,用于处理不同的DMA请求的优先级。

    本篇文章主要介绍如何使用STM32CubeMX实现串口DMA读取,并且打印出去。

硬件准备

    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:

选择芯片型号

    使用STM32CUBEMX选择芯片stm32f030r8,如下所示:

配置时钟源

   HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:

配置时钟树

    STM32F0的最高主频到48M,所以配置48即可:

串口配置

    本次实验使用的串口1进行串口通信,波特率配置为115200。

    配置DMA

    中断

生成工程设置

代码生成设置

最后设置生成独立的初始化文件:

生成代码

配置keil

代码

    在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。


/* USER CODE BEGIN Includes */


#include "stdio.h"


/* USER CODE END Includes */


/* USER CODE BEGIN Includes */

#include 'stdio.h'

/* USER CODE END Includes */

    变量定义:


/* USER CODE BEGIN PV */

#define BUFFERSIZE 255           //可以接收的最大字符个数

uint8_t ReceiveBuff[BUFFERSIZE]; //接收缓冲区

uint8_t recv_end_flag = 0,Rx_len;//接收完成中断标志,接收到字符长度

/* USER CODE END PV */

    函数声明和串口重定向:


/* USER CODE BEGIN PFP */

void uart1_data(void); //接收函数

#ifdef __GNUC__ //串口重定向

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif

PUTCHAR_PROTOTYPE

{

    HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);

    return ch;

}

/* USER CODE END PFP */

    开启串口IDLE中断:


/* USER CODE BEGIN 2 */

printf('串口1DMA例程rn');

  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能串口1 IDLE中断

  /* USER CODE END 2 */

    主循环:


/* USER CODE BEGIN WHILE */

  while (1)

  {

    /* USER CODE END WHILE */

uart1_data();//串口数据处理

    /* USER CODE BEGIN 3 */

  }

  /* USER CODE END 3 */

    串口DMA获取:


/* USER CODE BEGIN 4 */

void uart1_data(void)

{

if(recv_end_flag ==1)//接收完成标志

{

printf('数据长度=%drn',Rx_len);//打印接收到的数据长度

printf('数据内容:');

for(int i=0;i < Rx_len;i++)

{

printf('%c',ReceiveBuff[i]);//向串口打印接收到的数据

            }

    printf('rn');

    for(int i = 0; i < Rx_len ; i++) //清空接收缓存区

    ReceiveBuff[i]=0;//置0

    Rx_len=0;//接收数据长度清零

    recv_end_flag=0;//接收标志位清零

    }

    //开启下一次接收

    HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);

}

/* USER CODE END 4 */

    #include "stm32f0xx_it.c"文件中断外部变量引用:


/* USER CODE BEGIN 0 */

#define BUFFERSIZE 255 //可接收的最大数据

extern uint8_t recv_end_flag,Rx_len,bootfirst;

/* USER CODE END 0 */

    串口1中断函数:


/**

  * @brief This function handles USART1 global interrupt.

  */

void USART1_IRQHandler(void)

{

  /* USER CODE BEGIN USART1_IRQn 0 */


  /* USER CODE END USART1_IRQn 0 */

  HAL_UART_IRQHandler(&huart1);

  /* USER CODE BEGIN USART1_IRQn 1 */

uint32_t temp;

if(USART1 == huart1.Instance)//判断是否为串口1中断


{

if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))//如果为串口1

{

__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除中断标志

      HAL_UART_DMAStop(&huart1);//停止DMA接收

      temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//获取DMA当前还有多少未填充

      Rx_len =  BUFFERSIZE - temp; //计算串口接收到的数据个数

      recv_end_flag = 1;

    }

        }

  /* USER CODE END USART1_IRQn 1 */

}


演示效果


关键字:STM32CUBEMX  USART  DMA方式  不定长数据 引用地址: STM32CUBEMX(2)--USART通过DMA方式接收不定长数据

上一篇:STM32CUBEMX生成freeRTOS代码的时候出现警告
下一篇:STM32实现LED闪烁、流水灯与蜂鸣器功能详解教程

推荐阅读最新更新时间:2026-03-20 20:33

STM32CubeMX:UART(DMA空闲方式
UART传输有三种方式,而DMA的应用采用阻塞式接收指定的数据长度,效率较低,而应用DMA空闲方式可提高其效率。 参考帖子:http://blog.csdn.net/youmeichifan/article/details/51750435 帖子中应用参考,其中修改了几个内容: 1.空闲中断为连续接收; 2.去除发送完成回调函数HAL_UART_TxCpltCallback,而在发送函数中,等待huart的发送状态位。 DMA方式在连续发送数据应用当中,会产生丢失,所以在发送前需检查发送状态。
[单片机]
[STM32CubeMX]学习笔记4:printf( )重定向到USART串口输出
TIPS:作为一只新手,从标准库转到HAL库确实很不习惯,这个程序配置很简单但是代码也是纠结了很久,最终参考了官方的USART_Printf例程,下载见:STM32Cube官方例程学习指南。 MCU:STM32F103ZET6 IDE: MDK-ARM V5 +STM32CubeMX5.0.0 串口调试助手:SSCOM3.2 功能描述:USART1收到PC机发来的数据后原封不动的返回给PC机显示,但是C语言中printf函数默认输出设备是显示器,要使用printf输出到串口,需要将fputc里面的输出指向串口,这一过程就叫重定向。 需要配置的只有USART1,配置过程非常简单。 一. 在 Pinout&Co
[单片机]
[<font color='red'>STM32CubeMX</font>]学习笔记4:printf( )重定向到<font color='red'>USART</font>串口输出
STM32CubeMX学习教程之六:USART串口输出和printf( )重定向到串口
软件: STM32CubeMX V4.25.0 System Workbench V2.4 固件库版本: STM32Cube FW_F1 V1.6.1 硬件: OneNet 麒麟座V2.3 在STM32CubeMX中新建项目,选择正确的MCU型号 首先设置RCC和SYS,如下图 然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图 配置USART1为Asychronous模式 可以看到PA9和PA10被配置为了USART1_TX, USART1_RX。 UART1配置用默认的115200,8, None和1就好。 Project -
[单片机]
<font color='red'>STM32CubeMX</font>学习教程之六:<font color='red'>USART</font>串口输出和printf( )重定向到串口
STM32CubeMX学习教程之六:USART串口输出和printf( )重定向到串口
软件: STM32CubeMX V4.25.0 System Workbench V2.4 固件库版本: STM32Cube FW_F1 V1.6.1 硬件: OneNet 麒麟座V2.3 在STM32CubeMX中新建项目,选择正确的MCU型号 首先设置RCC和SYS,如下图 然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图 配置USART1为Asychronous模式 可以看到PA9和PA10被配置为了USART1_TX, USART1_RX。 UART1配置用默认的115200,8, None和1就好。
[单片机]
<font color='red'>STM32CubeMX</font>学习教程之六:<font color='red'>USART</font>串口输出和printf( )重定向到串口
STM32CubeMX生成USART+DMA程序
测试时参照以上链接进行测试的,经测试以上链接的方法完全没问题,测试结果如下: 同时验证了都使用USART都使用DMA进行发送接收的情况,无异常发生,现象同上
[单片机]
<font color='red'>STM32CubeMX</font>生成<font color='red'>USART</font>+<font color='red'>DMA</font>程序
STM32CubeMX软件工程描述_USART配置过程
Ⅰ、写在前面 学习本文之前可以查看我前面的文章: STM32CubeMX介绍、下载与安装 STM32CubeMX使用方法及功能介绍 STM32CubeMX新建工程+基本IO配置过程 本文接着前面 STM32CubeMX 文章结合USART实例,讲述关于STM32CubeMX新建USART工程,以及新建好完成的软件工程。最终通过STM32CubeMX工具配置完成实现USART串口通信的软件工程。 本文使用 Keil(MDK-ARM) V5 软件为编译环境,如果你没有安装最新版本的软件,请安装Keil(MDK-ARM) V5版本的软件,具体过程可以参考我的一篇文章: MDK-ARM下载与安装 关于本文的更多详情
[单片机]
<font color='red'>STM32CubeMX</font>软件工程描述_<font color='red'>USART</font>配置过程
STM32F0使用LL库实现DMA方式AD采集
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。在本文中我们将介绍基于LL库的ADC的DMA采集方式。 1、概述 这次我们使用DMA方式实现对AD的采集,在遗忘我们使用HAL库和标准库都做过,这次我们使用LL库来实现。接下来我们简单了解一下STM32F030F4中的ADC和DMA。 首先看一看ADC,STM32F030F4是12位的ADC。它有多达19个多路复用通道,允许它测量来自16个外部和2个内部源的信号。各种通道的A/D转换可采用单通道、连续通道、扫描通道或不连续通道进行。ADC的结果存储在左对齐或右对齐的1
[单片机]
STM32笔记--ADC(DMA方式)
在上一次的博客中重新学习了DMA,这次我们便学以致用了,ADC的概念想必大家都是十分清楚了,模拟转数字,可以用在测信号,测电压,在我们的生活中有着十分巨大的作用,这次我们就来看看ADC又有哪些操作吧! ADC流程,首先ADC采集一个信号(信号范围大都为0-3.3V,ps:3.3V可通过更改Vref寄存器修改),每隔相同时间菜一次数值发送到一个可变16位数中,下面是我们的数组定义: __IO uint16_t ADC_ConvertedValue; //定义该16位数用来传输数据,原因是我们使用的12位AD,由于寄存器的定义方便,因此使用16位数 下面是ADC的初始化和配置代码: void ADC1_Init(void
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved