AnsweredAssumed Answered

Multichannel ADC in disc. Mode (with DMA support)

Question asked by gerh.jo on Jul 14, 2015
Latest reply on Jul 15, 2015 by gerh.jo

Dear Community,

I want to use DMA to multichannel-convert the result of the ADC (for my case of the ADC1 of a F051 device). As shown in the STPL examples for the continuous mode this works very well. However I want to convert the ADC value(s) at a certain point in time since I have to setup some other parameters of my device first. I was thinking to configure the DMA and the ADC as shown in the examples but to use the DMA in normal-mode and the ADC in discontinues mode instead. Then I was thinking to start ADC conversion at some point in time and wait until either EOC is RESET or maybe DMA_IT_TC is set (which I probably need to clear if used). However unfortunately the whole concept does not work because I just get a zero as the result of the conversion. Therefore I want to ask whether my planed approach is possible or not. Here is some code (for the case I made a mistake somewhere). I would be very happy if someone would check this code for mistakes (if present).


 

unsigned char ConvADC0_ADC1[2];
  
void ADC_Config(void)
{   
  ADC_InitTypeDef     ADC_InitStructure;
  GPIO_InitTypeDef    GPIO_InitStructure;
  DMA_InitTypeDef     DMA_InitStructure;    
  //ADC1 de-Init
  ADC_DeInit(ADC1);
  //DMY1 Clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
  //GPIO Periph Clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  //ADC1 Periph clock enable 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
  //GPIO Config for ADC 
  // Configure ADC Channel0 -> OSC Amp  as analog input 
  // Configure ADC Channel1 -> Temp  as analog input 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  // Initialize ADC structure 
  ADC_StructInit(&ADC_InitStructure); 
  // Configure the ADC1 in continuous mode with a resolution equal to 8bits  
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;// 
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  //ENABLE
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
  ADC_Init(ADC1, &ADC_InitStructure); 
  
  // Convert the ADC1 Channel 0 and 1 with 239.5 Cycles as sampling time 
  // ADC Channel 0 is connmected to PA0 
  ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles);
  // ADC Channel 1 is connmected to PA1 
  ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_239_5Cycles);
      
  // ADC Calibration 
  ADC_GetCalibrationFactor(ADC1);   
      
 //DMA config
  DMA_DeInit(DMA1_Channel1);
    
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&(ConvADC0_ADC1);
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
      
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
      
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
      
  DMA_InitStructure.DMA_BufferSize = 2; //sizeof(ConvADC0_ADC1)
      
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//  DMA_Mode_Circular; //DMA_Mode_Normal;//    
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;   
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
      
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
      
  //DMA Enable
  DMA_Cmd(DMA1_Channel1, ENABLE);
    
 // ADC_DMAMode_OneShot: DMA One Shot Mode 
    // ADC_DMAMode_Circular: DMA Circular Mode  
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
    
  // Enable ADC_DMA 
  ADC_DMACmd(ADC1, ENABLE);  
    
  // Enable the ADC peripheral 
  ADC_Cmd(ADC1, ENABLE);     
    
  // Wait the ADRDY flag 
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY)); 
    
 // ADC_StartOfConversion(ADC1);
}
  
  
  
unsigned char GetADC() {
      unsigned char curr_signalpegel;
      ADC_StartOfConversion(ADC1);
       while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET) {};  
       curr_signalpegel = ConvADC0_ADC1[0];
return curr_signalpegel;
}

Outcomes