Skip to main content
Visitor II
October 13, 2025
Question

STM32C092 ADC channel 0 affecting reading of channel 1

  • October 13, 2025
  • 3 replies
  • 271 views

Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code

In STM32C092 board, when I configured in ioc file for ADC, with scan conversion mode and:
- enable analog channel 0 only, it is able to measure the analog channel 0 correctly.
- enable analog channel 1 only, it is unable to measure the analog channel 1 correctly.
- enable analog channels 0 & 1, it is able to measure the analog channel 0 correctly but channel 1 is mirroring the value of channel 0, instead of giving an independent value on changing voltages.

I tried:
- ranking ADC sequence manually, since in ioc file, it doesn't give options for ranking.
- verified the GPIO settings for analog function.
- increased sampling time for channel 1.
- gave sampling time for channel0 as 1.5 cycles and for channel1 as 160.5 cycles.


Am I doing something wrong here?

The IOC default code generation is as below:

static void MX_ADC1_Init(void)

{

ADC_ChannelConfTypeDef sConfig = {0};



hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

hadc1.Init.Resolution = ADC_RESOLUTION_10B;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED;

hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

hadc1.Init.LowPowerAutoWait = DISABLE;

hadc1.Init.LowPowerAutoPowerOff = 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.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;

hadc1.Init.OversamplingMode = DISABLE;

hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}



sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}



sConfig.Channel = ADC_CHANNEL_1;

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

}

 

In this code I changed the number of conversions to 2 manually (since in ioc, provision wasn't there)

and also tried making different functions to set rank and start reading adc each time.

    This topic has been closed for replies.

    3 replies

    Super User
    October 13, 2025

    > enable analog channel 1 only, it is unable to measure the analog channel 1 correctly.

    How "unable"?

    What are the signal sources? Isn't channel 1 source's impedance too high?

    > hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;

    Try increasing substantially.

    JW

    Noni95Author
    Visitor II
    October 14, 2025

    - Unable in the sense it reads value like 0.00118... 
    - So, the circuit is like below:

    Noni95_0-1760432241311.png

    If I increase WALL_IN voltage (connected to analog channel 0) to a value say 12V or decrease the value to 8V, the VCC_3V3 (connected to the analog channel 1) should not be affected. But in my case, it is increasing to 3.2V or decreasing to 2.8V corresponding to the WALL_IN voltage change. I checked in the hardware at pin 8, it remains 3.3V irrespective of WALL_IN voltage levels, but in software, it is mirroring the WALL_IN voltage (raw adc value is same for both channel 0 and channel 1). 

    - I gave one channel a sampling time of 1.5 and another as 160.5, but still no changes in the behavior.

     

    Graduate II
    October 14, 2025

    The ADC is not designed for high impedance signal sources. Read the following application note: AN2834 

    What can help is capacitors on the outputs the voltage dividers to buffer the signal voltage while the sampling capacitor is charged. And increase the sampling time significantly. If it fully charges each time the individual measurements are more accurate and cross talk should be lower too.

    Technical Moderator
    October 16, 2025

    Hello @Noni95 

    When configuring the ADC to read multiple channels, it’s essential to set the NbrOfConversion parameter to match the number of channels you intend to scan (for example, set it to 2 if you are using channels 0 and 1). Additionally, each channel must be assigned a unique rank in the conversion sequence—this is done by setting the Rank field in the ADC_ChannelConfTypeDef structure to 1 for the first channel, 2 for the second.

    Please refer to the snipped code below:

    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.ScanConvMode = ADC_SCAN_ENABLE;
     hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
     hadc1.Init.LowPowerAutoWait = DISABLE;
     hadc1.Init.LowPowerAutoPowerOff = DISABLE;
     hadc1.Init.ContinuousConvMode = DISABLE;
     hadc1.Init.NbrOfConversion = 3;
     hadc1.Init.DiscontinuousConvMode = ENABLE;
     hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
     hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
     hadc1.Init.DMAContinuousRequests = ENABLE;
     hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
     hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
     hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
     hadc1.Init.OversamplingMode = DISABLE;
     hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
     if (HAL_ADC_Init(&hadc1) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Configure Regular Channel
     */
     sConfig.Channel = ADC_CHANNEL_4;
     sConfig.Rank = ADC_REGULAR_RANK_1;
     sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Configure Regular Channel
     */
     sConfig.Channel = ADC_CHANNEL_VREFINT;
     sConfig.Rank = ADC_REGULAR_RANK_2;
     sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
     {
     Error_Handler();
     }
    
     /** Configure Regular Channel
     */
     sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
     sConfig.Rank = ADC_REGULAR_RANK_3;
     sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
     if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
     {
     Error_Handler();
     }

     Also, you can refer to the example ADC_MultiChannelSingleConversion in STM32CubeC0 package.