博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
stm32之DMA
阅读量:2140 次
发布时间:2019-04-30

本文共 4098 字,大约阅读时间需要 13 分钟。

DMA

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传

输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作通道配置过程下面是配置DMA通道x的过程(x代表通道号):
1. 在DMA_CPARx寄存器中设置外设寄存器的地址。发生外设数据传输请求时,这个地址将是数据传输的源或目标。
2. 在DMA_CMARx寄存器中设置数据存储器的地址。发生外设数据传输请求时,传输的数据将从这个地址读出或写入这个地址。
3. 在DMA_CNDTRx寄存器中设置要传输的数据量。在每个数据传输后,这个数值递减。
4. 在DMA_CCRx寄存器的PL[1:0]位中设置通道的优先级。
5. 在DMA_CCRx寄存器中设置数据传输的方向、循环模式、外设和存储器的增量模式、外设和存储器的数据宽度、传输一半产生中断或传输完成产生中断。
6. 设置DMA_CCRx寄存器的ENABLE位,启动该通道

1.串口DMA数据传输!!(内存到外设)

/**

  USART1 TX DMA 配置,内存到外设(USART1->DR)
  */
void USART_DMA_init(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  /*开启DMA时钟*/

  RCC_AHB1PeriphClockCmd(DEBUG_USART_DMA_CLK, ENABLE);
 
  /* 复位初始化DMA数据流 */
  DMA_DeInit(DEBUG_USART_DMA_STREAM);

  /* 确保DMA数据流复位完成 */

  while (DMA_GetCmdStatus(DEBUG_USART_DMA_STREAM) != DISABLE)  {
  }

  /*usart1 tx对应dma2,通道4,数据流7*/    

  DMA_InitStructure.DMA_Channel = DEBUG_USART_DMA_CHANNEL;  
  /*设置DMA源:串口数据寄存器地址*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = DEBUG_USART_DR_BASE;    
  /*内存地址(要传输的变量的指针)*/
  DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SendBuff;
  /*方向:从内存到外设*/        
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;    
  /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/    
  DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
  /*外设地址不增*/        
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  /*内存地址自增*/
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    
  /*外设数据单位*/    
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  /*内存数据单位 8bit*/
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;    
  /*DMA模式:不断循环*/
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;    
  /*优先级:中*/    
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;      
  /*禁用FIFO*/
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;        
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;    
  /*存储器突发传输 16个节拍*/
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;    
  /*外设突发传输 1个节拍*/
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;    
  /*配置DMA2的数据流7*/           
  DMA_Init(DEBUG_USART_DMA_STREAM, &DMA_InitStructure);
 
  /*使能DMA*/
  DMA_Cmd(DEBUG_USART_DMA_STREAM, ENABLE);
 
  /* 等待DMA数据流有效*/
  while(DMA_GetCmdStatus(DEBUG_USART_DMA_STREAM) != ENABLE)
  {
  }   
}

2.存储器到存储器数据传输配置

/**

  * DMA传输配置
  */
static void DMA_init(void)
{
  DMA_InitTypeDef  DMA_InitStructure;
  __IO uint32_t    Timeout = TIMEOUT_MAX;
    
  /* 使能DMA时钟 */
  RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE);
 
  /* 复位初始化DMA数据流 */
  DMA_DeInit(DMA_STREAM);

  /* 确保DMA数据流复位完成 */

  while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE)
  {
  }
 
  /* DMA数据流通道选择 */
  DMA_InitStructure.DMA_Channel = DMA_CHANNEL;                                              //   1
  /* 源数据地址 */
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aSRC_Const_Buffer;      //   2
  /* 目标地址 */
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aDST_Buffer;                  //    3
  /* 存储器到存储器模式 */
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;                              //4
  /* 数据数目 */
  DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE;                           //4
  /* 使能自动递增功能 */
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;                  //5
  /* 使能自动递增功能 */
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                      //6 存储器
  /* 源数据是字大小(32位) */
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;               //7  外设
  /* 目标数据也是字大小(32位) */
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;                  //8
  /* 一次传输模式,存储器到存储器模式不能使用循环传输 */
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                       //9
  /* DMA数据流优先级为高 */
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                  //10
  /* 禁用FIFO模式 */
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                    //11
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;            //12
  /* 单次模式 */
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;             //13
  /* 单次模式 */
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;        //14
  /* 完成DMA数据流参数配置 */
  DMA_Init(DMA_STREAM, &DMA_InitStructure);
 
  /* 清除DMA数据流传输完成标志位 */
  DMA_ClearFlag(DMA_STREAM,DMA_FLAG_TCIF);
 
  /* 使能DMA数据流,开始DMA数据传输 */
  DMA_Cmd(DMA_STREAM, ENABLE);

  /* 检测DMA数据流是否有效并带有超时检测功能 */

  Timeout = TIMEOUT_MAX;
  while ((DMA_GetCmdStatus(DMA_STREAM) != ENABLE) && (Timeout-- > 0))
  {
  }
   
  /* 判断是否超时 */
  if (Timeout == 0)
  {
    /* 超时就让程序运行下面循环:RGB彩色灯闪烁 */
    while (1)
    {      
      LED_RED;
      Delay(0xFFFFFF);
      LED_RGBOFF;
      Delay(0xFFFFFF);
    }
  }
}

应用:主函数中

  /* 等待DMA传输完成 */

  while(DMA_GetFlagStatus(DMA_STREAM,DMA_FLAG_TCIF)==DISABLE)
  {
    
  }

 

转载地址:http://qbtgf.baihongyu.com/

你可能感兴趣的文章
Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结
查看>>
Loadrunner之https协议录制回放报错如何解决?(九)
查看>>
python中xrange和range的异同
查看>>
列表、元组、集合、字典
查看>>
【Python】easygui小甲鱼
查看>>
【Python】关于Python多线程的一篇文章转载
查看>>
【Pyton】【小甲鱼】文件
查看>>
【Pyton】【小甲鱼】永久存储:腌制一缸美味的泡菜
查看>>
【Pyton】【小甲鱼】异常处理:你不可能总是对的
查看>>
APP性能测试工具
查看>>
【Pyton】【小甲鱼】类和对象
查看>>
压力测试工具JMeter入门教程
查看>>
作为一名软件测试工程师,需要具备哪些能力
查看>>
【Pyton】【小甲鱼】类和对象:一些相关的BIF(内置函数)
查看>>
【Pyton】【小甲鱼】魔法方法
查看>>
单元测试需要具备的技能和4大阶段的学习
查看>>
【Loadrunner】【浙江移动项目手写代码】代码备份
查看>>
Python几种并发实现方案的性能比较
查看>>
[Jmeter]jmeter之脚本录制与回放,优化(windows下的jmeter)
查看>>
Jmeter之正则
查看>>