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数据。

  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/zym0805/p/7049168.html
Copyright © 2011-2022 走看看