cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U535 - 14 Bit ADC1 performance - getting 5bits. 12 bit ADC4 performs as expected.

JLH64
Associate II

I am developing a board using an STM32U535RETQ - 64 pin QFP pkg. The part is an SMPSU capable "Q" variant - although we are only using the STM's internal LDO... NOT the SMPSU.

I am using CubeMx 6.14 and StmIDE 1.18 to produce my ioc and compilation.

The 14bit ADC1 is performing as expected when set to convert internal signals - Vdd and Vbatt.

The signal to be converted is a low frequency DC signal - we're measuring current via a precision sense resistor and instrumentation amplifier.

Calibration performed during programme "init" :-

 
 
ADC_ChannelConfTypeDef sConfig = {0};

hadc1.Instance = ADC1;

sConfig.Channel = ADC_CHANNEL_3; // Ch3 intended- ******************************************

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES;

sConfig.SingleDiff = ADC_SINGLE_ENDED;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;



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

{

Error_Handler();

}

if ( HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED ) != HAL_OK ) // Calibrate 14 bit ADC1 - needed to look at HAL_ADCEX driver source to determine extra ADC_Calib parameter.

{

Error_Handler(); // Handle configuration error

}

We are using the ADC in a basic mode - just one single channel to convert, started by regular software conversions.

Function to read ADC1_Ch3 :-

float Read_ADC1_Ch3(void)

{

float adc1Val;

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);

adc1Val = HAL_ADC_GetValue(&hadc1); // 14 bit converter

return adc1Val;

}

When I convert any of the external channels still available ( Ch3 - the one we want, or Ch8 & Ch16 - spare I/P's ), I'm getting a cyclical swing in the reading with a 3% variation - i.e. about 5 bit performance - this repeats every several seconds.

I've looked at the I/P capacitor - nominally 1nF, values from 0-100nF have been tried without any significant difference.

Looked at the number of sample clocks - 3-814, very little difference.

The board has one, solid, Gnd plane.

ADC clock is 4MHz noimal - I've tried 250KHz-16MHz. Again - without any significant difference.

The signal I'm monitoring, measured on a 6 1/2 digit DMM is stable. The SAME SIGNAL, converted by the 12 bit ADC4 is performing as expected for a 12 bit converter. That to me almost certainly says that the issue is with the STM32 / ADC1, and not my external circuitry.

The board can be DC or battery powered - no difference on ADC1 performance.

Has anyone else encountered this issue or have any suggestions as to what the cause may be?
Thanks for any comments received.
John Haughton.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Super User

> The 14bit ADC1 is performing as expected when set to convert internal signals - Vdd and Vbatt.

This indicates ADC1 is working okay. It's the same circuitry after the sampling cap for all channels.

Recheck your assumptions. Missing something.

Show a plot of the bad data if you can. Might provide some clues. What frequency is the noise? FFT may also prove insightful.

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

View solution in original post

7 REPLIES 7
TDK
Super User

> The 14bit ADC1 is performing as expected when set to convert internal signals - Vdd and Vbatt.

This indicates ADC1 is working okay. It's the same circuitry after the sampling cap for all channels.

Recheck your assumptions. Missing something.

Show a plot of the bad data if you can. Might provide some clues. What frequency is the noise? FFT may also prove insightful.

If you feel a post has answered your question, please click "Accept as Solution".
mƎALLEm
ST Employee

Hello @JLH64 ,

I've edited your post to follow the ST community rules. So in next time please use </> button to share your code. Please review this post.

Thank you for your understanding.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
JLH64
Associate II

Update - I have confirmed that the issue is still present on other boards, two variants - my developement set, with signal conditioning, as well as prototype production boards, where I currently only have a direct input to ADC1_Ch3 (the signal conditioning will be on an I/O board.

Using a reference voltage, direct into the ADC, gives me the same results as above.
I have also cut the project down so that the only peripherals initialised are ADC1 and the GPIO.

All other hardware ( pretty minimal - LCD driver, external comparator ) is powered down.

JLH64
Associate II

I've checked whether an ADC4 chanel, using the same physical pin as an ADC1 chanel, is performing within expectations - it is.

I've also cut down the code so that the only peripherals initialised are ADC1, GPIO, and the ICACHE :-

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
//  MX_RTC_Init();
 // MX_TIM2_Init();
//  MX_LPTIM1_Init();
  MX_ICACHE_Init();
//  MX_DAC1_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */

All that is left in the main loop is :-

 while (1)
  {
	  adcVal = Read_ADC1_Ch3();
	  HAL_Delay(5);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

Setting a breakpoint on the HAL_Delay, and inspecting "adcVal"confirms that internal signals are performing to expectations, whilst external signals are unusable.

In operation, the device only needs to read the i/p signal several times a second. To get a picture of the noise I'll create an array and see if I can get it into XL, or spit the values out of DAC1 ( which is performing to expectations).

Hello @JLH64 ,

 

The cyclical variation is related to the input multiplexer switching during the ADC's successive approximation process.
ADC4 works fine because it has its own independent input multiplexer and sampling mechanism, so it does not suffer from the same issue as ADC1.

A solution could be to use continuous conversion mode for the same channel, this keeps the input multiplexer fixed on the selected channel, avoiding disturbances from switching.
You could also try to increase the sampling time, allowing more time for the ADC to stabilize can help reduce noise. Ensure the ADC clock and sampling time are within the recommended ranges.
Finally, you could duplicate each channel in the scan sequence, in scan mode, set the sequence so that each channel is converted twice in a row. Discard the first result and use the second, as the first may be affected by switching noise.

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)

Thank you Gaetan for your reply.

This issue has come up towards the end of the development of a range of products in which the 12 bit DAC1 and ADC4 are both performing to expectations. For one of the variants we need to use the 14 bit ADC1.

Just one external channel to convert, close to DC signal ( current monitoring application ) which needs sampling several times a second. In theory, it's as simple as you could get.

I have got as far as building a fresh project on our boards (535RETQ-6) - no SMPS used, two versions (large dev board, most components on it, smaller production format, CPU card which different flavours of I/O board can plug into). Two schemes of Vdda ( Vdda = Vdd for a basic version. Using a higher precision MAX part for advanced versions of the product).

I've loaded the same basic project onto our original Nucleo-U575ZI-Q - the issue is still there. Looking around at other  examples, I can not see what I am doing differently.

The only things in the basic project, created with MxCube, coded within the STM IDE, are ADC1_IN3 and 4, internal clocks and debug. The issue is still there.

We had already been through the ADC clks - 250KHz -> 16MHz, cap on the i/p pin from 0->1nF. Sample time - all through the range.

We tried continuous scanning - with the same result. More tests needed to confirm that the scan was actually happening, and I wasn't performing simple conversions.

We have not tried setting up a sequence of reads yet, but will do so as soon as possible, along confirmation of the continuous scanning.

I am having to break from this problem for a few days whilst I'm on with other work. I expect to be able to get back to this problem in a week or so and will keep this post updated with my findings.

JLH64
Associate II

I confirmed that a pot across Vref was giving us 14 bit performance.
Further tests showed that the noise was coming from the power system -  deriving Vdd from a shunt regulator and low power capacitive doubler. Adding a capacitor to the input of the instrumentation amp gives us adequate performance.