zoukankan      html  css  js  c++  java
  • STM32f103的数电采集电路的DMA设计和使用优化程序

    DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAMI/O设备开辟一条直接传送数据的通路,能使CPU的效率大为提高。

    DMA设置的一般步骤可以总结为如下几个步骤:

    1.DMA时钟使能

    2.DMA设置复位

    3.设置DMA基地址,内存地址,输出方向参数

    4.设置DMA数据大小,优先级,使用通道参数

    5.DMA工作方式初始化

    6.使能DMA

    7.编写中断处理函数

     

    前端采集模块的DMA使用主要用于ADC采集结果的传输和USART串口的数据发送传输。根据《stm32中文参考手册》的DMA请求一览表,选用了DMA1的通道1作为ADC1的数据传输通道,以及DMA1通道4作为和USART串口的数据发送传输通道。此处采用了单个DMA复用多通道的设计,是因为DMA速度足以完成这些任务,而且留下其他DMA资源以便项目以后可以扩展,达到节省资源的目的。


    USART使用DMA发送数据配置和使能代码

     

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


    ADC使用DMA传送多通道数据配置和使能代码

     

    1. //DMA1的各通道配置  
    2. //这里的传输形式是固定的,这点要根据不同的情况来修改  
    3. //从存储器->外设模式/8位数据宽度/存储器增量模式  
    4. //DMA_CHx:DMA通道CHx  
    5. //cpar:外设地址  
    6. //cmar:存储器地址  
    7. //cndtr:数据传输量   
    8. void DMA_ADC_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)  
    9. {  
    10.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //使能DMA传输  
    11.       
    12.     DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值  
    13.     DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址  
    14.     DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址  
    15.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地  
    16.     DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小  
    17.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变  
    18.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增  
    19.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位  
    20.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位  
    21.     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式  
    22.     DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级  
    23.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输  
    24.     DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道  
    25.   
    26. }  
    27.   
    28. //开启一次DMA传输  
    29. void DMA_ADC_Enable(DMA_Channel_TypeDef*DMA_CHx)  
    30. {   
    31.     DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道  
    32.     DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道   
    33. }  


    这里需要注意的是USART使用DMA发送数据需要每一次都重新使能,即每发送一次数据使能一下。

    ADC使用DMA传送多通道数据则只需要使能一次就可以自动循环工作,只需从数组空间读取ADC数据。

  • 相关阅读:
    DOM对象模型接口规范中的四个基本接口
    js中几种实用的跨域方法原理详解(转)
    关于ie6/7下的z-index
    Mysql++学习(五)------专用SQL结构
    Mysql++学习(四)------模板查询
    Mysql++学习(三)------举个栗子
    Mysql++学习(二)------Mysql++简述
    Mysql++学习(一)------mysql编译安装
    epoll模型实例
    锁、页类型
  • 原文地址:https://www.cnblogs.com/zym0805/p/7049168.html
Copyright © 2011-2022 走看看