DMA和ADC传输问题

2019-08-23 15:41发布

#include "dma.h"                                                                                                                                                     
#include "delay.h"                 

//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chxMA通道选择,@ref DMA_channel DMA_Channel_0~DMA_Channel_7
//par:外设地址
//mar:存储器地址
//ndtr:数据传输量  
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{

        DMA_InitTypeDef  DMA_InitStructure;
       
        if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
               
        }else
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//DMA1时钟使能
        }
  DMA_DeInit(DMA_Streamx);
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//等待DMA可配置
       
  /* 配置 DMA Stream */
  DMA_InitStructure.DMA_Channel = chx;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//存储器到外设模式
  DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据长度:16位

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式

  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
       

}
//开启一次DMA传输
//DMA_StreamxMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量  
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr)
{

        DMA_Cmd(DMA_Streamx, DISABLE);                      //关闭DMA传输
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}        //确保DMA可以被设置  
               
        DMA_SetCurrDataCounter(DMA_Streamx,ndtr);          //数据传输量  

        DMA_Cmd(DMA_Streamx, ENABLE);                      //开启DMA传输
}          

#include "adc.h"
void My_adc_init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        ADC_InitTypeDef ADC_InitStruct;
        ADC_CommonInitTypeDef ADC_CommonInitStruct;
       
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1,ENABLE);
        //初始化ADC
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
       
        ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;
        ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div2;
        ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
        ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_10Cycles;
        ADC_CommonInit(&ADC_CommonInitStruct);
       
        ADC_InitStruct.ADC_Resolution=ADC_Resolution_12b;
        ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStruct.ADC_NbrOfConversion=ADC_Channel_5;
        ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;
        ADC_InitStruct.ADC_ScanConvMode=DISABLE;
        ADC_InitStruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
        ADC_Init(ADC1,&ADC_InitStruct);
       
//        ADC_DMACmd(ADC1,ENABLE);
        ADC_Cmd(ADC1,ENABLE);
}
u16 get_result(void)
{       
        u16 ADC_result;
        ADC_RegularChannelConfig(ADC1,5,1,ADC_SampleTime_480Cycles);//每次转换需要配置规则模式
        ADC_SoftwareStartConv(ADC1);
        while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==DISABLE);
        ADC_result=ADC_GetConversionValue(ADC1);
        ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
        return ADC_result;
}       


#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "adc.h"
#include "led.h"
#include "dma.h"

#define USART1_DR_BASE ((u32)0x40011004)
#define ADC1_DR_BASE  ((u32)0x4001204c)

#define SENDSIZE 1

__IO u16 result_data;

int main(void)
{
        u16 i;
        u8 j;
        delay_init(168);
        uart_init(115200);
        LED_Init();
        My_adc_init();
        MYDMA_Config(DMA2_Stream0,DMA_Channel_0,ADC1_DR_BASE,(u32)&result_data,SENDSIZE);
        while(1)
        {
                ADC_DMACmd(ADC1,ENABLE);
                MYDMA_Enable(DMA2_Stream0,SENDSIZE);
                ADC_RegularChannelConfig(ADC1,5,1,ADC_SampleTime_480Cycles);//每次转换需要配置规则模式
                ADC_SoftwareStartConv(ADC1);
                while(1)
                {
                if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==ENABLE)
                        {
                                ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
                                break;
                        }
                LED1=!LED1;
                delay_ms(500);
                }
                while(1)
                {
                        if(DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==ENABLE)
                        {
                                DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
                                break;
                        }
                LED0=!LED0;
                delay_ms(500);
                       
                }
                printf("the result is %d ",result_data);

        }
}

请问我设置的是AD连续采样模式,和DMA循环模式。为什么串口显示如下
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
the result is 519
为什么不更新AD转换结果?求助

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
mxiaotao
1楼-- · 2019-08-23 21:05
问题已经找到,是由于在使能DMA请求的过程中,ADC产生了溢出,停止了ADC请求,只要将溢出位清零,然后再初始化就可以了。
mxiaotao
2楼-- · 2019-08-24 02:39
 精彩回答 2  元偷偷看……
vivian
3楼-- · 2019-08-24 03:13
mxiaotao 发表于 2017-3-23 10:09
求高手帮忙

你好 我最近也在学习这个 我想用读取两个模拟量 需要用到DMA 么
vivian
4楼-- · 2019-08-24 04:28
你好 可以一起请教一下吗
mxiaotao
5楼-- · 2019-08-24 07:52
vivian 发表于 2017-3-28 19:49
你好 我最近也在学习这个 我想用读取两个模拟量 需要用到DMA 么

这个好像一般不需要,DMA好像一般用于比较大的数据保存数据,不过也可以通过这个练习一下
mxiaotao
6楼-- · 2019-08-24 12:22
mxiaotao 发表于 2017-3-29 14:38
这个好像一般不需要,DMA好像一般用于比较大的数据保存数据,不过也可以通过这个练习一下

遇到问题可以大家讨论一下

一周热门 更多>