时间:2024.10.31-11.2
参考资料:
《零死角玩转STM32》“DMA--直接存储器访问”章节
编程部分的代码基于12-GPIO输出-使用固件库点亮LED灯
一、学习内容
1、DMA功能框图和DMA初始化结构体
1.1DMA功能框图
1.1.1DMA简介
DMA:
Data Memory Access,直接存储器访问。和GPIO、串口等一样都是外设。
主要功能:
把数据从一个地方搬到另外一个地方,而且不占用CPU。
DMA1:
有7个通道(搬运数据的管道),可以实现P(外设)->M(存储器),M->P,M->M
DMA2(只存在大容量/互联型的产品中):
有5个通道,可以实现P->M,M->P,M->M
霸道和指南者是512K的,所以都有两个DMA控制器
1.1.2DMA功能框图
1-DMA请求
如果外设想要通过DMA来传输数据,必须先向DMA控制器发送DMA请求,DMA收到请求信号以后,控制器会给外设一个应答信号,当外设应答且DMA控制器收到应答信号之后,就会启动DMA的传输,直到传输完毕。
2-通道
传输数据的管道
2.1DMA请求+通道
DMA1请求映射
DMA2请求映射
TIPS:
1、ADC3/SDIO/TIM8的DMA请求只有大容量的单片机才有
2、当使用M->M模式时,所有通道均可使用,无硬性规定,P->M和M->P都需要根据实际需要的功能选择不同的通道
3-仲裁器
多个DMA请求一起来,怎么办?
1、软件阶段,DMA_CCPx:PL[1:0]。
2、硬件阶段,通道编号小的优先级大,DMA1的优先级高于DMA2的优先级。
1.1.3DMA处理
1.2DMA相关库函数
1.2.1DMA初始化结构体
初始化结构体在固件库头文件中:stm32f10x_dma.h
/**
* @brief DMA Init structure definition
*/
typedef struct
{
uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */
uint32_t DMA_MemoryBaseAddr; /*!< Specifies the memory base address for DMAy Channelx. */
uint32_t DMA_DIR; /*!< Specifies if the peripheral is the source or destination.
This parameter can be a value of @ref DMA_data_transfer_direction */
uint32_t DMA_BufferSize; /*!< Specifies the buffer size, in data unit, of the specified Channel.
The data unit is equal to the configuration set in DMA_PeripheralDataSize
or DMA_MemoryDataSize members depending in the transfer direction. */
uint32_t DMA_PeripheralInc; /*!< Specifies whether the Peripheral address register is incremented or not.
This parameter can be a value of @ref DMA_peripheral_incremented_mode */
uint32_t DMA_MemoryInc; /*!< Specifies whether the memory address register is incremented or not.
This parameter can be a value of @ref DMA_memory_incremented_mode */
uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.
This parameter can be a value of @ref DMA_peripheral_data_size */
uint32_t DMA_MemoryDataSize; /*!< Specifies the Memory data width.
This parameter can be a value of @ref DMA_memory_data_size */
uint32_t DMA_Mode; /*!< Specifies the operation mode of the DMAy Channelx.
This parameter can be a value of @ref DMA_circular_normal_mode.
@note: The circular buffer mode cannot be used if the memory-to-memory
data transfer is configured on the selected Channel */
uint32_t DMA_Priority; /*!< Specifies the software priority for the DMAy Channelx.
This parameter can be a value of @ref DMA_priority_level */
uint32_t DMA_M2M; /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer.
This parameter can be a value of @ref DMA_memory_to_memory */
}DMA_InitTypeDef;
1.数据从哪里来,要到哪里去
1.1外设地址,DMA_CPAR
地址从外设得来,一般情况下是从外设的数据寄存器而来
1.2存储器地址,DMA_CMAR
1.3传输方向,DMA_CCR:DIR
uint32_t DMA_PeripheralBaseAddr; //外设地址
uint32_t DMA_MemoryBaseAddr; //存储器地址
uint32_t DMA_DIR; //传输方向
M-->M的控制位
2.结构体成员取值
在固件库头文件中:stm32f10x_dma.h
/** @defgroup DMA_data_transfer_direction
* @{
*/
#define DMA_DIR_PeripheralDST ((uint32_t)0x00000010)
#define DMA_DIR_PeripheralSRC ((uint32_t)0x00000000)
#define IS_DMA_DIR(DIR) (((DIR) == DMA_DIR_PeripheralDST) || \
((DIR) == DMA_DIR_PeripheralSRC))
3.数据要传多少,传的单位是什么
uint32_t DMA_BufferSize; //传输数目
uint32_t DMA_PeripheralInc; //外设地址增量模式
uint32_t DMA_MemoryInc; //存储器地址增量模式
uint32_t DMA_PeripheralDataSize; //外设数据宽度
uint32_t DMA_MemoryDataSize; //存储器数据宽度
3.1传输数目,DMA_CNDTR
3.2外设地址是否递增,DMA_CCRx:PINC
3.3存储器地址是否递增,DMA_CCRx:MINC