ADC采集和DAC输出不能同时进行

2019-07-20 15:47发布

最近在做ADC+DAC。大概就是ADC采集一个正弦波,DMA存到一个数组里面。再用DAC把这个数组里面的值输出。目前ADC和DAC这俩部分都可以单独工作了。但是,我昨天把这两部分连在一起时,发生了一个奇观现象。
问题就是,在main.c里面  bsp_InitADC(); DAC_Mode_Init();   这两个函数不能同时作用。我注释掉ADC,DAC就可以输出正弦波。
我注释掉DAC,ADC就可以打印出采样值。不知道是什么原因???



[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"

#include "stdio.h"
#include "adc.h"
#include "dac.h"

#define  ADC_DMA_SIZE 2

extern volatile uint16_t ADC1ConvertedValue[ADC_DMA_SIZE];
extern __IO uint32_t ADC1ConvertedVoltage;
float ADC_ConvertedValueLocal;

int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);     //
        delay_init(168);    //
        uart_init(115200);        //

        bsp_InitADC();           //ADC1 channel10 DMA2 PC0
        DAC_Mode_Init();        // DAC
       
        while(1)
        {
                uint16_t i;
                 ADC1ConvertedVoltage = 0;
               
          for( i=0 ; i<ADC_DMA_SIZE ; i++ )
                        {
                                ADC1ConvertedVoltage += ADC1ConvertedValue;
                        }
            printf("%d; ", ADC1ConvertedVoltage/2);

        }
       
}
[/mw_shl_code]


ADC采集部分,我用的是ADC1——channel10,即PC0。再用DMA2传输数据。目前暂时在while死循环里面串口打印查看ADC采集的数据
[mw_shl_code=c,true]#include "adc.h"
#include "delay.h"

#define  ADC_DMA_SIZE  32

/* ±&#228;á&#191; ----------------------------------------------------------------------*/
__IO uint16_t ADC1ConvertedValue[ ADC_DMA_SIZE ];
__IO uint32_t ADC1ConvertedVoltage ;


/*
*********************************************************************************************************
*        oˉ êy &#195;&#251;: bsp_InitADC
*        1|&#196;ü&#203;μ&#195;÷: ADC3&#245;ê&#188;&#187;ˉ
*        D&#206;    2&#206;: &#206;T
*        ·μ &#187;&#216; &#214;μ: &#206;T
*********************************************************************************************************
*/
void bsp_InitADC(void)
{  
    ADC_InitTypeDef       ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    DMA_InitTypeDef       DMA_InitStructure;
    GPIO_InitTypeDef      GPIO_InitStructure;
//          NVIC_InitTypeDef        NVIC_InitStructure;

    /* ê1&#196;ü ADC1, DMA2 oí GPIO ê±&#214;ó ****************************************/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    /* DMA2 Stream0 channel2 &#197;&#228;&#214;&#195; **************************************/
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)( & ( ADC1->DR ) );  // è&#161;ADC1 μ&#196;μ&#216;&#214;·
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = ADC_DMA_SIZE ;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
    DMA_Cmd(DMA2_Stream0, ENABLE);

    /* &#197;&#228;&#214;&#195;ADC3í¨μà7òy&#189;&#197;&#206;a&#196;£&#196;aê&#228;è&#235;&#196;£ê&#189;******************************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    /****************************************************************************   
          PCLK2 = HCLK / 2
          &#207;&#194;&#195;&#230;&#209;&#161;&#212;&#241;μ&#196;ê&#199;2·&#214;&#198;μ
          ADCCLK = PCLK2 /2 = HCLK / 4 = 168 / 4 = 42M
      ADC2é&#209;ù&#198;μ&#194;ê£o Sampling Time + Conversion Time = 3 + 12 cycles = 15cyc
                    Conversion Time = 42MHz / 15cyc = 2.8Mbps.
    ***************************************************************************/
    /* ADC1&#171;122&#191;·&#214;3&#245;ê&#188;&#187;ˉ**********************************************************/
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    /* ADC3 3&#245;ê&#188;&#187;ˉ ****************************************************************/
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC3 1&#230;&#212;ò channel7 &#197;&#228;&#214;&#195; *************************************/
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_28Cycles);

    /* ê1&#196;üDMA&#199;&#235;&#199;ó(μ¥ADC&#196;£ê&#189;) */
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

    /* ê1&#196;ü ADC3 DMA */
    ADC_DMACmd(ADC1, ENABLE);
               

//                //&#209;&#161;&#212;&#241;DMA2êy&#190;Yá÷0í¨μà0
//                NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn;
//                //&#199;à&#213;&#188;ê&#189;ó&#197;&#207;è&#188;&#182;
//                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
//                //&#207;ìó|ê&#189;ó&#197;&#207;è&#188;&#182;
//                NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
//                //í¨μàê1&#196;ü
//                NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//                //&#189;&#171;ò&#212;é&#207;&#197;&#228;&#214;&#195;ó|ó&#195;óúNVIC
//                NVIC_Init(&NVIC_InitStructure);
//                //ê1&#196;üDMA′&#171;ê&#228;&#214;D&#182;&#207;
//                DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);
               
    /* ê1&#196;ü ADC3 */
    ADC_Cmd(ADC1, ENABLE);
   
    /* èí&#188;t&#198;&#244;&#182;ˉADC×a&#187;&#187; */
          ADC_SoftwareStartConv(ADC1);
}



[/mw_shl_code]

DAC部分,我用了一个32元素的正弦数组,DMA1数据流5 ,TIM2做DAC的触发,输出正弦波。

[mw_shl_code=c,true]#include "dac.h"

