0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

直接存储器存取(DMA)简介及程序设计

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-06-01 09:01 次阅读

1.DMA简介

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。
STM32F10x中有两个DMA控制器(DMA1有7个通道,DMA2有5个通道)每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

DMA1请求映像
  USART1_TX – DMA1_Chnanel4
  USART1_RC – DMA1_Channel5
  利用DMA功能完成串口数据处理,无需CPU干预,减少CPU占用。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

2.程序设计

 1.DMA1_CH4配置

/******DMA配合串口1发送数据************
**形参:u32 cpar -- 外设地址
**
**例:DMA_CH4_Init(&USART1->DR,buff)
**外设地址:USART1->DR的地址
**					buff的地址
**************************************/
void DMA_CH4_Init(u32 cpar)
{
	RCC->AHBENR|=1<<0;//dma1时钟使能
	DMA1_Channel4->CCR&=~(1<<14);//非存储器到存储器模式
	DMA1_Channel4->CCR|=0x3<<12;//设置CH4优先级为最高
	DMA1_Channel4->CCR&=~(0x3<<10);//存储器数据宽度8位
	DMA1_Channel4->CCR&=~(0x3<<8);//外设数据宽度8位	
	DMA1_Channel4->CCR|=1<<7;//存储器地址增量
	DMA1_Channel4->CCR&=~(1<<6);//外设地址不增量
	DMA1_Channel4->CCR&=~(1<<5);//不执行循环操作
	DMA1_Channel4->CCR|=1<<4;//从存储器读
	DMA1_Channel4->CPAR=cpar;//外设地址
}
/**********开启DMA1_CH4数据传输*************
***
***形参:u16 data_len -- DMA要传输数目
***********************************************/
void DMA_CH4_Start(u8 *buff,u16 data_len)
{
	DMA1_Channel4->CMAR=(u32)buff;//存储器地址
	DMA1_Channel4->CCR&=~(1<<0);//关闭通道传输
	DMA1_Channel4->CNDTR=data_len;//设置传输数量
	DMA1_Channel4->CCR|=1<<0;//开启通道传输
}

  2.DMA1_CH5配置

/******DMA配合串口1接收数据************
**形参:u32 cpar -- 外设地址
**			u32 cmar -- 存储器地址
**
**例:DMA_CH5_Init(&USART1->DR,buff)
**外设地址:USART1->DR的地址
**					buff的地址
**************************************/
void DMA_CH5_Init(u32 cpar,u32 cmar)
{
	RCC->AHBENR|=1<<0;//dma1时钟使能
	DMA1_Channel5->CCR&=~(1<<14);//非存储器到存储器模式
	DMA1_Channel5->CCR|=0x3<<12;//设置CH4优先级为最高
	DMA1_Channel5->CCR&=~(0x3<<10);//存储器数据宽度8位
	DMA1_Channel5->CCR&=~(0x3<<8);//外设数据宽度8位	
	DMA1_Channel5->CCR|=1<<7;//存储器地址增量
	DMA1_Channel5->CCR&=~(1<<6);//外设地址不增量
	DMA1_Channel5->CCR&=~(1<<5);//执行循环操作
	DMA1_Channel5->CCR&=~(1<<4);//从外设读
	DMA1_Channel5->CPAR=cpar;//外设地址
	DMA1_Channel5->CMAR=cmar;//存储器地址
	DMA1_Channel5->CCR&=~(1<<0);//关闭通道传输
	DMA1_Channel5->CNDTR=1024;//设置传输数量
	DMA1_Channel5->CCR|=1<<0;//开启通道传输
}

  3.USART1配置

