Day2 STM32之DMA通信

1 DMA介绍

        DMA(Direct Memory Accesse,直接内存访问)是一种数据通信技术

        允许数据无需借助CPU,直接开辟内存和外设通道进行数据传输

        提高数据传输效率,减负CPU

        外设发送请求,DMA收到请求给外设返回ack应答信号

        外设收到ack后释放请求,启动DMA数据传输,直至传输结束

        每个外设有一个特定的通道供数据传输

        同时多个外设使用同一个通道时由仲裁器决定优先级

        多个请求进入DMA只有一个请求有效

STM32F10xxx参考手册_V10(中文版)表59 各个通道的DMA1请求一览

2 DMA相关HAL库驱动介绍

2.0 DMA_HandleTypeDef
typedef struct __DMA_HandleTypeDef
{
  DMA_Channel_TypeDef   *Instance;        //DMA通道
  DMA_InitTypeDef       Init;                            /*!< DMA communication parameters           */ 
  
  HAL_LockTypeDef       Lock;                            /*!< DMA locking object                     */  
  
  HAL_DMA_StateTypeDef  State;                           /*!< DMA transfer state                     */
  
  void                  *Parent;                                                      /*!< Parent object state                    */  
  
  void                  (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA transfer complete callback         */
  
  void                  (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback    */
  
  void                  (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer error callback            */

  void                  (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer abort callback            */  
  
  __IO uint32_t         ErrorCode;                                                    /*!< DMA Error code                         */

  DMA_TypeDef            *DmaBaseAddress;                                             /*!< DMA Channel Base Address               */
  
  uint32_t               ChannelIndex;                                                /*!< DMA Channel Index                      */  

} DMA_HandleTypeDef;  
2.1 __HAL_RCC_DMAx_CLK_ENABLE()

        用于使能DMA1控制器的时钟,其中 x 代表想要使能的DMA控制器的编号

__HAL_RCC_DMA1_CLK_ENABLE();
2.2 HAL_DMA_Init()

        函数定义        HAL_StatusTypeDef HAL_DMA_Init (DMA_HandleTypeDef * hdma)

        函数描述        根据DMA_InitTypeDef中指定的参数初始化DMA,并创建关联的句柄。

        参数               hdma:指向包含指定DMA通道的配置信息的指针。

        返回值            HAL status

DMA_HandleTypeDef  g_dma_handle;                                //创建DMA句柄

g_dma_handle.Instance = DMA1_Channel4 ;                         //DMA传输使用的通道
g_dma_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;             //模式,内存到外设
g_dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;                 //外设非增量模式
//递增模式会使得DMA在传输数据时会自动递增寄存器地址,用于处理连续数据块
g_dma_handle.Init.MemInc = DMA_MINC_ENABLE;                     //存储器增量模式
//与外设增量模式差不多,只不过这个应用于内存
g_dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //数据对齐方式:一字节
//类似于缓存,收集到一字节的数据后DMA才进行数据传输
g_dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //存储器数据长度:一字节
g_dma_handle.Init.Mode = DMA_NORMAL;                            //DMA模式:正常模式
//循环模式会在完成一次传输后,自动重新开始一次新的传输,继续传输之前设置的数据
//这种循环的过程可以持续进行,直到手动停止DMA或者中止传输
g_dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;               //中等优先级

HAL_DMA_Init(&g_dma_handle);
2.3 __HAL_LINKDMA()

        宏描述        用于将外设和 DMA 通道关联起来,以便在使用 DMA 进行数据传输时,DMA 控制器知道要使用哪个 DMA 通道来管理传输

__HAL_LINKDMA(&g_uart1_handle, hdmatx, g_dma_handle);
//hdmatx是UART句柄中一个成员,是UART1的DMA发送通道
2.4 HAL_UART_Transmit_DMA()

        函数定义        HAL_StatusTypeDef HAL_UART_Transmit_DMA (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size)

        函数描述        以非阻塞模式发送数据

        参数               huart:指向UART_HandleTypeDef结构体的指针,该结构体包含指定UART

                              模块的配置信息。

                              pData: 指向数据缓冲区指针

                              Size: 要发送的数据量

        返回值            HAL status

HAL_UART_Transmit_DMA(&g_uart1_handle, g_sendbuf, SEND_BUF_SIZE);
2.6 __HAL_DMA_GET_FLAG()

        宏定义        __HAL_DMA_GET_FLAG(&hdma, DMA_FLAG_XYZ)

        宏描述        用于检查特定DMA通道的标志位是否被置位,以确定是否发生了某个特定的事件,比如传输完成

        宏参数        &hdma:DMA_HandleTypeDef 结构体变量,DMA句柄

                           DMA_FLAG_XYZ:要检查的标志位

if ( __HAL_DMA_GET_FLAG(&g_dma_handle, DMA_FLAG_TC4))   /* 等待 DMA1_Channel4 传输完成 */
{
    __HAL_DMA_CLEAR_FLAG(&g_dma_handle, DMA_FLAG_TC4);  /* 清除 DMA1_Channel4 传输完成标志 */
    HAL_UART_DMAStop(&g_uart1_handle);                  /* 传输完成以后关闭串口DMA */
    break;
}
2.7 __HAL_DMA_GET_COUNTER()

        宏定义        __HAL_DMA_GET_COUNTER(&hdma);

        宏描述        获取特定DMA通道的剩余传输字节数

        宏参数        &hdma:DMA_HandleTypeDef 结构体变量,DMA句柄

pro = __HAL_DMA_GET_COUNTER(&g_dma_handle);

3 DMA配置步骤

        使能DMA时钟                                        __HAL_RCC_DMA1_CLK_ENABLE

        初始化DMA                                           HAL_DMA_Init; __HAL_LINKDMA

        使能串口的DMA发送,启动传输           HAL_UART_Transmit_DMA

        查询DMA传输状态                                __HAL_DMA_GET_FLAG;                                                                       __HAL_DMA_GET_COUNTER

        DMA中断使用                                       HAL_NVIC_EnableIRQ; HAL_NVIC_SetPriority

4 参考资料

       1.  Description of STM32F1xx HAL drivers.pdf

       2.【【正点原子】手把手教你学STM32 HAL库开发全集【真人出镜】STM32入门教学视频教程 单片机 嵌入式】 https://www.bilibili.com/video/BV1bv4y1R7dp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值