1,DMA控制器的内部结构
STM32中的DMA控制器是一种用于在外设和存储器之间传输数据的专用硬件。DMA控制器的内部结构主要包括以下几个关键部分:
通道: DMA控制器可以有多个通道,每个通道独立管理一个数据传输任务。通道的数量取决于具体的STM32型号,每个通道可以独立配置,使得DMA可以同时执行多个数据传输任务。
数据传输方向寄存器: 该寄存器用于配置数据传输的方向,可以设置为从外设到存储器(Memory-to-Memory)、从外设到存储器(Peripheral-to-Memory)、从存储器到外设(Memory-to-Peripheral)等不同方向。
地址寄存器: DMA控制器有两个地址寄存器,一个用于配置外设地址,另一个用于配置存储器地址。这些寄存器存储了传输数据的源地址和目的地址。
传输计数寄存器: 该寄存器用于设置传输的数据量,即希望传输的数据的数量。传输计数寄存器的值递减或递增,直到传输完成。
传输模式寄存器: DMA控制器支持不同的传输模式,例如循环模式、块传输模式、内存自增/自减等。传输模式寄存器用于配置这些传输模式。
优先级寄存器: 当多个通道同时请求DMA服务时,通过优先级寄存器可以配置通道的优先级。优先级高的通道将获得DMA控制权。
中断和事件寄存器: DMA控制器支持中断,用于在数据传输完成或发生错误时通知CPU。相关寄存器用于配置和监视中断和事件状态。
配置寄存器: DMA控制器有一些配置寄存器,用于配置DMA的工作模式、触发条件、错误处理等。
状态寄存器: 用于存储DMA通道的状态信息,例如传输完成、半传输等状态。
2,DMA处理过程
DMA的处理过程涉及以下几个关键步骤,这些步骤描述了DMA如何从源地址传输数据到目的地址,而无需CPU的干预:
通道配置: DMA控制器可以有多个通道,每个通道独立管理一个数据传输任务。首先,需要配置DMA通道,确定数据传输的方向、源和目的地址、传输数据量等参数。
源和目的地址设置: 配置DMA的源地址和目的地址,分别指定数据传输的起始点和目标存储位置。
传输数量设置: 配置传输计数寄存器,确定要传输的数据的数量。这个值在传输过程中递减或递增,直到传输完成。
传输模式设置: 配置传输模式寄存器,选择传输模式。常见的传输模式包括循环模式、块传输模式、内存自增/自减等。
启动DMA传输: 当DMA的配置完成后,通过软件或外部触发信号启动DMA传输。DMA控制器将开始在指定通道上执行数据传输任务。
数据传输: DMA控制器根据配置的参数,从源地址读取数据,然后将数据写入目的地址。这一过程在不需要CPU干预的情况下进行。
中断和事件处理: 如果配置了中断,DMA在传输完成时可以生成中断请求。CPU可以通过中断服务例程处理传输完成事件,执行相关的操作。另外,DMA还可以在传输完成或发生错误时生成事件,用于触发其他模块的操作。
传输结束: DMA控制器监视传输计数寄存器,当传输计数达到零时,传输完成。在某些情况下,可以在传输完成时产生传输完成事件,通知相关模块传输已经结束。
3,DMA中断
DMA中断是指在DMA(Direct Memory Access)传输过程中,当数据传输完成或者发生错误时,DMA控制器产生中断请求,通知CPU进行相应的处理。DMA中断允许CPU在数据传输阶段结束时或者在发生错误时执行特定的中断服务例程,以便对数据传输的完成状态进行处理或进行错误处理。
在使用DMA时,可以配置DMA中断,以便在以下情况之一发生时通知CPU:
传输完成中断: 当DMA传输的数据量达到设定值时,DMA控制器产生传输完成中断请求。这时,CPU可以执行相应的中断服务例程,处理传输完成后的操作,如数据处理、状态更新等。
半传输中断: 在一些DMA控制器中,还可以配置半传输中断,即在传输完成一半数据时产生中断请求。这对于一些特殊的数据传输场景可能会有用。
错误中断: 如果在DMA传输过程中发生错误,例如总线错误或存储器溢出,DMA控制器可以产生错误中断请求。CPU可以通过错误中断服务例程来处理这些错误,采取相应的措施。
DMA中断的使用可以提高系统的灵活性和可靠性。通过合理配置DMA中断,可以在不占用CPU时间的情况下及时获取数据传输的状态,进行相应的处理。配置DMA中断的具体步骤包括:
使能DMA中断: 在DMA控制寄存器中,通常有一个使能中断的位,设置为1表示允许产生中断。
配置中断优先级: 在中断控制器中,配置DMA中断的优先级,以确保在多个中断同时发生时,能够按照优先级顺序进行响应。
编写中断服务例程: CPU需要编写中断服务例程,以定义在中断发生时要执行的操作。这可以包括数据处理、状态更新、错误处理等。
4,DMA映射
DMA中断映射是指将DMA(Direct Memory Access)传输的中断请求映射到特定的中断线上,以便在中断控制器中进行管理和处理。在某些DMA控制器中,可以配置DMA中断映射,以确定DMA传输完成或发生错误时触发的中断是哪一个中断线上的中断。
为了更好地理解DMA中断映射,以下是一些相关的概念:
中断线: 中断线是连接外设或模块到中断控制器的通道。每个中断线上可以连接多个中断源,中断控制器可以通过中断优先级和中断屏蔽来决定哪个中断源获得服务。
DMA通道: DMA控制器有多个通道,每个通道负责一个数据传输任务。当数据传输完成或发生错误时,DMA通道可以产生中断请求。
DMA中断映射: DMA中断映射允许将DMA通道的中断请求映射到特定的中断线上。这样,CPU就可以通过中断控制器管理和处理DMA通道产生的中断。
中断控制器配置: 在某些STM32系列微控制器中,中断控制器(NVIC)提供了中断线的配置和管理功能。通过配置中断线,可以确定DMA中断映射到哪个中断线上,以及中断线的优先级等参数。
下面是一个简化的例子,说明DMA中断映射的可能配置:
#include "stm32f4xx_hal.h"
void DMA_Configuration(void)
{
// 初始化 DMA 结构体
DMA_HandleTypeDef dma_handle;
dma_handle.Instance = DMA1_Stream0;
dma_handle.Init.Channel = DMA_CHANNEL_0;
dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY;
dma_handle.Init.PeriphInc = DMA_PINC_ENABLE;
dma_handle.Init.MemInc = DMA_MINC_ENABLE;
dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
dma_handle.Init.Mode = DMA_NORMAL;
dma_handle.Init.Priority = DMA_PRIORITY_HIGH;
// 关联 DMA 句柄与 DMA 控制器
HAL_DMA_Init(&dma_handle);
// 关联 DMA 句柄与源、目的地地址
HAL_DMA_Start(&dma_handle, (uint32_t)sourceBuffer, (uint32_t)destinationBuffer, BUFFER_SIZE);
// 配置 DMA 中断映射
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
==========
往期回顾:
单片机的各个通信协议的波特率
C语言有哪些预处理操作?
面试题--函数指针的五大作用
卡尔曼滤波的原理和C代码
中值滤波的原理和C代码
==========