/********************串口初始化函数封装*********************
****硬件接口:USART1_TX -- PA9(发送)
**						USART1-RX --PA10(接收)
**						USART2_TX -- PA2(发送)
**						USART2-RX --PA3(接收)
**						USART3_TX -- PB10(发送)
**						USART3_RX -- PB11(接收)
形参:USART_TypeDef *USARTx -- 要配置的哪个串口
**			u32 baud  --波特率
**			u32 sysclk --时钟频率(USART1 --72MHZ ,USAT2USART3 --36MHZ)
**
***********************************************************/
void Usartx_Init(USART_TypeDef *USARTx,u32 baud,u32 sysclk)
{
	if(USART1 == USARTx)
	{
			/*1.开时钟*/
		RCC->APB2ENR|=1<<2;//PA时钟
		RCC->APB2ENR|=1<<14;//串口时钟
		RCC->APB2RSTR|=1<<14;//串口复位
		RCC->APB2RSTR&=~(1<<14);//取消复位
		/*2.配置GPIO口*/
		GPIOA->CRH&=0xFFFFF00F;
		GPIOA->CRH|=0x000008B0;//上下拉输入,复用推挽输出	
		USART1->CR3|=1<<7;//DMA发送
		USART1->CR3|=1<<6;//DMA接收
		USART1->CR1|=1<<4;//IDLE(空闲帧中断)
		STM32_NVIC_SetPriority(USART1_IRQn,0,1);//设置优先级
	}
	else if(USART2 == USARTx)
	{
		/*1.开时钟*/
		RCC->APB2ENR|=1<<2;//PA时钟
		RCC->APB1ENR|=1<<17;//USART2时钟
		RCC->APB1RSTR|=1<<17;//开复位时钟
		RCC->APB1RSTR&=~(1<<17);//取消复位
		/*2.配置GPIO口*/
		GPIOA->CRL&=0xFFFF00FF;//清除原来寄存器中的值
		GPIOA->CRL|=0x00008B00;		
		#ifdef USART2_IRQ
			USART2->CR1|=1<<5;//串口2接收中断
			STM32_NVIC_SetPriority(USART2_IRQn,1,2);//设置优先级
		#endif
	}
	else if(USART3 == USARTx)
	{
		/*1.开时钟*/
		RCC->APB2ENR|=1<<3;//PB时钟
		RCC->APB1ENR|=1<<18;//USART3时钟
		RCC->APB1RSTR|=1<<18;//开复位时钟
		RCC->APB1RSTR&=~(1<<18);//取消复位
		/*2.配置GPIO口*/
		GPIOB->CRH&=0xFFFF00FF;
		GPIOB->CRH|=0x00008B00;	
		#ifdef USART3_IRQ
			USART3->CR1|=1<<5;//开启接收中断
			STM32_NVIC_SetPriority(USART3_IRQn,0,0);//设置优先级
		#endif
	}
	else return;
	/*3.配置串口核心寄存器*/
	USARTx->BRR=sysclk*1000000/baud;//设置波特率
	USARTx->CR1|=1<<2;//接收使能
	USARTx->CR1|=1<<3;//发送使能
	USARTx->CR1|=1<<13;//使能串口3
	#ifdef DMA_USART1_SEND //利用DMA完成数据收发
		DMA_CH5_Init((u32 )&USART1->DR,(u32 )usart1_rx_buff);//DMA配合串口1接收数据
		DMA_CH4_Init((u32 )&USART1->DR);
	#endif
}

4.串口1中断,DMA数据接收数据

u8 usart1_rx_buff[1024];//串口1接收数据缓冲区
u16 usart1_cnt=0;//保存数组下班
u8 usart1_flag;//接收完成标志符
void USART1_IRQHandler(void)
{
	U8 C;
	//清除标志:先读USART_SR,再读USART_DR
	if(USART1->SR&1<<4)//空闲帧
	{
		C=USART1->DR;
		C=c;
       // USART1->DR=c;
		Usart1_Receive_Data();//接收数据处理函数
	}
	USART1->SR=0;//清除标志位
}

/*************************串口接收数据函数********************/
void Usart1_Receive_Data(void)
{
	DMA1_Channel5->CCR&=~(1<<0);//关闭通道传输
	usart1_cnt=1024-DMA1_Channel5->CNDTR;//获取接收到是字符长度
	if(usart1_cnt>=1024)usart1_cnt=0;
	DMA1->IFCR|=1<<17;//清除标志位
	DMA1_Channel5->CNDTR=1024;//从新赋值
	DMA1_Channel5->CCR|=1<<0;//开启通道传输
	usart1_flag=1;
}

  5.串口数据发送

/****************串口发送字符串*****************************/
void Usart1_SendStr(u8 *str)
{
	#ifdef DMA_USART1_SEND
		DMA_CH4_Start(str,strlen((char *)str));
	#else
		while(*str!='�')
		{
			USART1->DR=*str++;
			while(!(USART1->SR&1<<7));
		}
	#endif
}

6.硬件初始化,DMA配合串口调试

int main()
{
	u8 key;
	Beep_Init();//蜂鸣器初始化
	Led_Init();//LED初始化
	Key_Init();//按键初始化
	Usartx_Init(USART1,115200,72);
	while(1)
	{
		key=Key_Scan();
		if(key)
		{
			Usart1_SendStr((u8 *)"DMA1配合串口收发数据不定长测试234556789rn");
		}
		if(usart1_flag)
		{
			usart1_rx_buff[usart1_cnt]='�';
			printf("%srn",usart1_rx_buff);
			usart1_flag=0;
		}
	}
}

