文档章节

stm32 HAL库 HAL_UART_Transmit_DMA 发送函数分析

vccw
 vccw
发布于 2016/11/13 03:24
字数 541
阅读 9.5K
收藏 0

请勿转载。谢谢。

###1.函数主体内容

HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  uint32_t *tmp;
  
  /* Check that a Tx process is not already ongoing */
  if(huart->gState == HAL_UART_STATE_READY)
  {
    if((pData == NULL ) || (Size == 0U))
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;

    /* Set the UART DMA transfer complete callback */
    huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;

    /* Set the UART DMA Half transfer complete callback */
    huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;

    /* Set the DMA error callback */
    huart->hdmatx->XferErrorCallback = UART_DMAError;

    /* Set the DMA abort callback */
    huart->hdmatx->XferAbortCallback = NULL;

    /* Enable the UART transmit DMA Stream */
    tmp = (uint32_t*)&pData;
    HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
    
    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
    
    /* Process Unlocked */
    __HAL_UNLOCK(huart);
    
    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

如上就是HAL_UART_Transmit_DMA 函数全部的代码。除去些初始化的代码,可以提炼到比较重要的代码如下

设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道

HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);

清除串口 TC 中断 FLAG

__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

使能发送

SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

2.调用HAL_DMA_Start_IT

设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道 函数内容如下

HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* calculate DMA base and stream number */
  DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
  
  /* Check the parameters */
  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
 
  /* Process locked */
  __HAL_LOCK(hdma);
  
  if(HAL_DMA_STATE_READY == hdma->State)
  {
    /* Change DMA peripheral state */
    hdma->State = HAL_DMA_STATE_BUSY;
    
    /* Initialize the error code */
    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
    
    /* Configure the source, destination address and the data length */
    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
    
    /* Clear all interrupt flags at correct offset within the register */
    regs->IFCR = 0x3FU << hdma->StreamIndex;
    
    /* Enable Common interrupts*/
    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
    hdma->Instance->FCR |= DMA_IT_FE;
    
    if(hdma->XferHalfCpltCallback != NULL)
    {
      hdma->Instance->CR  |= DMA_IT_HT;
    }
    
    /* Enable the Peripheral */

__HAL_DMA_ENABLE(hdma);

  }
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdma);	  
    
    /* Return error status */
    status = HAL_BUSY;
  }
  
  return status;
}

设置memory 到 periphery 地址

DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);

打开中断

    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
    hdma->Instance->FCR |= DMA_IT_FE;

开启通道

__HAL_DMA_ENABLE(hdma);

关于开启通道的的这个marco 可以在这条语句中得到解答

#define __HAL_DMA_ENABLE(__HANDLE__)      ((__HANDLE__)->Instance->CR |=  DMA_SxCR_EN)

###3.结尾 那么HAL_UART_Transmit_DMA 函数主要做的事情顺序如下

  • 设置memory 到 periphery 的地址,并且开启中断 并使能DMA通道
  • 清除串口 TC 中断 FLAG
  • 使能发送

© 著作权归作者所有

vccw

vccw

粉丝 2
博文 1
码字总数 541
作品 0
武汉
程序员
私信 提问
加载中

评论(0)

STM32 之 HAL 库串口(USART/UART)驱动 BUG 及解决方法

版权声明:进步始于交流,收获源于分享!转载请保留原文出处,谢谢! https://blog.csdn.net/ZCShouCSDN/article/details/84768101 问题 在使用HAL库的串口部分时,发现了有以下6个比较严重B...

ZCShouCSDN
2018/12/03
0
0
STM32 HAL库 回调函数总结

普通函数与回调函数的区别:就是ST将中断封装,给使用者的API,就是标准库的中断函数 对普通函数的调用: 调用程序发出对普通函数的调用后,程序执行立即转向被调用函数执行,直到被调用函数...

super828
2018/01/21
0
0
STM32之HAL库详解 及 手动移植

HAL库结构   说到STM32的HAL库,就不得不提STM32CubeMX,其作为一个可视化的配置工具,对于开发者来说,确实大大节省了开发时间。STM32CubeMX就是以HAL库为基础的,且目前仅支持HAL库!首先...

ZCShouCSDN
2017/02/15
0
0
stm32f1xx HAL库下载介绍

1、下载 想要下载STM32F1的HAL库的朋友可以去官网下载,不过需要注册账户,当然也可以去STM32论坛中下载。 2、目录结构介绍 解压下载好的en.stm32cubef1.zip,解压好的目录结构如下图所示: ...

也许现在将来
03/31
0
0
AliOS Things标准输入输出端口对接以及修改方法

1 标准输入输出端口对接 标准输入输出用于输出系统日志、打印异常信息、软件调试、CLI交互等场景。在具体项目中,只需要对接PUTCHARPROTOTYPE和GETCHARPROTOTYPE两个函数即可。其具体定义如下...

jason_sophia
2018/08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

嵌套滑动通用解决方案--NestedScrollingParent2

文章目录 一、问题及解决方案 二、NestedScrollingParent2LayoutImpl3的实现原理 2.1 先来回顾下嵌套滑动机制。 2.2 再来看看NestedScrollView嵌套RecyclerView 2.3 NestedScrollingParent2...

osc_mgvk29y5
6分钟前
4
0
概率分布

二项分布 # 1次试验中,成功的次数np.random.binomial(1, 0.5)# 1000次试验中,成功的次数print('1000次试验中,成功的次数: ', np.random.binomial(1000, 0.5))# 1000次试验中,...

JosiahMg
7分钟前
13
0
学军信友队趣味网络邀请赛 b题 齐心抗疫(树的直径)

题目描述 对于所有数据,满足2<=n<=50000,1<=a[i]<=1000。 题目思路 前言 本来我以为是最短路什么的。。。结果是我太菜,个人认为此题还是补充了自己知识,学到了不少 知识 树的直径表示最长...

osc_uj3h5gt9
7分钟前
8
0
安卓svc命令使用总结

使用环境: 在无屏幕状态下想要控制Wi-Fi、电源、数据流量、usb、nfc。 命令简介: 通过adb shell 进入交互页面,输入svc显示下图说明 下面就每个命令做相应的使用说明: 1、power 在shell环...

osc_zitca8hu
8分钟前
16
0
切换页面取消请求

在axios的封装文件中添加 import axios from 'axios'let router = import("@/router");let source = axios.CancelToken.source();const baseURL = process.env.VUE_APP_MODE == 'develo......

osc_3ytpwpyb
9分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部