AnsweredAssumed Answered

Can't get multiple ADC via DMA working

Question asked by cicerom on Aug 12, 2015
Latest reply on Feb 23, 2018 by David Pekin
Hi,

I've been jumping between the regular libraries and Hal and the Cube and I've now settled on the Cube and HAL libs.

I'm trying to get multiple ADC channel conversions to work via DMA to an array, but with no success as yet.

I'm using a Nucleo-F411RE, and trying to use PC0 (ADC1_CH10) and PC1(ADC1_CH11).  I've got a single channel working correctly (PC0), but multiple channels still alludes me and looking at hte examples I'm not sure where I'm going wrong.

I thought the only real difference would be changing the 
AdcHandle.Init.NbrOfConversion = 2;
and setting the HAL_ADC_ConfigChannel ranks.

static GPIO_InitTypeDef  GPIO_InitStruct;
/* ADC handler declaration */
ADC_HandleTypeDef    AdcHandle;
 
/* Variable used to get converted value */
__IO uint32_t uhADCxConvertedValue[2] = {0};
 
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;
  static DMA_HandleTypeDef  hdma_adc;
   
  /* Enable peripherals and GPIO Clocks */
  /* Enable GPIO clock */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  /* ADC3 Periph clock enable */
  __HAL_RCC_ADC1_CLK_ENABLE();
  /* Enable DMA2 clock */
  __HAL_RCC_DMA2_CLK_ENABLE();
   
  /* Configure peripheral GPIO */
  /* ADC1 GPIO pin configuration */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
   
  /* Configure the DMA streams */
  /* Set the parameters to be configured */
  hdma_adc.Instance = DMA2_Stream0;
   
  hdma_adc.Init.Channel  = DMA_CHANNEL_0;
  hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
  hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_adc.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
  hdma_adc.Init.Mode = DMA_CIRCULAR;
  hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
  hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;        
  hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
  hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
  hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
 
  HAL_DMA_Init(&hdma_adc);
     
  /* Associate the initialized DMA handle to the the ADC handle */
  __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);
}
 
int main(void)
{
  ADC_ChannelConfTypeDef sConfig;
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */
  HAL_Init();
 
  /* Configure the system clock to 100 MHz */
  SystemClock_Config();
      
  /* Configure the ADC peripheral */
  AdcHandle.Instance = ADC1;
   
  AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
  AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
  AdcHandle.Init.ScanConvMode = DISABLE;
  AdcHandle.Init.ContinuousConvMode = ENABLE;
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;
  AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
  AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.NbrOfConversion = 2;
  AdcHandle.Init.DMAContinuousRequests = ENABLE;
  AdcHandle.Init.EOCSelection = DISABLE;
       
  if(HAL_ADC_Init(&AdcHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
   
  /* Configure ADC regular channel */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
  sConfig.Offset = 0;
   
  if(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
  {
    /* Channel Configuration Error */
    Error_Handler();
  }
   
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = 2;
   
  if(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
  {
    /* Channel Configuration Error */
    Error_Handler();
  }
 
  /* Start the conversion process and enable interrupt */ 
  if(HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)uhADCxConvertedValue, 1) != HAL_OK)
  {
    /* Start Conversation Error */
    Error_Handler();
  }
 
  while (1)
  {
    
  }
}
 

Outcomes