cancel
Showing results for 
Search instead for 
Did you mean: 

Bug in CubeMX (6.11.1) STM32G474VETx ADC Missing channel configuration

Georg_Gebauer
Visitor

Dear ST-Developer,

i have discovered that the ADC configuration with cube takes only effect for one channel instead of every enabled channel. In the reference Manual and HAL_ADC documentation i have understood that each ADC-Channel of the G474 series are independent configurable from each other.  The problem is that the generated code by CubeMX seems to not generate the configuration for enabled channels.

I have expected that ALL  ADC-Configuration for ALL enabled channels will be generated. So i faced the problem that only one ADC-Channel (independent from ADC1,2,3,4 and 5) was configured correctly.

I don't want to check the code generated by CubeMX for correctness because then i can write it by my own from scratch. And i don't want to insert missing channel configuration by hand because i use CubeMX that should do it for me. Thats why we use it to simplify our work. Our code uses the Hardware configurations from CubeMX as single point of truth  so that we have only to change the settings there.

I have tested it with following setup for ADC1 and ADC3. By ADC-3 it is more surprising that i have configured Channel 2 to be differential and channel 4 to be single ended and the generated code configures randomly channel  4 only. All other configured channels are completely missing in code.

Cube configuration for ADC1:

Georg_Gebauer_2-1721908098703.png

Generated Code by CubeMX:

 

 

static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.GainCompensation = 0;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

 

 

 

Cube configuration for ADC 3:

Georg_Gebauer_1-1721907922483.png

Generated code in main.c:

 

 

static void MX_ADC3_Init(void)
{

/* USER CODE BEGIN ADC3_Init 0 */

/* USER CODE END ADC3_Init 0 */

ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};

/* USER CODE BEGIN ADC3_Init 1 */

/* USER CODE END ADC3_Init 1 */

/** Common config
*/
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.GainCompensation = 0;
hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc3.Init.LowPowerAutoWait = DISABLE;
hadc3.Init.ContinuousConvMode = DISABLE;
hadc3.Init.NbrOfConversion = 1;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.DMAContinuousRequests = DISABLE;
hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc3.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
Error_Handler();
}

/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc3, &multimode) != HAL_OK)
{
Error_Handler();
}

/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC3_Init 2 */

/* USER CODE END ADC3_Init 2 */

}

 

 

 

 

 

3 REPLIES 3
TDK
Guru

You only have one channel conversion selected. Increase that to the number of channels you want to convert.

Then, expand Rank and select the order and configuration of each converted channel.

TDK_0-1721910214289.png

 

If you feel a post has answered your question, please click "Accept as Solution".

Hi thanks for the quick response.

 

Why do i have to change the Number of conversion when i have enabled the channels by selecting the conversion mode from "disabled" to other mode. I hadn't expected to have to do it. When i have configured the  channels from "disabled" to specific mode i think the software should configure it.

Thats why i had expected that Cube will configure them. When it is for some purpose hardly required to set Number Of Conversion to "enable" the configuration of selected channels it is confusing to change channels from "disabled" to some mode.

Because that's how the program works. It can't read your mind, you have to follow the rules. I didn't write it.

Perhaps it should add new channels as you enable them, but it doesn't, so you have to do this.

If you feel a post has answered your question, please click "Accept as Solution".