AnsweredAssumed Answered

STM32F1 ADC DMA multichannel continuous mode troubles

Question asked by Zarckk on Oct 19, 2016
Latest reply on Oct 25, 2016 by McC.Joe
Hi everyone,

I have troubles getting the ADC working properly.

This is my set-up :
- STM32F103CB
- ADC1 with 8 channels
- DMA set on ADC1

I would like to make the conversion of the 8 channels continuously in order to show the value on a screen in real-time.
I made the initialization and started the ADC.
I get values which are correct considering the analog input, but sometimes I get only 0 for all channels, and then it shows the values again.

Here are my code for ADC Initialization (ADC_FOR_CHANNELS_INPUTS = ADC1) :

void vHILCHANNELS_Initialize(uint16_t *__pu16_DMAChannelsResults)
{
   
  ADC_ChannelConfTypeDef        __t_ChannelConfig;
   
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
   
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
   
  /* Common config */
  _t_ADC1Handle.Instance = ADC_FOR_CHANNELS_INPUTS;
  _t_ADC1Handle.Init.ScanConvMode = ADC_SCAN_ENABLE;
  _t_ADC1Handle.Init.ContinuousConvMode = ENABLE;
  _t_ADC1Handle.Init.DiscontinuousConvMode = DISABLE;
  _t_ADC1Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  _t_ADC1Handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  _t_ADC1Handle.Init.NbrOfConversion = 8;
  if (HAL_ADC_Init(&_t_ADC1Handle) != HAL_OK)
  {
    printf("Error while initialization of ADC for channels inputs\n");
  }
   
  /*Configure Regular CH1 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_0;
  __t_ChannelConfig.Rank = 1;
  __t_ChannelConfig.SamplingTime = ADC_SAMPLETIME_41CYCLES_5;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH1\n");
  }
 
  /*Configure Regular CH2 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_1;
  __t_ChannelConfig.Rank = 2;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH2\n");
  }
 
  /*Configure Regular CH3 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_2;
  __t_ChannelConfig.Rank = 3;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH3\n");
  }
 
  /*Configure Regular CH4 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_3;
  __t_ChannelConfig.Rank = 4;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH4\n");
  }
 
  /*Configure Regular CH5 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_4;
  __t_ChannelConfig.Rank = 5;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH5\n");
  }
 
  /*Configure Regular CH6 */
  __t_ChannelConfig.Channel = ADC_CHANNEL_5;
  __t_ChannelConfig.Rank = 6;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC CH6\n");
  }
 
  /*Configure Regular Z */
  __t_ChannelConfig.Channel = ADC_CHANNEL_6;
  __t_ChannelConfig.Rank = 7;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC Z\n");
  }
 
  /*Configure Regular INTENS_BLK */
  __t_ChannelConfig.Channel = ADC_CHANNEL_7;
  __t_ChannelConfig.Rank = 8;
  if (HAL_ADC_ConfigChannel(&_t_ADC1Handle, &__t_ChannelConfig) != HAL_OK)
  {
    printf("Error while initialization of ADC INTENS_BLK\n");
  }
   
  /* Enables ADC and starts conversion of the regular channels */
  if(HAL_ADC_Start(&_t_ADC1Handle) != HAL_OK)
  {
    printf("Error while Starting ADC\n");
  }
  /* Enables ADC DMA request */
  if(HAL_ADC_Start_DMA(&_t_ADC1Handle,(uint32_t *)__pu16_DMAChannelsResults, 8) != HAL_OK)
  {
    printf("Error while Starting DMA for ADC\n");
  }
}

Here are my code for MSP redefined :

