zoukankan      html  css  js  c++  java
  • stm32 DMA配置

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

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

      STM32 的 DMA 有以下一些特性:   

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

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

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

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

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

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

      ●支持循环的缓冲器管理

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

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

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

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

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

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

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

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

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

     1 DMA_InitTypeDef DMA_InitStructure;
     2 DMA_InitStructure.DMA_PeripheralBaseAddr = &USART1->DR; //DMA 外设 ADC 基地址
     3 DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA 内存基地址
     4 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //从内存读取发送到外设
     5 DMA_InitStructure.DMA_BufferSize = 64; //DMA 通道的 DMA 缓存的大小
     6 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
     7 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
     8 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //8 位
     9 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 8 位
    10 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
    11 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA 通道 x 拥有中优先级
    12 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非内存到内存传输
    13 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);

     1 void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
     2 {
     3      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //使能DMA传输
     4     
     5   DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
     6 
     7     DMA1_MEM_LEN=cndtr;
     8     DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设基地址
     9     DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
    10     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
    11     DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
    12     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
    13     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
    14     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
    15     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
    16     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
    17     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 
    18     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
    19     DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
    20           
    21 } 
    22 //开启一次DMA传输
    23 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
    24 { 
    25     DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
    26      DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小
    27      DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道 
    28 }      

    知识来源:STM32F1 开发指南

  • 相关阅读:
    Spring MVC系列之Hello World(SpringBoot)(六)
    SpringBoot系列之注解@Autowired VS @Qualifier VS @Primary(五)
    SpringBoot系列之注解@Component VS @Bean(四)
    SpringBoot系列之@PropertySource和@Value注解(二)
    SpringBoot系列之入门篇(一)
    不要叫我,我会叫你(控制反转原理)
    EntityFramework Core 3多次Include导致查询性能低之解决方案
    EntityFramework Core 3.0查询
    Java入门系列之集合HashMap源码分析(十四)
    浅析性能测试策略及适用场景
  • 原文地址:https://www.cnblogs.com/zengsf/p/7217412.html
Copyright © 2011-2022 走看看