直接寄存器访问(DMA)

本文介绍了STM32的DMA基础知识,包括DMA控制器的数量、通道、特性等,并详细阐述了如何通过寄存器和库函数两种方式配置及操作DMA,以实现数据从内存到外设的高效传输。通过DMA,CPU的效率得以显著提高,允许在数据传输期间执行其他任务。
摘要由CSDN通过智能技术生成

DMA 即 Direct Memory Access. DMA传输方式无须CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,能使CPU的效率大为提高。

1. DMA基础知识

STM32 最多有2个DMA控制器(DMA2仅存在大容量产品中),DMA有7个通道,DMA2有5个通道。每个通道专门用来管理来自一个或多个外设对存储器访问的请求。还有一个仲裁器协调各个DMA请求的优先权。

STM32的DMA有以下一些特性:

  1. 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。
  2. 在7个请求间的优先权可以通过软件编程来配置,假如在优先权相等时,由硬件决定。
  3. 独立的源和目标数据区的传输宽度(字节,半字,全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。
  4. 支持循环的缓冲器管理。
  5. 每个通道都有3个事件标志(DMA半传输,DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。
  6. 存储器和存储器间的传输。
  7. 外设和存储器,存储器和外设的传输。
  8. 闪存,SRAM, 外设的SRAM,APB1,APB2,和AHB外设均可作为访问的源和目标。
  9. 可编程的数据传输数目,最大为65536.
    外设通过逻辑或输入到DMA通道,意味着每个通道只能同时接收一个请求。

2. 用寄存器方式操作DMA

假设为DMA1的通道4,配置步骤如下:

  1. 设置外设地址。 外设地址通过DMA1_CPAR4设置,只要在这个寄存器里面写入&USART1_DR的值就可以。该地址将作为DMA传输的目标地址。
  2. 设置存储器地址。存储器地址通过DMA1_CMAR4来设置,假设要把数组SendBuf作为存储器,那么在该寄存器内写入&SendBuf就可以。该地址将作为DMA传输的源地址。
  3. 设置传输数据量。通过DMA_CNDTR4寄存器,这里面写入此次要传输的数据量,即SendBuf的大小。该寄存器的数值将在DMA启动后自减,每次新的DMA传输,都重新向该寄存器写入要传输的数据量。
  4. 设置通道4的配置信息。设置存储器和外设的数据位宽为8,存储器增量模式。优先级可以随便设置,因为只有一个通道开启。
  5. 使能DMA1通道4,启动传输。以上配置都完成后,就使能DMA1_CCR4的最低位开启DMA传输,注意要设置USART1的使能DMA传输位,通过USART1->CR3的第7位设置。

3. 用库函数的方式操作DMA

总共5步去配置DMA.

  • 使能DMA时钟。
  • 初始化DMA通道4的参数。
  • 使能串口DMA发送。
  • 使能DMA1通道4,启动传输。
  • 查询DMA传输状态。

1. 使能DMA时钟

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

2. 初始化DMA通道4的参数

DMA的初始化是通过配置函数:

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)

第1个参数指定通道,第二个参数用来初始化DMA。
设置具体如下:

DMA_InitTypeDef DMA_InitStructure; 
//DMA外设ADC基地址
DMA_InitStructure.DMA_PeriperalBaseAddr = &USART->DR;
//DMA内存基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar;
//从内存读取发送到外设
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripherialDST;
//DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_BufferSize = 64;
//外设地址不变
DMA_InitStructure.DMA_PeripherialInc = DMA_PeripherialInc_Disable;
//内存地址递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//8位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
//8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//工作在正常缓存模式
DMA_InitStructure.DMA_Mode =</
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值