cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H750 ADC+DMA Continuous mode PC2_C and PC3_C sampling data is unstable

RWu.2
Associate II

I'm having some ADC+DMA sampling problems with the H750.  

When the ADC+DMA is working, in continuous mode, PC2_C(ADC3_CH0) gets 16bit sampling data which is unstable and constantly jumps between 10000+ and 30000+. I guess there is a problem with the code configuration.  

However, the channel PF9(ADC3_CH2) with the same configuration is very stable with only a very small fluctuation.  

The ADC clock frequency is 10Mhz.

I checked the errata but could not find a solution.  

In HW, both VDDA and Vref+ have a pair of decoupling capacitors near H750, and each ADC channel also has a low-pass filter. 

The following is the sample data of PC2_C

0693W00000Npv4xQAB.png 

bsp_adc.c

#include "bsp_adc.h"
 
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;
 
 
/* ADC3 init function */
void MX_ADC3_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /** Common config 
  */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = ENABLE;
  hadc3.Init.NbrOfConversion = 6;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    ////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  //sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
	sConfig.SamplingTime = ADC_SAMPLETIME_387CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    ////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    ////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    ////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    ////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    //////Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_13;
  sConfig.Rank = ADC_REGULAR_RANK_6;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    ////Error_Handler();
  }
 
}
 
static uint32_t HAL_RCC_ADC12_CLK_ENABLED=0;
 
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
 
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  
	if(adcHandle->Instance==ADC3)
  {
  /* USER CODE BEGIN ADC3_MspInit 0 */
 
  /* USER CODE END ADC3_MspInit 0 */
    /* ADC3 clock enable */
    __HAL_RCC_ADC3_CLK_ENABLE();
  
    __HAL_RCC_GPIOF_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**ADC3 GPIO Configuration    
    PF6     ------> ADC3_INP8
    PF7     ------> ADC3_INP3
    PF9     ------> ADC3_INP2
    PH2     ------> ADC3_INP13
    PC2_C     ------> ADC3_INP0
    PC3_C     ------> ADC3_INP1 
    */
    GPIO_InitStruct.Pin = RCB_REV_Pin|IF_BOARD_REV_Pin|VAA5_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
    GPIO_InitStruct.Pin = AEC_REV_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(AEC_REV_GPIO_Port, &GPIO_InitStruct);
 
    HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC2, SYSCFG_SWITCH_PC2_OPEN);
 
    HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_OPEN);
 
    /* ADC3 DMA Init */
    /* ADC3 Init */
    hdma_adc3.Instance = DMA1_Stream2;
    hdma_adc3.Init.Request = DMA_REQUEST_ADC3;
    hdma_adc3.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc3.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc3.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc3.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_adc3.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_adc3.Init.Mode = DMA_CIRCULAR;
    hdma_adc3.Init.Priority = DMA_PRIORITY_LOW;
    hdma_adc3.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_adc3) != HAL_OK)
    {
      ////Error_Handler();
    }
 
    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc3);
 
  /* USER CODE BEGIN ADC3_MspInit 1 */
 
  /* USER CODE END ADC3_MspInit 1 */
  }
}
 
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
 
  if(adcHandle->Instance==ADC3)
  {
  /* USER CODE BEGIN ADC3_MspDeInit 0 */
 
  /* USER CODE END ADC3_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC3_CLK_DISABLE();
  
    /**ADC3 GPIO Configuration    
    PF6     ------> ADC3_INP8
    PF7     ------> ADC3_INP3
    PF9     ------> ADC3_INP2
    PH2     ------> ADC3_INP13
    PC2_C     ------> ADC3_INP0
    PC3_C     ------> ADC3_INP1 
    */
    HAL_GPIO_DeInit(GPIOF, RCB_REV_Pin|IF_BOARD_REV_Pin|VAA5_Pin);
 
    HAL_GPIO_DeInit(AEC_REV_GPIO_Port, AEC_REV_Pin);
 
    /* ADC3 DMA DeInit */
    HAL_DMA_DeInit(adcHandle->DMA_Handle);
  /* USER CODE BEGIN ADC3_MspDeInit 1 */
 
  /* USER CODE END ADC3_MspDeInit 1 */
  }
}

6 REPLIES 6
Pavel A.
Evangelist III

What is the source of the ADC "async" clock?

There is a nasty Cube bug in ADC clock source configuration.

If your init code is affected, will have to wait for fix.

Georgy Moshkin
Senior II

Are you sure about 10Mhz sampling frequency?

Check DM00609692 and dm00628458:

0693W00000Npvw1QAB.png0693W00000Npvw6QAB.pngin Cube IDE configurator: SystemCore → RCC → Product Revision → rev.Y / rev.V

(must provide 2x frequency revision V compared to revision Y).

Disappointed with crowdfunding projects? Make a lasting, meaningful impact as a Tech Sponsor instead: Visit TechSponsor.io to Start Your Journey!

Thanks for your reply. The ASYNC clock source is adc_ker_ck_input. This project was created with MX 5, so the bug in MX 6.5 and IDE 1.9 shouldn't exist.

Sorry, 10Mhz sampling frequency is my mistake, 10Mhz should be Fadc_ker_ck. The configuration of Rev V and Rev Y in RCC is something I didn't pay attention to before, and I also chose the wrong Rev. Thank you for reminding me. I will do some tests to see if this change solves my problem.

You can attach your IOC file if problem still exists. Make sure that "PC2_C(ADC3_CH0)" is not connected to something else (some IC). Also, some glitches may occur if you configure input as differential, but input signal do not satisfy this:

0693W00000Nq1djQAB.pngThere is still possibility that there is some bug in your code. Have you tried simplest possible read of ADC value without DMA?

Disappointed with crowdfunding projects? Make a lasting, meaningful impact as a Tech Sponsor instead: Visit TechSponsor.io to Start Your Journey!

Thanks for your reply.

PC2_C(ADC3_CH0) is indeed connected to other circuits at the same time, but the possibility of causing problem has been ruled out by disconnecting other circuit.

ADC is configured in single-ended input mode in ioc.

ADC data is OK without DMA mode, which is one of the methods I'm trying.