#define DAC_DHR12RD_Address   0x40007420 //  &#198;&#171;ò&#198;μ&#216;&#214;·0x08

const uint16_t Sine12bit[32] = {
        2448,2832,3186,3496,3751,3940,4057,4095,4057,3940,
        3751,3496,3186,2832,2448,2048,1648,1264,910,600,345,
        156,39,0,39,156,345,600,910,1264,1648,2048
};

uint32_t DualSine12bit[32];

static void DAC_Config(void)
{  
    GPIO_InitTypeDef  GPIO_InitStructure;
          DAC_InitTypeDef   DAC_InitType;
       
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//ê1&#196;üGPIOAê±&#214;ó
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//ê1&#196;üDACê±&#214;ó
                          
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;     //&#196;£&#196;aê&#228;è&#235;
          GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;   //&#207;&#194;à-
          GPIO_Init(GPIOA, &GPIO_InitStructure);           //3&#245;ê&#188;&#187;ˉ

                DAC_InitType.DAC_Trigger=DAC_Trigger_T2_TRGO  ;                                 //2&#187;ê1ó&#195;′¥·¢1|&#196;ü TEN1=0
                DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;             //2&#187;ê1ó&#195;2¨D&#206;·¢éú
          DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;   //&#198;á±&#206;&#161;¢·ù&#214;μéè&#214;&#195;
                DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;                 //DAC1ê&#228;3&#246;&#187;o′&#230;1&#216;±&#213; BOFF1=1
       
                DAC_Init(DAC_Channel_1,&DAC_InitType);                                                                         //3&#245;ê&#188;&#187;ˉDACí¨μà1
                 //DAC_Init(DAC_Channel_2,&DAC_InitType);                                                                         //3&#245;ê&#188;&#187;ˉDACí¨μà1

          DAC_Cmd(DAC_Channel_1, ENABLE);  //ê1&#196;üDACí¨μà1
       //   DAC_Cmd(DAC_Channel_2, ENABLE);  //ê1&#196;üDACí¨μà2
               
    DAC_SetChannel1Data(DAC_Align_12b_R, 0);   //12&#206;&#187;óò&#182;&#212;&#198;&#235;êy&#190;Y&#184;&#241;ê&#189;éè&#214;&#195;DAC&#214;μ
            //        DAC_SetChannel2Data(DAC_Align_12b_R, 0);   //12&#206;&#187;óò&#182;&#212;&#198;&#235;êy&#190;Y&#184;&#241;ê&#189;éè&#214;&#195;DAC&#214;μ
               
                DAC_DMACmd(DAC_Channel_1, ENABLE);
}
                               
static void DAC_TIM_Config(void)
{
       
        TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);         

  /* TIM2&#187;ù±&#190;&#182;¨ê±&#198;÷&#197;&#228;&#214;&#195; */
  TIM_TimeBaseStructure.TIM_Period = 130;                   //&#182;¨ê±&#214;ü&#198;ú 130 ||  f = 84M/(32*130)  &#184;&#196;±&#228;&#188;&#198;êy&#214;μ
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;                                                               //&#212;¤·&#214;&#198;μ
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;                                                    //ê±&#214;ó·&#214;&#198;μ&#207;μêy
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;          //&#207;òé&#207;&#188;&#198;êy&#196;£ê&#189;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

  TIM_Cmd(TIM2, ENABLE);

}

static void DAC_DMA_Config(DMA_Stream_TypeDef *DMA_Streamx)
{       
        DMA_InitTypeDef  DMA_InitStructure;
       
        if((u32)DMA_Streamx>(u32)DMA2)
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
               
        }
        else
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
        }
       
  DMA_DeInit(DMA_Streamx);
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}
        /* ê1&#196;üDMA1ê±&#214;ó */
               
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
       
        /* &#197;&#228;&#214;&#195;DMA1 */
       
        DMA_InitStructure.DMA_Channel = DMA_Channel_7;  
  DMA_InitStructure.DMA_PeripheralBaseAddr =  DAC_DHR12RD_Address;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DualSine12bit;
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;
  DMA_InitStructure.DMA_BufferSize = 32 ;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  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);

  /* ê1&#196;üDMA1-7í¨μà */
  DMA_Cmd(DMA1_Stream5, ENABLE);
}


void DAC_Mode_Init(void)
{
        uint32_t Idx = 0;  

        DAC_Config();
        DAC_TIM_Config();
        DAC_DMA_Config(DMA1_Stream5);
       
        /* ì&#238;3&#228;&#213;y&#207;ò2¨D&#206;êy&#190;Y£&#172;&#203;&#171;í¨μàóò&#182;&#212;&#198;&#235;*/
  for (Idx = 0; Idx < 1000; Idx++)
  {
   // DualSine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);
                DualSine12bit[Idx] = (Sine12bit[Idx]);
  }
}

[/mw_shl_code]

问题就是,在main.c里面  bsp_InitADC();         DAC_Mode_Init();    这两个函数不能同时作用。我注释掉ADC,DAC就可以输出正弦波。
我注释掉DAC,ADC就可以打印出采样值。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
qianlong
1楼-- · 2019-07-20 17:58
如果,bsp_InitADC();      DAC_Mode_Init();  两个都不注释,就只能输出正弦波,而不能打印ADC的采样值。
正点原子
2楼-- · 2019-07-20 22:29
仿真,对比寄存器组的差异。
学会找问题的方法。
不能用肯定是寄存器变化了。
包括:
1,ADC/DAC的寄存器组
2,时钟控制寄存器(RCC,管理ADC/DAC/IO的时钟)
3,IO寄存器
whyviking
3楼-- · 2019-07-21 02:32
 精彩回答 2  元偷偷看……

一周热门 更多>