文档章节

stm32 HAL库 HAL_UART_Transmit_DMA 发送函数分析

vccw
 vccw
发布于 2016/11/13 03:24
字数 541
阅读 2162
收藏 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
粉丝 2
博文 1
码字总数 541
作品 0
武汉
程序员
私信 提问
STM32 HAL库 回调函数总结

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

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

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

ZCShouCSDN
2017/02/15
0
0
AliOS Things标准输入输出端口对接以及修改方法

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

jason_sophia
08/09
0
0
STM32时钟配置与SysTick配置_基于STM32F103

【一】前言 STM32前后台程序编程时,最基本的配置应当是对其时钟和系统定时器的配置,对标准库而言,调用SysTickInit ();。如果采用HAL库,首先还应该调用HALInit();初始化HAL库。 此处采用标...

u010834669
05/05
0
0
最新HAL库 CUBEMX 的CAN总线配置接收发送(STM32F412)

STM32F412 精简版本 功能完整。 来说一下CAN外设的配置以及收发。 HAL库发展到现在BUG越来越少,大大减少了用户的开发量,但是缺点明显,代码量庞大。效率不高。 配置CAN总线首先要明确APB1的...

qubozhan4751
04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ios多个target

1.建立3个target,分别为heroone,heroone test,heroone dev;分别为正式环境,test环境,dev环境 2.注意取消掉autocreate以防止名字不对,分别以Duplicate的方式建立另外两个scheme 3.创建...

HeroHY
今天
5
0
php获取客户端IP

php获取客户端IP 首先先阅读关于IP真实性安全的文章:如何正確的取得使用者 IP? 「任何從客戶端取得的資料都是不可信任的!」 HTTP_CLIENT_IP头是有的,但未成标准,不一定服务器都实现。 ...

DrChenXX
昨天
0
0
. The valid characters are defined in RFC 7230 and RFC 问题

通过这里的回答,我们可以知道: Tomcat在 7.0.73, 8.0.39, 8.5.7 版本后,添加了对于http头的验证。 具体来说,就是添加了些规则去限制HTTP头的规范性 参考这里 具体来说: org.apache.tom...

west_coast
昨天
1
0
刷leetcode第704题-二分查找

今天双十一买的算法书到货了,路上刷到有人说的这个题,借(chao)鉴(xi)一下别人的思路,这个是C++标准库里面的经典方法,思路精巧,优雅好品味 int search(int* nums, int numsSize, in...

锟斤拷烫烫烫
昨天
3
0
【分享实录】BANCOR算法详解及代码实现

1 活动基本信息 1)主题:【区块链技术工坊22期】BANCOR算法详解及代码实现 2)议题: BANCOR算法的特点和优劣势 BANCOR算法和举例 如何加入BANCOR.NETWORK交易所 如何开发自己的BANCOR去中心...

HiBlock
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部