打印
[应用相关]

stm32 再来学习DMA

[复制链接]
1361|38
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
DMA 简介
DMA(Direct Memory Access)—直接存储器存取,是单片机的一个外设,它的主要功能
是用来搬数据,但是不需要占用 CPU,即在传输数据的时候, CPU 可以干其他的事情,好
像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以
SRAM 或者是 FLASHDMA 控制器包含了 DMA1 DMA2,其中 DMA1 7 个通道,
DMA2 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存
在于大容量的单片机中。  

评论
香水城 2018-11-1 10:36 回复TA
加油! 
沙发
hanzhen654|  楼主 | 2018-10-31 20:43 | 只看该作者
DMA 功能框图



使用特权

评论回复
板凳
hanzhen654|  楼主 | 2018-10-31 20:44 | 只看该作者
DMA 请求
如果外设要想通过 DMA 来传输数据,必须先给 DMA 控制器发送 DMA 请求, DMA
收到请求信号之后,控制器会给外设一个应答信号,当外设应答后且 DMA 控制器收到应
答信号之后,就会启动 DMA 的传输,直到传输完毕。
DMA 有 DMA1 和 DMA2 两个控制器, DMA1 有 7 个通道, DMA2 有 5 个通道,不同
的 DMA 控制器的通道对应着不同的外设请求,这决定了我们在软件编程上该怎么设置

使用特权

评论回复
地板
hanzhen654|  楼主 | 2018-10-31 20:45 | 只看该作者
DMA1 各个通道的请求映像


使用特权

评论回复
5
hanzhen654|  楼主 | 2018-10-31 20:46 | 只看该作者
DMA2 各个通道的请求映像


使用特权

评论回复
6
hanzhen654|  楼主 | 2018-10-31 20:47 | 只看该作者
通道
DMA 具有 12 个独立可编程的通道,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,每
个通道对应不同的外设的 DMA 请求。虽然每个通道可以接收多个外设的请求,但是同一
时间只能接收一个,不能同时接收多个

使用特权

评论回复
7
hanzhen654|  楼主 | 2018-10-31 20:48 | 只看该作者
仲裁器
当发生多个 DMA 通道请求时,就意味着有先后响应处理的顺序问题,这个就由仲裁
器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段,可以在
DMA_CCRx 寄存器中设置,有 4 个等级:非常高、高、中和低四个优先级。第二阶段属于
硬件阶段,如果两个或以上的 DMA 通道请求设置的优先级一样,则他们优先级取决于通道
编号,编号越低优先权越高,比如通道 0 高于通道 1。在大容量产品和互联型产品中,
DMA1 控制器拥有高于 DMA2 控制器的优先级。

使用特权

评论回复
8
hanzhen654|  楼主 | 2018-10-31 20:50 | 只看该作者
DMA 方向配置:
DMA 传输数据的方向有三个:从外设到存储器,从存储器到外设,从存储
器到存储器。具体的方向 DMA_CCR 位 4 DIR 配置: 0 表示从外设到存储器, 1 表示从存
储器到外设。这里面涉及到的外设地址由 DMA_CPAR 配置,存储器地址由 DMA_CMAR
配置。

使用特权

评论回复
9
hanzhen654|  楼主 | 2018-10-31 20:50 | 只看该作者
外设到存储器
当我们使用从外设到存储器传输时,以 ADC 采集为例。 DMA 外设寄存器的地址对应
的就是 ADC 数据寄存器的地址, DMA 存储器的地址就是我们自定义的变量(用来接收存
储 AD 采集的数据)的地址。方向我们设置外设为源地址。

使用特权

评论回复
10
hanzhen654|  楼主 | 2018-10-31 20:52 | 只看该作者
存储器到外设
当我们使用从存储器到外设传输时,以串口向电脑端发送数据为例。 DMA 外设寄存器
的地址对应的就是串口数据寄存器的地址, DMA 存储器的地址就是我们自定义的变量(相
当于一个缓冲区,用来存储通过串口发送到电脑的数据)的地址。方向我们设置外设为目
标地址

使用特权

评论回复
11
hanzhen654|  楼主 | 2018-10-31 20:53 | 只看该作者
存储器到存储器
当我们使用从存储器到存储器传输时,以内部 FLASH 向内部 SRAM 复制数据为例。
DMA 外设寄存器的地址对应的就是内部 FLASH(我们这里把内部 FALSH 当作一个外设
来看)的地址, DMA 存储器的地址就是我们自定义的变量(相当于一个缓冲区,用来存储
来自内部 FLASH 的数据)的地址。方向我们设置外设(即内部 FLASH)为源地址。跟上
面两个不一样的是,这里需要把 DMA_CCR 位 14: MEM2MEM:存储器到存储器模式配
置为 1,启动 M2M 模式。

使用特权

