DMA外设

文章目录

  • DMA简介
  • cubeMX配置
  • keil使用流程
  • HAL库
    • Handler
    • StateTypeDef
    • DMA状态控制函数
    • DMA中断控制函数
    • DMA回调函数

DMA简介

DAM简介

cubeMX配置

DMA外设_第1张图片

  • DMA_Request:外设的通道

  • Channel:一般通道都为默认的

  • Direction:传输方向

    • Peripheral To Memory:外设到内存
    • Memory To Peripheral:内存到外设
    • Memory To Memory:内存到内存
  • Priority:DMA优先级

    • Low:低
    • Medium:中
    • High:高
      当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在 DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通 道编号,编号越低优先权越高,比如通道 0 高于通道 1。
      DMA外设_第2张图片
  • Mode

    • Normal:表示单次传输,传输一次后终止传输,配置并产生中断。
    • Circular:表示循环传输,传输完成后又重新开始继续传输。
  • Increment Address

    • Peripheral:表示外设地址自增。
    • Memory:表示内存地址自增。
      串口发送数据是将数据不断存进串口的发送数据寄存器(USARTx_TDR)。所以外接的地址是不递增。而内存储器存储的是要发送的数据,所以地址指针要递增才能将所以的数据发送出去。
  • Data Width

    • Byte:一个字节。
    • Half Word:半字,两字节。
    • Word:一个字,四字节。

DMA外设_第3张图片

DAM中断一般都被强制使能了,也可以通过Force DMA channels Interrupts来取消。


keil使用流程

在响应的外设中找到DMA模式,调用相关函数即可。

HAL库

Handler

typedef struct __DMA_HandleTypeDef
{
  DMA_Channel_TypeDef        *Instance;                                                    /*!< Register base address                  */
  DMA_InitTypeDef            Init;                                                         /*!< DMA communication parameters           */
  HAL_LockTypeDef            Lock;                                                         /*!< DMA locking object                     */
  __IO 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;   

StateTypeDef

typedef enum
{
  HAL_DMA_STATE_RESET          = 0x00U,  /*!< DMA not yet initialized or disabled    */
  HAL_DMA_STATE_READY          = 0x01U,  /*!< DMA initialized and ready for use      */
  HAL_DMA_STATE_BUSY           = 0x02U,  /*!< DMA process is ongoing                 */
  HAL_DMA_STATE_TIMEOUT        = 0x03U   /*!< DMA timeout state                      */
}HAL_DMA_StateTypeDef;

DMA状态控制函数

// 使能DMA非中断模式
HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);

// 终止DMA
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma);

// 等待DMA传输完成
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout);

// 获取DMA状态
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma);

// 获取DMA错误
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma);

// 使能DMA(非中断模式)
#define __HAL_DMA_ENABLE(__HANDLE__)

// 失能DMA
#define __HAL_DMA_DISABLE(__HANDLE__)

// 获取DMA的传输计数器
#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR)

DMA中断控制函数

// 使能DMA中断模式
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);

// 终止中断模式的DMA
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma);

// 使能DMA中断
// 三种DMA中断(DMA_IT_TC传完 / DMA_IT_HT传一半 / DMA_IT_TE出错)
#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__)

// 失能DMA中断
#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__)

// 获取中断使能状态
#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__)

DMA回调函数

必须将回调函数注册到handler里,当中断发生时由HAL_DMA_IRQHandler()函数调用

// DMA传输完成
void TransferCpltCallback( struct __DMA_HandleTypeDef * hdma);

// DMA传输一半
void TransferHalfCpltCallback( struct __DMA_HandleTypeDef * hdma);

// 传输错误
void TransferErrorCallback( struct __DMA_HandleTypeDef * hdma);

// 传输停止
void TransferAbortCallback( struct __DMA_HandleTypeDef * hdma);

                                     ------ BY Flier

2023.10.17

你可能感兴趣的:(#,HAL库,stm32,单片机,arm开发,c语言,嵌入式硬件)