void HAL_ADC_MspInit(ADC_HandleTypeDef* __pt_ADCHandle)
{
  GPIO_InitTypeDef __t_GPIO_InitStruct;
   
  if(__pt_ADCHandle->Instance == ADC_FOR_CHANNELS_INPUTS)
  {
    /* Peripheral clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();
   
    /**ADC1 GPIO Configuration   
    PA0-WKUP     ------> ADC1_IN0
    PA1     ------> ADC1_IN1
    PA2     ------> ADC1_IN2
    PA3     ------> ADC1_IN3
    PA4     ------> ADC1_IN4
    PA5     ------> ADC1_IN5
    PA6     ------> ADC1_IN6
    PA7     ------> ADC1_IN7
    */
    __t_GPIO_InitStruct.Pin = ADC_CH1_PIN|ADC_CH2_PIN|ADC_CH3_PIN|ADC_CH4_PIN
                          |ADC_CH5_PIN|ADC_CH6_PIN|ADC_Z_PIN|ADC_INTENS_BLK_PIN;
    __t_GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(ADC_PORT, &__t_GPIO_InitStruct);
 
    /* Peripheral DMA init*/
   
    _t_DMAADC1.Instance = DMA_ADC_CHANNELS_INPUTS;
    _t_DMAADC1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    _t_DMAADC1.Init.PeriphInc = DMA_PINC_DISABLE;
    _t_DMAADC1.Init.MemInc = DMA_MINC_ENABLE;
    _t_DMAADC1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    _t_DMAADC1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    _t_DMAADC1.Init.Mode = DMA_CIRCULAR;
    _t_DMAADC1.Init.Priority = DMA_PRIORITY_VERY_HIGH;
    if (HAL_DMA_Init(&_t_DMAADC1) != HAL_OK)
    {
      printf("Error during initialization of DMA for ADC");
    }
 
    __HAL_LINKDMA(__pt_ADCHandle,DMA_Handle,_t_DMAADC1);
  }
 
}
 
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* __pt_ADCHandle)
{
 
  if(__pt_ADCHandle->Instance == ADC_FOR_CHANNELS_INPUTS)
  {
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();
   
    /**ADC1 GPIO Configuration   
    PA0-WKUP     ------> ADC1_IN0
    PA1     ------> ADC1_IN1
    PA2     ------> ADC1_IN2
    PA3     ------> ADC1_IN3
    PA4     ------> ADC1_IN4
    PA5     ------> ADC1_IN5
    PA6     ------> ADC1_IN6
    PA7     ------> ADC1_IN7
    */
    HAL_GPIO_DeInit(ADC_PORT, ADC_CH1_PIN|ADC_CH2_PIN|ADC_CH3_PIN|ADC_CH4_PIN
                          |ADC_CH5_PIN|ADC_CH6_PIN|ADC_Z_PIN|ADC_INTENS_BLK_PIN);
 
    /* Peripheral DMA DeInit*/
    HAL_DMA_DeInit(__pt_ADCHandle->DMA_Handle);
  }
 
}

Here is the main function :

uint16_t         _au16_ChannelsResults[8];
 
void main(void)
{
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
   
  /* Configure the system clock */
  vHILSTM32F103CB_SystemClockConfig();
   
  /* Initialize all configured peripherals */
  vHILCHANNELS_Initialize(_au16_ChannelsResults);
 
  while (1)
  {
     
    printf("***** ADC VALUES :\n");
    printf("CH1 = %03X\nCH2 = %03X\nCH3 = %03X\nCH4 = %03X\nCH5 = %03X\nCH6 = %03X\nZ = %03X\nINTENS_BLK = %03X\n", _au16_ChannelsResults[0], _au16_ChannelsResults[1], _au16_ChannelsResults[2], _au16_ChannelsResults[3], _au16_ChannelsResults[4], _au16_ChannelsResults[5], _au16_ChannelsResults[6], _au16_ChannelsResults[7]);
     
    HAL_Delay(200);
     
}

Here are the Terminal log for print (Z always at 0 is normal), where you can see the 0s on values sometimes:
***** ADC VALUES :
CH1 = 000
CH2 = 000
CH3 = 000
CH4 = 000
CH5 = 000
CH6 = 000
Z = 000
INTENS_BLK = 000
***** ADC VALUES :
CH1 = FC6
CH2 = FB4
CH3 = FB0
CH4 = FBC
CH5 = FC7
CH6 = FAC
Z = 000
INTENS_BLK = E5E
***** ADC VALUES :
CH1 = FC2
CH2 = FB6
CH3 = FA8
CH4 = FBA
CH5 = FD2
CH6 = FBC
Z = 000
INTENS_BLK = E5A
***** ADC VALUES :
CH1 = 000
CH2 = 000
CH3 = 000
CH4 = 000
CH5 = 000
CH6 = 000
Z = 000
INTENS_BLK = 000
***** ADC VALUES :
CH1 = FBF
CH2 = FAC
CH3 = F9D
CH4 = FB4
CH5 = FC4
CH6 = FAA
Z = 000
INTENS_BLK = E53
***** ADC VALUES :
CH1 = FC4
CH2 = FB4
CH3 = FAC
CH4 = FB4
CH5 = FCD
CH6 = FB4
Z = 000
INTENS_BLK = E60
***** ADC VALUES :
CH1 = FC2
CH2 = FAC
CH3 = FA8
CH4 = FB6
CH5 = FBF
CH6 = FA6
Z = 000
INTENS_BLK = E5A
***** ADC VALUES :
CH1 = FC5
CH2 = FB0
CH3 = FA3
CH4 = FB6
CH5 = FC8
CH6 = FA9
Z = 000
INTENS_BLK = E59
***** ADC VALUES :
CH1 = 000
CH2 = 000
CH3 = 000
CH4 = 000
CH5 = 000
CH6 = 000
Z = 000
INTENS_BLK = 000
***** ADC VALUES :
CH1 = FC5
CH2 = FB4
CH3 = FAD
CH4 = FB7
CH5 = FCC
CH6 = FB0
Z = 000
INTENS_BLK = E5C
***** ADC VALUES :
CH1 = FCE
CH2 = FB5
CH3 = FB2
CH4 = FBA
CH5 = FCE
CH6 = FB2
Z = 000
INTENS_BLK = E60


I tried different ways : changing sample rate, increasing the values buffer for DMA. Always get 0 at one time and it distorts my calculations.

I would be grateful if someone could help me on this.
If I miss some information, please tell me.

Thank you,
Marc

Outcomes