DMA就是将一个地址空间复制到另外一个地址空间。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备直接传送数据,使CPU的效率大大的提高了。

  stm一般有两个DMA控制器,DMA1有7通道。DMA2有5个通道。

  STM32 的 DMA 有以下一些特性:   

  ●每个通道都直接连接专用的硬件 DMA 请求,每个通道都同样支持软件触发。

这些功能通过软件来配置。

  ●在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),

假如在相等优先权时由硬件决定(请求 0 优先于请求 1,依此类推) 。

  ●独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。

源和目标地址必须按数据传输宽度对齐。

  ●支持循环的缓冲器管理

  ●每个通道都有 3 个事件标志(DMA 半传输, DMA 传输完成和 DMA 传输出错),

这3个事件标志逻辑或成为一个单独的中断请求。

  ●存储器和存储器间的传输

  ●外设和存储器,存储器和外设的传输

  ●闪存、 SRAM、外设的 SRAM、 APB1 APB2 和 AHB 外设均可作为访问的源和目标。

  ●可编程的数据传输数目:最大为 65536

  我们可以通过DMA中断状态寄存器(DMA_ISR)来获取当前DMA传输的状态。通过

DMA中断标志清除寄存器(CMA_IFCR)清除中断状态寄存器对应的位。

1)使能 DMA 时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 时钟
2)初始化 DMA 通道 4 参数

 DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = &USART1->DR; //DMA 外设 ADC 基地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA 内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = ; //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_Init(DMA_CHx, &DMA_InitStructure); //根据指定的参数初始化

3) 使能串口 DMA 发送

进行 DMA 配置之后,我们就要开启串口的 DMA 发送功能,使用的函数是:
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
如果是要使能串口 DMA 接受,那么第二个参数修改为 USART_DMAReq_Rx 即可。

4) 使能 DMA1 通道 4,启动传输。

使能串口 DMA 发送之后,我们接着就要使能 DMA 传输通道:
DMA_Cmd(DMA_CHx, ENABLE);

5) 查询 DMA 传输状态
在 DMA 传输过程中,我们要查询 DMA 传输通道的状态,使用的函数是:
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
比如我们要查询 DMA 通道 4 传输是否完成,方法是:
DMA_GetFlagStatus(DMA2_FLAG_TC4);
这里还有一个比较重要的函数就是获取当前剩余数据量大小的函数:
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
比如我们要获取 DMA 通道 4 还有多少个数据没有传输,方法是:
DMA_GetCurrDataCounter(DMA1_Channel4);

 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 所指示的通道
}

知识来源:STM32F1 开发指南

stm32 DMA配置的更多相关文章

  1. STM32 DMA使用详解

    DMA部分我用到的相对简单,当然,可能这是新东西,我暂时还用不到它的复杂功能吧.下面用问答的形式表达我的思路. DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数 ...

  2. stm32 DMA数据搬运 [操作寄存器+库函数](转)

    源:stm32 DMA数据搬运 [操作寄存器+库函数]        DMA(Direct Memory Access)常译为“存储器直接存取”.早在Intel的8086平台上就有了DMA应用了.   ...

  3. STM32 DMA简述

    STM32 DMA简述 DMA (Direct Memory Access) 直接内存存储器,在做数据传输时能够大大减轻CPU的负担. DMA的作用 DMA提供了一个关于数据的高数传输通道,这个通道不 ...

  4. stm32时钟配置总结

    stm32时钟配置时钟源: 1,HSE(高速外部时钟)即常见的外接8M晶振方案: 2,HSI(高速内部时钟) 即8M内部振荡时钟方案: 3,LSE(低速外部时钟)即常见的32.768Khz晶振方案: ...

  5. STM32 GPIO 配置之ODR, BSRR, BRR 详解

    STM32 GPIO 配置之ODR, BSRR, BRR 详解 用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态. ODR寄存器可读可写:既能 ...

  6. 【STM32】STM32串口配置的一般步骤(库函数)

    STM32串口配置的一般步骤(库函数)(1)串口时钟使能:RCC_APBxPeriphClockCmd();    GPIO时钟使能:RCC_AHBxPeriphClockCmd();(2)引脚复用映 ...

  7. STM32CubeMX 多通道 ADC DMA 配置 测试小程序

    要点: 1.STM32F103C8T6单片机 2.ADC+DMA 多通道 重点是ADC+DMA配置,ADC+DMA配置如下 其他配置略略略略. 然后各位自行直看.ioc文件,生成代码后在while之前 ...

  8. STM32—DMA存储器到外设

    DMA目录 DMA简介 DMA框图 DMA传输数据分析 1.传输的方向 2.传输的数量 3.传输的模式 代码部分 DMA初始化结构体 USART配置函数 DMA配置函数 主函数 DMA简介 DMA(D ...

  9. STM32 DMA模块的配置与使用

    DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输.无须CPU的干预,通过DMA数据可以快速地移动.这就节省了CPU的资源来做其他操作. 有多少个DMA资源 ...

随机推荐

  1. android中 检查网络连接状态的变化,无网络时跳转到设置界面

    1:在AndroidManifest.xml中加一个声明 <receiver android:name="NetCheckReceiver">    <inten ...

  2. URAL 1501 Sense of Beauty

    URAL 1501 思路: dp+记忆化搜索 状态:dp[i][j]表示选取第一堆前i个和第二堆前j的状态:0:0多1个              1:0和1相等                2:1 ...

  3. git/ssh备查文档

    配置多个ssh key: 待更新 git速查表: git remote set-url origin(远程仓库名称) https://xxxxx/ProjectName.git  从ssh切换至htt ...

  4. php.ini配置说明

    1.设置时区为中国时区 date.timezone = PRC 2.设置支持MySql数据 extension=php_pdo_mysql.dll 直接将这个注释打开就OK了 3.让PHP支持简写&l ...

  5. 关Java的内存模型(JMM)

    JMM的关键技术点都是围绕着多线程的原子性.可见性和有序性来建立的 一.原子性(Atomicity) 原子性是指一个操作是不可中断的.即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程 ...

  6. memcached客户端连接建立过程笔记

    memcached在启动过程初始化server_sockets时,根据启动参数决定系统是进行tcp监听还是udp监听,这里暂时只关注tcp的情况. server_socket在初始化时会向系统申请监听 ...

  7. 原生js实现选项卡

    html代码: <div class="tab"> <ul> <li class="selected">图片</li& ...

  8. 『Kaggle』Sklearn中几种分类器的调用&词袋建立

    几种分类器的基本调用方法 本节的目的是基本的使用这些工具,达到熟悉sklearn的流程而已,既不会设计超参数的选择原理(后面会进行介绍),也不会介绍数学原理(应该不会涉及了,打公式超麻烦,而且近期也没 ...

  9. iterator not dereferencable问题

    STL中的迭代器总是出现各种问题,这个是我在打表达式求值时碰到的... 综合网上的答案,一般来说有两种情况: 第一:访问了非法位置. 一般来说可能在queue为空时取front(),rear(),或者 ...

  10. UVA-10995 Educational Journey

    The University of Calgary team qualified for the 28th ACM International Collegiate Programming Conte ...