AnsweredAssumed Answered

How does the ADC work with multiple channels ?

Question asked by mccarty.michael on Jan 20, 2013
Latest reply on Jan 22, 2013 by mccarty.michael
Hello All,
   My ideal setup would be to use adc1, read channels 11,12,13 and the temp as half words then store them in a buffer at a certain memory location. 

   I think the way to do this is to enable the ADC and then hook it up to the DMA, set the dma to have a buffersize of 4, in circular mode. Then have the ADC read each channel and after finishing trigger the dma to store the next value. 

  Been trying to do that for a few days with no luck. I always end up with the OVR flag set in my ADC. The best I have been able to get is one adc channel working at a time. I'm really confused, if i get an error in ADC like "ovr" i can clear that flag and reinit, do i need to clear the error flags in the dma also and re init ? When you init a perph does it reset all of the error flags ? 

   This is what I have that does not work, sorry, so sorry for my choice of define prefix. 

/**
 * ADC perph defines
 */
#define ZANAL_ADC                     ADC3
#define ZANAL_DR                     ((uint32_t)0x4001224C)
#define ZANAL_ADCCLK                   RCC_APB2Periph_ADC3
#define ZANAL_PIN1                     GPIO_Pin_1
#define ZANAL_PIN2                     GPIO_Pin_2
#define ZANAL_PIN3                     GPIO_Pin_3
#define ZANAL_PIN1_PORT                GPIOC
#define ZANAL_GPIO1CLK                RCC_AHB1Periph_GPIOC
#define ZANAL_ADCCHAN1                ADC_Channel_11
#define ZANAL_ADCCHAN2                ADC_Channel_12
#define ZANAL_ADCCHAN3                ADC_Channel_13
#define ZANAL_DMA_CHAN                DMA_Channel_2
#define ZANAL_DMA_CLK                RCC_AHB1Periph_DMA2
#define ZANAL_DMA_STREAM             DMA2_Stream0

void initADC()
{
     ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;


  /* Enable ADC3, DMA2 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd(ZANAL_DMA_CLK | ZANAL_GPIO1CLK, ENABLE);
  RCC_APB2PeriphClockCmd(ZANAL_ADCCLK, ENABLE);


  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_InitStructure.DMA_Channel = ZANAL_DMA_CHAN;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = ZANAL_DR;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&mygVars->ADCIN1;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  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(ZANAL_DMA_STREAM, &DMA_InitStructure);
  DMA_Cmd(ZANAL_DMA_STREAM, ENABLE);


  /* Configure ADC3 Channel12 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = ZANAL_PIN1 | ZANAL_PIN2;// | ZANAL_PIN3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(ZANAL_PIN1_PORT, &GPIO_InitStructure);


  /* ADC Common Init **********************************************************/
  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 Init ****************************************************************/
  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 = 0;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ZANAL_ADC, &ADC_InitStructure);


  /* ADC3 regular channel12 configuration *************************************/
  ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN2, 1, ADC_SampleTime_3Cycles  );
  //ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN2, 2, ADC_SampleTime_3Cycles  );
  //ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN3, 3, ADC_SampleTime_15Cycles  );


  ADC_DMARequestAfterLastTransferCmd(ZANAL_ADC, ENABLE);


  /* Enable ADC3 DMA */
  ADC_DMACmd(ZANAL_ADC, ENABLE);


  /* Enable ADC3 */
  ADC_Cmd(ZANAL_ADC, ENABLE);


  ADC_SoftwareStartConv(ZANAL_ADC);
}

Outcomes