stm32串口HAL库的DMA发送问题

2023-05-16

本文使用stm32f411ret的串口1的DMA方式发送数据,刚开始调试的时候发现串口只能发送一次数据,之后就把系统hang住了。通过网上搜资料和不断尝试,发现问题是中断回调函数没有写的原因。

使用HAL库的DMA,需要同时实现DMA中断回调函数串口中断回调函数。

void DMA2_Stream7_IRQHandler(void)
{
    HAL_DMA_IRQHandler(Uart1Handle.hdmatx);
}

void USART1_IRQHandler(void)
{
  HAL_NVIC_ClearPendingIRQ(USART1_IRQn);
  HAL_UART_IRQHandler(&Uart1Handle);
}

下面附上我的dma配置和串口配置函数

dma配置

void HAL_UART1_dma_Init(void)
{
  static DMA_HandleTypeDef hdma_tx;

  __HAL_RCC_DMA2_CLK_ENABLE();                //打开DMA2时钟
  /*##-3- Configure the DMA streams ##########################################*/
  /* Configure the DMA handler for Transmission process */
  hdma_tx.Instance                 = DMA2_Stream7;      
  hdma_tx.Init.Channel             = DMA_CHANNEL_4;        //串口1发送属于stream7、channel4,可在参考手册的DMA章节查到
  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;    //数据发送方向:内存->外设
  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;        //外设为串口,地址不需要增加
  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;        //存储需要增加
  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //串口为字节
  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;    //与串口设置要一致
  hdma_tx.Init.Mode                = DMA_NORMAL;              //一次发送,如果设置为循环模式,会一直不停的发 
  hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;        //低优先级
  hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;    
  hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
  hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
  
  HAL_DMA_Init(&hdma_tx);   
  
  /* Associate the initialized DMA handle to the the UART handle */
  __HAL_LINKDMA(&Uart1Handle, hdmatx, hdma_tx);            //将dma的发送handle赋值给串口1的hdmatx成员
  /*##-4- Configure the NVIC for DMA #########################################*/
  /* NVIC configuration for DMA transfer complete interrupt (USARTx_TX) */
  HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 1);           //设置dma中断优先级
  HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);                   //使能dma中断
}

串口引脚配置

void Init_Usart1(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
  
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();  
  /* Enable USARTx clock */
   __HAL_RCC_USART1_CLK_ENABLE();
  
  /*##-2- Configure peripheral GPIO ##########################################*/  
  /* UART TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = GPIO_PIN_9;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
  /* UART RX GPIO pin configuration  */
  GPIO_InitStruct.Pin = GPIO_PIN_10;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
    
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	HAL_NVIC_SetPriority(USART1_IRQn,0,0);
	HAL_NVIC_EnableIRQ(USART1_IRQn);				
	
}

串口配置