7.运行效果

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储器
    +关注

    关注

    38

    文章

    7484

    浏览量

    163767
  • STM32F10x
    +关注

    关注

    1

    文章

    81

    浏览量

    20681
  • dma
    dma
    +关注

    关注

    3

    文章

    560

    浏览量

    100550
收藏 人收藏

    评论

    相关推荐

    DMA简介

    DMA直接存储器访问)目录文章目录DMA直接存储器访问)一、
    发表于 07-28 08:59

    DMA简介

    1. DMA简介直接存储器存取(DMA,Direct Memory Access)用来提供在外设
    发表于 08-16 08:30

    DMA直接存储器存取的主要功能是什么

    DMA 简介DMA(Direct Memory Access) —— 直接存储器存取,是单片机的
    发表于 01-26 06:35

    STM32的DMA简介

    1、DMA简介DMA(Direct Memory Access) :直接存储器存取,是单片机的一
    发表于 01-26 08:27

    DMA直接存储器访问与配置流程简介

    DMA配置流程三、DMA应用简单实例1. 存储器存储器(M2M)2. 存储器到USART串口(M2P)一、
    发表于 01-26 07:54

    STM32F2技术培训_直接存储器访问_DMA

    STM32F2技术培训_直接存储器访问_DMA
    发表于 12-03 17:51 0次下载

    DMA直接内存存取

    【*】程序简介 -工程名称:DMA直接内存存取 -实验平台: 秉火STM32 F429 开发板 -MDK版本:5.16 -ST固件库版本:1
    发表于 12-13 15:09 9次下载

    TMS320VC5505DSP直接存储器存取DMA)控制特点和操作的概述

     该文档描述了在TMS3VC5505/5504数字信号处理(DSP)上可用的直接存储器存取DMA)控制
    发表于 04-26 10:34 3次下载
    TMS320VC5505DSP<b class='flag-5'>直接</b><b class='flag-5'>存储器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)控制<b class='flag-5'>器</b>特点和操作的概述

    TMS320VC5501和TMS320VC5502DSP直接存储器存取DMA)控制详细描述

    本文描述了TMS320VC5501/TMS320VC5502数字信号处理(DSPS)的直接存储器存取DMA)控制
    发表于 04-26 15:41 10次下载
    TMS320VC5501和TMS320VC5502DSP<b class='flag-5'>直接</b><b class='flag-5'>存储器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)控制<b class='flag-5'>器</b>详细描述

    MSP430教程Chapt11-直接存储器存取DMA

    MSP430系列中的一些设备支持多通道直接存储器地址(DMA)控制,可以在没有CPU干预的情况下将数据从一个位置移动到另一个位置。
    发表于 05-07 09:30 2次下载
    MSP430教程Chapt11-<b class='flag-5'>直接</b><b class='flag-5'>存储器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)

    随机存取存储器为什么叫随机存取存储器(结构、特点、分类、优缺点)

    随机存取存储器(random access memory,RAM)又称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作
    发表于 05-17 17:04 2.1w次阅读

    随机存取存储器的最大特点

    随机存取存储器(randomaccessmemory,RAM)又称作“随机存储器”,是与CPU直接交换数据的内部存储器,也叫主存(内存)。它可以随时读写,而且速度很快,通常作为操作系统
    的头像 发表于 11-24 10:59 4.4w次阅读

    静态随机存取存储器简介及应用

    SRAM(Static Random Access Memory),即静态随机存取存储器。它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据
    发表于 07-16 10:44 5655次阅读
    静态随机<b class='flag-5'>存取存储器</b><b class='flag-5'>简介</b>及应用

    STM32学习笔记(7)——DMA直接存储器访问

    DMA配置流程三、DMA应用简单实例1. 存储器存储器(M2M)2. 存储器到USART串口(M2P)一、
    发表于 12-02 14:06 3次下载
    STM32学习笔记(7)——<b class='flag-5'>DMA</b><b class='flag-5'>直接</b><b class='flag-5'>存储器</b>访问

    STM32F103 中级篇 22 DMA 直接存储器访问

    22.1直接存储器访问22.1.1 DMA功能框图讲解DMA(Direct Memory Access)—直接
    发表于 12-16 16:59 2次下载
    STM32F103 中级篇 22 <b class='flag-5'>DMA</b> <b class='flag-5'>直接</b><b class='flag-5'>存储器</b>访问