STM32系列第21篇--DMA

发布者:TechGuru123最新更新时间:2017-09-22 来源: eefocus关键字:STM32系列  DMA 手机看文章 扫描二维码
随时随地手机看文章

简介:

DMA全称DirectMemory Access,即直接存储器访问。 
比如串口发送用和不用DMA当然都可以发送。不用DMA发送是需要单片机实时参与,由单片机一个一个地发送数据并进行监控。但是如果用DMA,设置了起始地址,数据大小等参数后,就直接由专门的一个DMA模块进行数据发送,发送过程中单片机无需参与。发送完后会产生中断告知单片机。由此可知用DMA可以节省单片机资源,让单片可以在同一时间里干更多事。 
STM32最多有2个DMA控制器(DMA2仅存在大容量产品中),DMA1有7个通道(通道1~通道7)。DMA2有5个通道(通道1~通道5)。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起来协调各个DMA请求的优先权。

请求列表:

DMA1的7个通道的请求列表: 
这里写图片描述

DMA2的5个通道的请求列 
这里写图片描述

CODE:

用DMA进行串口发送。

//dma.c#include "dma.h"DMA_InitTypeDef DMA_InitStructure;u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度       //DMA1的各通道配置//这里的传输形式是固定的,这点要根据不同的情况来修改//从存储器->外设模式/8位数据宽度/存储器增量模式//DMA_CHx:DMA通道CHx//cpar:外设地址//cmar:存储器地址//cndtr:数据传输量 void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输
  DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
    DMA1_MEM_LEN=cndtr;
    DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
    DMA_InitStructure.DMA_BufferSize = cndtr;  //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没有设置为内存到内存传输
    DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器} 
//开启一次DMA传输void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{ 
    DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
    DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小
    DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道 }   

main.c
#include "led.h"#include "delay.h"#include "key.h"#include "sys.h"#include "lcd.h"#include "usart.h"   #include "dma.h"#define SEND_BUF_SIZE 8200  //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍.u8 SendBuff[SEND_BUF_SIZE]; //发送数据缓冲区const u8 TEXT_TO_SEND[]={"ALIENTEK WarShip STM32F1 DMA 串口实验"}; int main(void)
 {   
    u16 i;    u8 t=0;    u8 j,mask=0;    float pro=0;//进度
    delay_init();               //延时函数初始化     
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);      //串口初始化为115200
    LED_Init();                 //初始化与LED连接的硬件接口
    LCD_Init();                 //初始化LCD    
    KEY_Init();                     //按键初始化         
    MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,SEND_BUF_SIZE);//DMA1通道4,外设为串口1,存储器为SendBuff,长度SEND_BUF_SIZE.
    POINT_COLOR=RED;            //设置字体为红色 
    LCD_ShowString(30,50,200,16,16,"WarShip STM32");    
    LCD_ShowString(30,70,200,16,16,"DMA TEST"); 
    LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
    LCD_ShowString(30,110,200,16,16,"2015/1/15");   
    LCD_ShowString(30,130,200,16,16,"KEY0:Start");    //显示提示信息    
    j=sizeof(TEXT_TO_SEND);    
    for(i=0;i=j)//加入换行符
        {            if(mask)
            {
                SendBuff[i]=0x0a;
                t=0;
            }else 
            {
                SendBuff[i]=0x0d;
                mask++;
            }   
        }        else//复制TEXT_TO_SEND语句
        {
            mask=0;
            SendBuff[i]=TEXT_TO_SEND[t];
            t++;
        }          
    }        
    POINT_COLOR=BLUE;//设置字体为蓝色    
    i=0;    while(1)
    {
        t=KEY_Scan(0);        if(t==KEY0_PRES)//KEY0按下
        {
            LCD_ShowString(30,150,200,16,16,"Start Transimit....");
            LCD_ShowString(30,170,200,16,16,"   %");//显示百分号
            printf("\r\nDMA DATA:\r\n");        
          USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送      
            MYDMA_Enable(DMA1_Channel4);//开始一次DMA传输!      
            //等待DMA传输完成,此时我们来做另外一些事,点灯
            //实际应用中,传输数据期间,可以执行另外的任务
            while(1)
            {                if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET) //判断通道4传输完成
                {
                    DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
                    break; 
            }
                pro=DMA_GetCurrDataCounter(DMA1_Channel4);//得到当前还剩余多少个数据
                pro=1-pro/SEND_BUF_SIZE;//得到百分比   
                pro*=100;      //扩大100倍
                LCD_ShowNum(30,170,pro,3,16);     
            }               
            LCD_ShowNum(30,170,100,3,16);//显示100%     
            LCD_ShowString(30,150,200,16,16,"Transimit Finished!");//提示传送完成
        }
        i++;
        delay_ms(10);        if(i==20)
        {
            LED0=!LED0;//提示系统正在运行   
            i=0;
        }          
    }
}


关键字:STM32系列  DMA 引用地址:STM32系列第21篇--DMA

上一篇:STM32系列第22篇--I2C
下一篇:STM32系列第20篇--DAC

推荐阅读最新更新时间:2024-03-16 15:38