void Usart1_Configuration(uint32_t BaudRate)
{								   
  Uart1Handle.Instance          = USART1;
  
  Uart1Handle.Init.BaudRate     = BaudRate;
  Uart1Handle.Init.WordLength   = UART_WORDLENGTH_8B;
  Uart1Handle.Init.StopBits     = UART_STOPBITS_1;
  Uart1Handle.Init.Parity       = UART_PARITY_NONE;
  Uart1Handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  Uart1Handle.Init.Mode         = UART_MODE_TX_RX;
  Uart1Handle.Init.OverSampling = UART_OVERSAMPLING_16;
    
  if(HAL_UART_Init(&Uart1Handle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler(); 
  }	
    
}

发送数据调用下面的函数即可

HAL_UART_Transmit_DMA(&Uart1Handle, (uint8_t*)aTxBuffer, 32)

实际操作时可以在串口中断中设置一个标志位,用来标记串口发送完成,在主程序中用标志位控制对发送函数的调用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32串口HAL库的DMA发送问题 的相关文章

随机推荐

  • 跌倒检测和识别1:跌倒检测数据集(含下载链接)

    跌倒检测和识别1 xff1a 跌倒检测数据集 含下载链接 目录 跌倒检测和识别1 xff1a 跌倒检测数据集 含下载链接 1 前言 2 跌倒姿态 xff1a 站立 弯腰 蹲下 躺下 3 跌倒检测数据集 xff1a xff08 1 xff09
  • 跌倒检测和识别2:YOLOv5实现跌倒检测(含跌倒检测数据集和训练代码)

    跌倒检测和识别2 xff1a YOLOv5实现跌倒检测 含跌倒检测数据集和训练代码 目录 跌倒检测和识别2 xff1a YOLOv5实现跌倒检测 含跌倒检测数据集和训练代码 1 前言 2 跌倒检测数据集说明 xff08 1 xff09 跌倒
  • 跌倒检测和识别3:Android实现跌倒检测(含源码,可实时跌倒检测)

    跌倒检测和识别3 xff1a Android实现跌倒检测 含源码 xff0c 可实时跌倒检测 目录 跌倒检测和识别3 xff1a Android实现跌倒检测 含源码 xff0c 可实时跌倒检测 1 前言 2 跌倒检测数据集说明 3 基于YO
  • 跌倒检测和识别4:C++实现跌倒检测(含源码,可实时跌倒检测)

    跌倒检测和识别4 xff1a C 43 43 实现跌倒检测 含源码 xff0c 可实时跌倒检测 目录 跌倒检测和识别4 xff1a C 43 43 实现跌倒检测 含源码 xff0c 可实时跌倒检测 1 前言 2 跌倒检测模型 xff08 Y
  • 接口测试工具:Postman

    无论是接口调试还是接口测试 xff0c postman都算的上很优秀的工具 xff0c 好多接口测试平台 接口测试工具框架的设计也都能看到postman的影子 xff0c 我们真正了解了这款工具 xff0c 才可以在这个基础上进行自己的设计
  • ROS实验笔记之——move_base_simple/goal

    本博文打算通过节点发布导航的坐标让机器人自动移动到目标点 通过自定义节点来实现导航功能 nbsp 目录 创建仿真环境 编写导航发布者 move base msgs MoveBaseActionGoal Message 实现代码 参考资料 n
  • ROS实验笔记之——自主搭建四旋翼无人机

    最近搭建了一台小的四旋翼无人机 xff0c 本博文记录一下搭建的过程以及一些问题 请问我博客就记录了自己做实验的搭建的飞机有什么问题 xff1f xff1f xff1f 目录 组装 飞行前准备 试飞 组装 首先是一系列的散装原件 到最后搭建
  • ROS实验笔记之——基于l515激光相机的FLVIS与MLMapping

    之前博客 ROS实验笔记之 VINS Mono在l515上的实现 在l515上实现了vins xff0c 博客 ROS实验笔记之 SLAM无人驾驶初入门 配置flvis并跑了对应的kitti数据集 本博文在l515上先实现flvis然后再用
  • Chapter 2. ROS 创建和编译功能包

    1 创建ROS功能包 使用catkin create pkg命令来创建一个新的catkin程序包 首先切换到之前通过创建catkin工作空间教程创建的catkin工作空间中的src目录下 xff1a ros workspace span c
  • linux ulimit命令用法解析

    以下内容转载自 xff1a http www linuxidc com Linux 2012 10 72782 htm Linux对于每个用户 xff0c 系统限制其最大进程数 为提高性能 xff0c 可以根据设备资源情况 xff0c 设置
  • 机体坐标系的角速度分量

    一 角速度分量 机体坐标系的三个角速度分量 xff0c 是机体坐标系相对于地面坐标系的转动角速度在机体坐标系各轴上的分量 其中 xff1a 角速度 xff50 xff0c 与机体轴 xff58 重合一致 xff1b 角速度 xff51 xf
  • 使用Realsense测试aruco_ros包

    01 准备工作 安装realsense ros安装aruco ros span class token builtin class name cd span ur ws src span class token function git s
  • DIY遥控船(一):电调和舵机的驱动[使用STC89C52]

    在动力模型中 xff0c 有两样东西是最基本 最必要的 xff0c 即舵机和无刷电机 舵机提供转动特定角度的功能 xff0c 而无刷电机需要由电调 xff0d xff0d 电子调速器驱动 舵机 舵机又叫伺服电机 xff0c 可以按照输入的指
  • GD32VF103之CRC

    在GD32VF103内部有一个CRC 循环冗余校验计算单元 xff0c 使用它可以对数据的完整性和正确性进行校验 xff0c 比如固件的完整性和正确性校验 通信数据的校验等 它使用固定的32位多项式 xff1a 0x4C11DB7 xff1
  • GD32VF103之GPIO最小配置

    longan nano是Sipeed xff08 矽速科技 xff09 推出的开发板 xff0c 使用兆易创新的gd32vf103cbt6芯片 xff0c 该芯片是基于芯来科技的Nuclei Bumblebee处理器的32位通用微控制器 x
  • Linux控制I2C/SMBus设备

    平台 xff1a 树莓派 bcm2835 Raspberry Pi 3 Model B Rev 1 2 I2C是Philips开发的一种两线通信协议 xff0c 常用于一些对速度要求不高的小型器件上 SMBus是系统管理总线 xff0c 基
  • ArduPilot/APM源码学习笔记(一)

    最近开始学习ArduPilot APM飞控的源码 xff0c 源码托管在github上 源码链接 xff1a https github com diydrones ardupilot 飞控主页 xff1a http ardupilot co
  • GRUB2引导修复

    本来是想把GRUB2装到U盘 xff0c 却不小心把电脑的GRUB搞坏了 原因可能是我执行命令grub install时没有加任何参数 xff0c 由于不知道没有参数怎么执行 xff0c 我赶紧ctrl 43 c终止了安装 xff0c 最后
  • ardupilot的libraries之PID

    在源码的libraries中 xff0c 有两个关于PID的源文件文件夹 xff0c 一个叫AC PID xff0c 另一个是PID AC PID中又细分为AC HELI PID AC P和AC PID xff0c 这里我们只讨论AC PI
  • stm32串口HAL库的DMA发送问题

    本文使用stm32f411ret的串口1的DMA方式发送数据 xff0c 刚开始调试的时候发现串口只能发送一次数据 xff0c 之后就把系统hang住了 通过网上搜资料和不断尝试 xff0c 发现问题是中断回调函数没有写的原因 使用HAL库