Skip to main content
PIvan.9
Associate III
January 14, 2022
Question

When PWM output through TIM2 channel 1 on STM32G061G6U6 is enabled, the data register of ADC1 sometimes stores high values (~4095) even if there is no signal being fed to it.

  • January 14, 2022
  • 10 replies
  • 3270 views

Here is the configuration I use:

int main(void)
{
 HAL_Init();
 SystemClock_Config();
 MX_GPIO_Init();
 MX_ADC1_Init();
 MX_TIM2_Init();
 
 // configure PWM
 __HAL_TIM_SET_AUTORELOAD(&htim2, 1000);
 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 1001);
 
 // start PWM
 HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
 
 // configure ADC
 HAL_ADC_MspInit(&hadc1);
 // start ADC in interrupt mode
 HAL_ADC_Start_IT(&hadc1);
 
 while (1)
 {
 // some code
 }
 
// callback for ADC interrupts
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
 // some code
}

When lines 11 and 14 are not commented out (i.e. compare register is configured and PWM is enabled), the ADC1 sometimes reads high values with no signal being fed to it (ADC input pins are pulled down, so there is no floating voltage). When lines 11 and 14 are commented out, there is no such issue. Also, by changing the TIM2 PWM channel to any other one, the issue dissapers. This was tested on 2 MCUs.

Does anyone have any ideas why TIM2 channel 1 PWM might interfere with ADC readings?

This topic has been closed for replies.

10 replies

waclawek.jan
Super User
January 14, 2022

Which pins exactly, both PWM and ADC?

What is the ADC readout periodicity, what is the sampling time, how exactly is reference set, etc.?

JW

PIvan.9
PIvan.9Author
Associate III
January 14, 2022

PA0 for PWM output and PA2/PA3 for ADC input.

LCE
Principal II
January 14, 2022

And what about external hardware:

  • Are the PWM / ADC pins (or pcb traces) close to each other?
  • How are these IOs connected externally?
  • Especially the ADC inputs, any low impedance driver connected, or at least an RC low pass close to the pins?
  • What are the frequencies of the PWM and the ADC sampling rate?

PIvan.9
PIvan.9Author
Associate III
January 14, 2022

ADC is connected to an active mode phototransistor circuit (Vout in the image):

0693W00000HrhtIQAR.pngPWM and ADC traces are close to each other only at some points and mostly due to the MCU package. I initially thought about crosstalk between them, but 10kOhm (Re) pull-downs on ADC pins should have helped with it. There is no RC filter and a phototransistor signal is not expected to be noisy anyway.

PWM frequency is 50kHz, but, here is the interesting part, the duty cycle is set to 100%, so there should have been no swithching between HIGH and LOW in my tests.

The ADC sampling frequency is 1.6MHz, but that's not taking into account the interrupt code.

LCE
Principal II
January 17, 2022

If the PWM is inactive (better check pins on scope), it's probably no hardware problem.

On the other hand, depending on the phototransistor, it seems very bold to connect it directly to the STM's ADC input.

To finally check if the problem is related to external circuitry, I would bridge the pull-down R with 0 Ohm, or even connect the ADC input to GND very close to the pin.

Better remove the phototransistor before doing that!

PIvan.9
PIvan.9Author
Associate III
January 17, 2022

I've checked the PWM output pin, it is truly at 100% duty cycle. I've also checked that the duty cycle can be reduced to other values. It is possible, so PWM works properly. However, it doesn't change the situation, ADC still detects max values from time to time.

I've also removed phototransistors on both ADC pins and replaced Re with jumper wires. The result is the same. However, it's not possible to connect ADC inputs to ground really close to the pins due to the layout. The distance to Re is ~2cm.

It would be nice, if someone could check this issue with their own PCBs, although I understand that chances for this are pretty low.

PIvan.9
PIvan.9Author
Associate III
January 17, 2022

As a last test, I've commented out

// HAL_ADC_MspInit(&hadc1);

command, so no ADC pins should be configured and ADC can't receive any data from anywhere, however the issue is still there.

Philippe Cherbonnel
ST Employee
January 21, 2022

Hello,

Can you show the content of MX_ADC1_Init() and HAL_ADC_MspInit() ?

By the way, it should not be needed to call HAL_ADC_MspInit() because already called by HAL_ADC_Init().

PIvan.9
PIvan.9Author
Associate III
January 21, 2022

Yes, you're right about HAL_ADC_MspInit(). I've attached my project to this message.

On my board I also disconnected PWM output pin (PA0) from the rest of the circuit and as I mentioned previously, ADC input (PA2) is tied to ground.

waclawek.jan
Super User
January 21, 2022

> It would be nice, if someone could check this issue with their own PCBs,

Conversely, you can try to do it on a "known good" board such as Nucleo or EVAL.

JW

PIvan.9
PIvan.9Author
Associate III
January 21, 2022

Yeah, but there is no dev board with exactly STM32G061G6U6 chip.

Philippe Cherbonnel
ST Employee
January 24, 2022

Hello @PIvan.9​ ,

Thanks for your whole CubeIDE program.

I have tested it on a board Nucleo STM32G070RB (device similar to STM32G061): I do not reproduce your issue.

Even after even after 30min run, I never go in case of ADC conversion saturated high.

I have checked low frequency mode, in case of triggers spaced out of more than 100us for STM32G0.

Conversion duration:

In your configuration, ADC clock from PLL-P 16MHz with prescaler 10, sampling time 1.5 ADC clock cycles, resolution 12 bit:

Tconv = Tadc_clk * (Tsmpl + Tsar) = (1/ (16MHz / prescaler 10)) * (1.5 + 12.5) = 8.75us

So it's ok for setting TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

Can you try to increase sampling time, for example to 39.5 ADC clock cycles ?

(but low probability of the root cause since you have tested with ADC channel grounded)

What could explain the random behavior on your side ?

The board environment could be the cause: for example, some instabilities on voltage reference Vref+.

(on STM32G061G6U6, pin Vref+ available with package LQFP48 or connected to pin Vdda on other packages).

The link with PWM would be strange, but side effects due to current draw are possible.

Is there a stable voltage supply, decoupling capacitor, ..., on your board ?

You can refer to application note:

AN2834: How to get the best ADC accuracy in STM32 microcontrollers

As suggested by @Community member​ , you can compare you board design and program execution on a known good board with similar devices: STM32G071 or STM32G070 Nucleo/Eval (as STM reference design).

Best regards

Philippe

PIvan.9
PIvan.9Author
Associate III
January 25, 2022

Hi Philippe,

Thanks for your time and trying to help.

So far, I've figured out that the false values the ADC stores in its data register are all equal to exactly 4095. I've double checked that the ADC inputs are not connected to anything other than GND and I've also measured them with oscilloscope, they are actually at 0V as expected.

The only way I can check ADC readings is with if condition and GPIO toggling, since I don't have any communication protocol connection (I2C, UART, SPI) on my board.

After setting up oscilloscope, it looks like most of the readings are the false ones and the one that should have a proper low value appears once in 8 readings. See the graph below, yellow line is pin toggling at values 4095, blue is another pin toggling at values lower than 500.

Changing sampling time only affects the period between readings/pin toggling, but it doesn't fix anything.

I don't have any explanations for this behaviour from my side, since power supply is designed properly in my opinion. Also, bad supply wouldn't explain why this issue appears only during enabling PWM output on one specific channel and disappears when a channel is changed to another one. Also, I don't think that the current draw can be the reason, since PWM pin is disconnected and duty cycle is set to 100%.

Regards,

Pavels