评论回复
12
hanzhen654|  楼主 | 2018-10-31 20:54 | 只看该作者
当我们配置好数据要从哪里来到哪里去之后,我们还需要知道我们要传输的数据是多
少,数据的单位是什么。
以串口向电脑发送数据为例,我们可以一次性给电脑发送很多数据,具体多少由
DMA_CNDTR 配置,这是一个 32 位的寄存器,一次最多只能传输 65535 个数据。
要想数据传输正确,源和目标地址存储的数据宽度还必须一致,串口数据寄存器是 8
位的,所以我们定义的要发送的数据也必须是 8 位。外设的数据宽度由 DMA_CCR 的
PSIZE[1:0]配置,可以是 8/16/32 位,存储器的数据宽度由 DMA_CCR 的 MSIZE[1:0]配置,
可以是 8/16/32 位。

使用特权

评论回复
13
hanzhen654|  楼主 | 2018-10-31 20:54 | 只看该作者
在 DMA 控制器的控制下,数据要想有条不紊的从一个地方搬到另外一个地方,还必
须正确设置两边数据指针的增量模式。外设的地址指针由 DMA_CCRx 的 PINC 配置,存储
器的地址指针由 MINC 配置。以串口向电脑发送数据为例,要发送的数据很多,每发送完
一个,那么存储器的地址指针就应该加 1,而串口数据寄存器只有一个,那么外设的地址
指针就固定不变。具体的数据指针的增量模式由实际情况决定。

使用特权

评论回复
14
hanzhen654|  楼主 | 2018-10-31 20:55 | 只看该作者
数据什么时候传输完成,我们可以通过查询标志位或者通过中断的方式来鉴别。每个
DMA 通道在 DMA 传输过半、传输完成和传输错误时都会有相应的标志位,如果使能了该
类型的中断后,则会产生中断。有关各个标志位的详细描述请参考 DMA 中断状态寄存器
DMA_ISR 的详细描述。
传输完成还分两种模式,是一次传输还是循环传输,一次传输很好理解,即是传输一
次之后就停止,要想再传输的话,必须关断 DMA 使能后再重新配置后才能继续传输。循
环传输则是一次传输完成之后又恢复第一次传输时的配置循环传输,不断的重复。具体的
由 DMA_CCR 寄存器的 CIRC 循环模式位控制

使用特权

评论回复
15
hanzhen654|  楼主 | 2018-10-31 20:56 | 只看该作者
DMA_ InitTypeDef 初始化结构体
1typedef struct
2 {
3 uint32_t DMA_PeripheralBaseAddr; // 外设地址
4 uint32_t DMA_MemoryBaseAddr; // 存储器地址
5 uint32_t DMA_DIR; // 传输方向
6 uint32_t DMA_BufferSize; // 传输数目
7 uint32_t DMA_PeripheralInc; // 外设地址增量模式
8 uint32_t DMA_MemoryInc; // 存储器地址增量模式
9 uint32_t DMA_PeripheralDataSize; // 外设数据宽度
10 uint32_t DMA_MemoryDataSize; // 存储器数据宽度
11 uint32_t DMA_Mode; // 模式选择
12 uint32_t DMA_Priority; // 通道优先级
13 uint32_t DMA_M2M; // 存储器到存储器模式
14 } DMA_InitTypeDef;



使用特权

评论回复
16
hanzhen654|  楼主 | 2018-10-31 20:56 | 只看该作者
DMA_PeripheralBaseAddr:外设地址,设定 DMA_CPAR 寄存器的值;一般设置
为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储器
地址

使用特权

评论回复
17
hanzhen654|  楼主 | 2018-10-31 20:57 | 只看该作者
DMA_Memory0BaseAddr:存储器地址,设定 DMA_CMAR 寄存器值;一般设置
为我们自定义存储区的首地址。

使用特权

评论回复
18
hanzhen654|  楼主 | 2018-10-31 20:57 | 只看该作者
DMA_DIR :传 输方 向选 择,可 选外 设到 存储 器、 存储 器到 外设 。它 设 定
DMA_CCR 寄存器的 DIR[1:0]位的值。这里并没有存储器到存储器的方向选择,
当使用存储器到存储器时,只需要把其中一个存储器当作外设使用即可。

使用特权

评论回复
19
hanzhen654|  楼主 | 2018-10-31 20:58 | 只看该作者
DMA_BufferSize:设定待传输数据数目,初始化设定 DMA_CNDTR 寄存器的值。

使用特权

评论回复
20
hanzhen654|  楼主 | 2018-10-31 20:58 | 只看该作者
DMA_PeripheralInc:如果配置为 DMA_PeripheralInc_Enable,使能外设地址自动
递增功能,它设定 DMA_CCR 寄存器的 PINC 位的值;一般外设都是只有一个数
据寄存器,所以一般不会使能该位。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

1766

帖子

2

粉丝