裸机系列——DMA工作
DMA 优点是其进行数据传输时不需要 CPU 的干涉,可以大大提高 CPU 的工作效率。 DMA 大容量数据传输中非常重要,比如图像数据传输, SD 卡数据传输, USB 数据传输等等。 S3C2410 有四个 DMA ,每个 DMA 支持工作方式基本相同,但支持的 source Dest 可能略有不同。 那么怎么使用 DMA 呢, S3C2410 内部集成了 DMA 控制器,我们只需要简单的配置一下寄存器就可以实现 DMA 的传输了。 步骤与要点: 1.数据从哪里来,到哪里去? 使用 DMA 当然首先我们要知道数据的流向, DISRCx 寄存器是 DMA 初始源寄存器存放了数据的源地址。 DIDSTx 是 DMA
[单片机]
stm32 DMA性能资料
为了快速传送一个数据块,使用 DMA 传送程序(Mem to Mem 16bits) 测量了一下传送的时间,128个16b数据大约用了12us (72Mhz 时钟)。 换句话来说,STM32 DMA 性能为10M/s 又使用memcpy 来比对一下,用时约4us ,显然memcpy 要快很多。 btw, 在ST的手册里面未见对DMA性能的表述。 ------------------------------ ---- DMA传送数据的速度不会比CPU直接传送数据快,因为总 线频率没有变。 当CPU也在运行执行指令时, DMA传送数据的速度会比CPU直接传送数据慢, 这是因为DMA与CPU分时使用同一条总线的
[单片机]
STM32 DMA详解——一串口为例
一. DMA原理: DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依于 CPU 的大量 中断 负载。否则,CPU 需要从 来源 把每一片段的资料复制到 暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。 DMA 传输将数据从一个地址空间复制到另外一个地址空间。当 CPU 初始化这个传输动作,传输动作本身是由 DMA 控制器 来实行和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。像是这样的操作并没有让处理器工作拖延,反而可以被重新排程去处理其他的工作。 二.STM32使用DMA 1.D
[单片机]
STM32F407ZET6 USART DMA方式收发数据
串口采用DMA方式收发数据有两种不同的方式,第一种方式:采用DMA传输完成中断进行发送和接收;第二种方式:采用串口总线空闲方式收发数据。这两种方式第二种方式更好一些,因为第二种方式可以收发不定长度的数据帧,然而第一种方式不能。但是第二种方式的逻辑复杂一些,收发过程之前都要判断总线是否是空闲。 在此,以USART2的DMA收发方式举例: 一、使用DMA传输完成中断收发 整体思路:上位机发送四个字节的数据,STM32接收完成后进入DMA中断中,发送下位机STM32定义好的数据给上位机并且清除DMA传输完成中断标志位,最后进入发送完成中断,关闭发送通道,清除DMA发送完成标志位。 在上述思路之前,要进行的自然是串口配置、DMA配置以及中
[单片机]
linux-2.6.24.4中s3c2410和dma有关的函数的分析
首先介绍s3c2410与DMA相关的寄存器。 s3c2410共有4通道的dma,每通道9个寄存器,共36个。 1、DISRCn 该寄存器保存待传送数据的源地址。 2、DISRCCn 源控制寄存器。位1表示数据源的总线类型,位0表示地址是否自动增减。 3、DIDSTn 该寄存器保存待传送数据的目的地址。 4、DIDSTCn 目的控制寄存器。位1表示目的地址的总线类型,位0表示地址是否自动增减。 5、DCON DMA控制寄存器。 6、DSTATn DMA状态寄存器。 7、DCSRCn 当前源地址寄存器。 8、DCDSTn 当前目的地址寄存器。 9、DMASKTRIGn DMA MASK寄存器。
[单片机]
STM32 DMA USART串口发送解析
数据传输时要从支持那些相关的标准?传输的速度?什么时候开始?什么时候结束?传输的内容?怎样防止通信出错?数据量大的时候怎么弄?硬件怎么连接出发,当然对于stm32还要熟悉库函数的功能 具起来rs232和485电平的区别硬件外围芯片,波特率(反映传一位的时间),起始位和停止位,数据宽度,校验,硬件流控制,相应连接电脑时的接口怎么样的。配置,使用函数,中断,查询并结合通信协议才算了解了串口使用。 以上是基础,当然stm很多相关复用功能,支持同步单向通信和半双工单线通信,支持局部互联网、智能卡协议和红外数据组织相关规范,以及调制解调器操作,运行多处理器通信。同时可以使用DMA方式进行高速数据通信。注意Print函数时间问题,尝试通过DM
[单片机]
ADSP-21535 Blackfin的Mem DMA高速通信
摘要:针对ADSP-21535 Blackfin 的Mem DMA 高速通信中的关键技术进行了讨论,分析了系统的内存管理,对DMA的相关寄存器的配置进行了详细讲解,并给出了具体实例。对多种内存之间的DMA列出了实际的指标评测,为该系列DSP工程应用的高速通信设计提供了重要参考。 关键词: ADSP-21535, Blackfin Mem DMA ADSP-21535 Blackfin 是美国AD公司和Intel 公司于2001年底联合推出的一款定点DSP, RISC指令结构,运作高效,具有十分优异的性能。该DSP具有300MHz的主频,2个40bit的MAC(乘加器)和2个32bit的ALU(算术逻辑单元),4个8bit的视频
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved