STM32——DMA、代码配置部分(2)(学习笔记)

STM32的DMA配置

结构体成员分析

首先我们看一下DMA_Init();初始化里面的结构体成员:
在这里插入图片描述

在这里插入图片描述

DMA_Channel:这个是DMA的通道选择,可选通道 0 至通道 7,每一个外设对应固定的通道。这个直接控制寄存器的DMA_SxCR寄存器的 CHSEL[2:0] 位的值。即:
在这里插入图片描述
DMA_PeripheralBaseAddr:外设地址。这里直接控制的是寄存DMA_SxPAR 寄存器的值;一般设置为外设的数据寄存器地址。

DMA_Memory0BaseAddr:存储器 0 地址,设定DMA_SxM0AR寄存器值;一般设置为我们自定义存储区的首地址。我们程序先自定义一个 16 位无符号整形数组用来存放每个通道的值,所以把数组 首 地 址 (直 接 使 用 数 组 名 即 可) 赋值给DMA_Memory0BaseAddr。

DMA_DIR:传输方向选择,可选外设到存储器、存储器到外设以及存储器到存储器。它设定DMA_SxCR 寄存器的 DIR[1:0] 位的值。

DMA_BufferSize:设定待传输数据数目,初始化设定DMA_SxNDTR寄存器的值。

DMA_PeripheralInc:如果配置为 DMA_PeripheralInc_Enable,使能外设地址自动递增功能,它设定DMA_SxCR寄存器的 PINC 位的值;一般外设都是只有一个数据寄存器,所以一般不会使能该位。ADC3 的数据寄存器地址是固定并且只有一个所以不使能外设地址递增。

DMA_MemoryInc:如果配置为 DMA_MemoryInc_Enable,使能存储器地址自动递增功能,它设定DMA_SxCR寄存器的 MINC 位的值;我们自定义的存储区一般都是存放多个数据的,所以使能存储器地址自动递增功能。我们之前已经定义了一个包含 4 个元素的数字用来存放数据,使能存储区地址递增功能,自动把每个通道数据存放到对应数组元素内。

DMA_PeripheralDataSize:外设数据宽度,可选字节 (8 位)、半字 (16 位) 和字 (32 位),它设定DMA_SxCR 寄存器的 PSIZE[1:0] 位的值。ADC 数据寄存器只有低 16 位数据有效,使用半字数据宽度。

DMA_MemoryDataSize:存储器数据宽度,可选字节 (8 位)、半字 (16 位) 和字 (32 位),它设定DMA_SxCR 寄存器的 MSIZE[1:0] 位的值。保存 ADC 转换数据也要使用半字数据宽度,这跟我们定义的数组是相对应的。

DMA_Mode:DMA传输模式选择,可选一次传输或者循环传输,它设定 DMA_SxCR寄存器的 CIRC 位的值。我们希望 ADC 采集是持续循环进行的,所以使用循环传输模式。

DMA_Priority:软件设置数据流的优先级,有 4 个可选优先级分别为非常高、高、中和低,它设定DMA_SxCR 寄存器的 PL[1:0] 位的值。DMA 优先级只有在多个 DMA 数据流同时使用时才有意义,这里我们设置为非常高优先级就可以了。

DMA_FIFOMode:FIFO模式使能,如果设置为DMA_FIFOMode_Enable表示使能 FIFO 模式功能;它设定DMA_SxFCR 寄存器的 DMDIS 位。

DMA_FIFOThreshold:FIFO阈值选择,可选 4 种状态分别为 FIFO 容量的 1/4、1/2、3/4 和满;它设定DMA_SxFCR寄存器的 FTH[1:0] 位;DMA_FIFOMode 设置为DMA_FIFOMode_Disable,那么DMA_FIFOThreshold值无效。

DMA_MemoryBurst:存储器突发模式选择,可选单次模式、4 节拍的增量突发模式、8 节拍的增量突发模式或 16 节拍的增量突发模式,它设定DMA_SxCR寄存器的 MBURST[1:0] 位的值。

DMA_PeripheralBurst:外设突发模式选择,可选单次模式、4 节拍的增量突发模式、8 节拍的增量突发模式或 16 节拍的增量突发模式,它设定DMA_SxCR 寄存器的 PBURST[1:0] 位的值。

DMA完整的配置

这些结构体分析完了。我们再看看一般情况下怎么完整的配置DMA呢?

本文以stm32f4的存储器到外设的模式为例。这里用到usart1。
我们查阅DMA2的各个通道的请求映像知道USART1对应DMA2的数据流7通道4。

首先我们要开启DMA对应的时钟,例:开启DMA2时钟:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

将DMAyChannelx寄存器的初始化为其默认值。即复位初始化DMA的数据流:

DMA_DeInit(DMA2_Stream7);

等待数据流复位完成

while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);

配置DMA_Init()函数

u16 SENDBUFF_SIZE=5000//发送的数据量
uint8_t SendBuff[SENDBUFF_SIZE];


 DMA_InitTypeDef DMA_InitStructure;
 DMA_InitStructure.DMA_Channel=DMA_Channel_4;//通道4
 DMA_InitStructure.DMA_PeripheralBaseAddr = (USART1_BASE+0x04);	//设置DMA源,串口DMA的数据寄存器地址
 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SendBuff;  //配置内存地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;	//方向:存储器到外设
 DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不增
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;	//内存地址自增
 DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;//外设数据单位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;	//内存数据单位
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	 //DMA模式《不断循环》
 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //优先级为中
  /*禁用FIFO*/
 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;        
 DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; 
 DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发传输16个节拍
 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发传输1个节拍
 DMA_Init(DMA2_Stream7, &DMA_InitStructure);

初始化完之后别忘了要对DMA进行使能:

DMA_Cmd(DMA2_Stream7, ENABLE);

最后在等待数据流有效:

 while(DMA_GetCmdStatus(DMA2_Stream7) != ENABLE);

这样就完整的配置完了DMA在串口usart1上的配置了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叶同学要努力呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值