36_DMA内存到外设实验

DMA简介

DMA全称Direct Memroy Access, 既直接存储器访问。

DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。

DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接数据的通道,使得CPU的效率大大提高,为CPU减轻负担。

常用的DMA库函数

void DMA_Init(); //DMA初始化函数

void DMA_Cmd();//DMA使能函数

void DMA_ITConfig();//DMA中断开启

void DMA_SetCurrDataCounter();//设置DMA要传输数量

uint16_t DMA_GetCurrDataCounter();//获取DMA还需要传输的数量

FlagStatus DMA GetFlagStatus();//获取状态标志位

void DMA ClearFlag();//清除标注位

ITStatus DMA GetITStatus();//获取中断标志位

void DMA_ClearlTPendingBit();//清除中断标志位

常用的外设DMA使能库函数

void USART_DMACmd();//串口DMA使能

void ADC_DMACmd();//模拟转数字DMA使能

void DAC DMACmd();//数字转模拟DMA使能

void SDIO_DMACmd();//SDIO DMA使能

void TIM_DMAConfig();//定时器DMA配置数

void TIM DMACmd()l//定时器DMA使能函数

DMA_Init_TypeDef结构体详解

Typedef struct
{
uint32_t DMA_PeripheralBaseAddr; //外设基地址
uint32_t DMA_MemoryBaseAddr; //存储器基地址
uint32_t DMA_DIR;//数据传输方向
uint32_t DMA_BufferSize; //通道传输数据量
uint32_t DMA_Peripherallnc;//外设增量模式
uint32_t DMA_Memorylnc; //存储器增量模式
uint32_t DMA_PeripheralData Size; //外设数据宽度
uint32_t DMA_MemoryDataSize;//存储器数据宽度
uint32_t DMA_Mode; //模式:是否循环
uint32_t DMA_Priority; //优先级
uint32_t DMA M2M; //是否存储器到存储器方式
}DMA_Init_TypeDef

DMA配置程序过程

1.使能DMA时钟
RCC_AHBPeriphClockCmd();
2.初始化DMA通道参数
DMA_Init();
3.使能串口DMA发送,串口DMA使能函数:
USART_DMACmd();
4.使能DMA1通道,启动传输。
DMA_Cmd()
5.查询DMA传输状态
DMA_GetFlag Status(),
6.获取设置通道当前剩余数据量:
DMA_GetCurrDataCounter();
DMA_SetCurrDataCounter();

实验源码

/**
  ******************************************************************************
  * @file           : user_rcc_config.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_rcc_config.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		RCC配置
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Rcc_config(void)
{	
	/*使能GPIOA时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	/*使能UART1时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	/*使能DMA1时钟*/	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_gpio.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_gpio.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		GPIO初始化函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Gpio_Init(void)
{	
	/*GPIO结构体*/
	GPIO_InitTypeDef GPIO_InitTypeDefstruct;
	
	/*UART1发送引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_AF_PP;//推挽复用输出
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
	
	/*UART1接收引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/	
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
		
}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_uart.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_uart.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/

extern uint16_t USART_RX_STA;
extern uint8_t USART_RX_BUF[200];


/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/
#if 1
#pragma import(__use_no_semihosting)  
/*实现Printf代码*/
struct __FILE 
{ 
	int handle; 

}; 
FILE __stdout;       

void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 




/*!
	\brief		UART1初始化
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void Uart1_Init(u32 bound)
{
	/*UART结构体*/
	USART_InitTypeDef USART_InitTypeDefstruct;
	
	/*UART结构体配置*/
	USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率
	USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
	USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
	USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
	USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
	USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
	/*写入USART1*/
	USART_Init(USART1,&USART_InitTypeDefstruct);
	
	/*使能串口1*/
	USART_Cmd(USART1,ENABLE);
	/*使能串口1的DMA发送*/
	USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); 
}


/*!
	\brief		UART1中断服务函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void USART1_IRQHandler(void)
{

}
	

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_dma.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_dma.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
extern uint8_t DMA_Buff[10];
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		DMA1初始化
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void DMA1_Init()
{	
	/*DMA结构体*/
	DMA_InitTypeDef DMA_InitStructure;

	/*复位DMA1通道14*/
	DMA_DeInit(DMA1_Channel4);	
	
	/*DMA配置*/
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;  //DMA外设基地址串口发送寄存器
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DMA_Buff;  //DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
	DMA_InitStructure.DMA_BufferSize = 3;  //DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //不循环
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
	/*写入DMA1通道14*/
	DMA_Init(DMA1_Channel4, &DMA_InitStructure);
	  	
}


/*!
	\brief		开启一次DMA传输
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void DMA1_Enable(uint8_t len)
{
	/*关闭USART1 TX DMA1 所指示的通道*/
	DMA_Cmd(DMA1_Channel4, DISABLE );
	/*设置DMA通道的DMA缓存的大小*/
	DMA_SetCurrDataCounter(DMA1_Channel4,3);
	/*开启USART1 TX DMA1 所指示的通道*/
	DMA_Cmd(DMA1_Channel4, ENABLE); 

}
/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_mian.h
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "user_dma.h"


/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
uint8_t DMA_Buff[3] = {'a',0x20}; 	 //20 是空格
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/


 int main(void)
 {	
	 uint8_t a=0;
	 
	/*配置系统中断分组为2位抢占2位响应*/
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	 /*延时函数初始化*/
	 delay_init();
	/*RCC配置*/
	 Rcc_config();
	/*GPIO初始化*/ 
	 Gpio_Init();
	/*USART1初始化*/
	 Uart1_Init(9600);
	 /*初始化DMA1*/
	 DMA1_Init();
	 /*传输一次*/

	/*死循环*/ 
	 while(1){
	/*开启一次DMA传输*/
 	 DMA1_Enable(3);  
	 delay_ms(1000);
	
	 if(a<100)
	 {
	  DMA_Buff[0] = DMA_Buff[0]+1;
	 }else
	{
	  DMA_Buff[0] = 0;
	}

	 }
		

}
 
 /************************************************************** END OF FILE ****/

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值