微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > stm32之DMA彻底研究

stm32之DMA彻底研究

时间:11-19 来源:互联网 点击:
在做实验之前,首先必须明白什么是DMA,DMA的作用又体现在哪里。

DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。让CPU有足够的时间处理其他的事情。

stm32使用DMA的相关操作:

1、DMA的配置

要配置的有DMA传输通道选择,传输的成员和方向、普通模式还是循环模式等等。

void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//DMA设置:
//设置DMA源:内存地址&串口数据寄存器地址
//方向:内存-->外设
//每次传输位:8bit
//传输大小DMA_BufferSize=SENDBUFF_SIZE
//地址自增模式:外设地址不增,内存地址自增1
//DMA模式:一次传输,非循环
//优先级:中
DMA_DeInit(DMA1_Channel4);//串口1的DMA传输通道是通道4
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外设作为DMA的目的端
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不增加
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址自增1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA传送优先级为中等)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}

注:

1、传输通道:通过查表,串口1的发送对应的是DMA的通道4,所以此处选择通道4.

2、DMA传输方式:

(1) DMA_Mode_Normal,正常模式,当一次DMA数据传输完后,停止DMA传送,对于上例而言,就是DMA_PeripheralDataSize_Byte个字节的传送完成后,就停止传送。

(2) DMA_Mode_Circular

循环模式,当传输完一次后,重新接着传送,永不停息。

2、外设的DMA方式设置

将串口1设置成DMA模式:

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

3、待传输数据的定义和初始化

#define SENDBUFF_SIZE 10240
vu8 SendBuff[SENDBUFF_SIZE];

for(i=0;i{
SendBuff[i] = i%10+0;
}
4、开始DMA传输(使能对应的DMA通道)
DMA_Cmd(DMA1_Channel4, ENABLE);

5、DMA传输的完成

while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
{
LED_1_REV; //LED翻转
Delay(); //浪费时间
}

当传输完成后,就会跳出上面的死循环。

下面是九九的一个例程,测试过,可以运行!

/******************************************************************************
* 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData()
* 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输
* 每当USART的发送缓冲区空时,USART模块产生一个DMA事件,
* 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART
* 整个过程无需用户程序干预,用户只需启动DMA传输传输即可
* 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止
* 串口依然发送,表明DMA传输是一个独立的过程。
* 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理
* 作者:jjldc(九九)
* 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "stdio.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USART1_DR_Base 0x40013804

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#define SENDBUFF_SIZE 10240
vu8 SendBuff[SENDBUFF_SIZE];
vu8 RecvBuff[10];
vu8 recv_ptr;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
void USART1_Configuration(void);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top