Skip to main content
Associate II
March 19, 2026
Solved

STM32F334 HRTIM and ADC noise

  • March 19, 2026
  • 10 replies
  • 634 views

Hello,

I am using the HRTIM on an STM32F334 to drive a buck/boost converter.

I monitor MOSFET temperature using NTCs via ADC2, and I also need to measure the internal CPU temperature and VREFINT using ADC1.

ADC configuration:

ADC1

  • Regular: VREFINT, TEMPSENSOR

  • Injected: Vin

ADC2

  • Regular: MosFetTemp1, MosFetTemp2, AnalogStartInfo

  • Injected: Vout

Issue:

As soon as the HRTIM is initialized (even without starting it), the ADC regular conversion values become unstable.

Observations:

  • 100 samples of VREFINT only → stable when HRTIM is not initialized

  • 100 samples of TEMPSENSOR only → stable when HRTIM is not initialized

  • 100 samples of (VREFINT + TEMPSENSOR) → stable when HRTIM is not initialized

  • 100 samples of (VREFINT + TEMPSENSOR + ANALOGSTARTINFO) → stable when HRTIM is not initialized

As soon as HRTIM is initialized, all these measurements become noisy/unstable.

The issue is also present:

  • even if HRTIM is not started

  • even if GPIOs are not initialized  (so MOSFETs are not switching)

  • even if line HAL_HRTIM_MspPostInit(&hhrtim1) is comment

Question:

Has anyone experienced a similar issue with HRTIM affecting ADC accuracy on STM32F3?

Could this be related to:

  • internal analog coupling between HRTIM and ADC?

  • ADC clocking or trigger configuration?

  • VDDA or internal reference disturbance caused by HRTIM initialization?

Any insights or ideas would be greatly appreciated.

Thanks in advance.

Best regards,

in main.c :

 MX_GPIO_Init();
 MX_ADC1_Init();
 MX_ADC2_Init();

 MX_HRTIM1_Init();

 /* ---- Test pour debug ADC ---- */
 if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
 {

 }

 Debug_ActiveCanauxInternesAdc1();
 HAL_Delay(2);

 U16 volatile u16_Index = 0;
 U16 volatile tu16_Data[100][2];
 U16 volatile tu16_Data_2[100];

 while(1)
 {
 U16 volatile u16_raw_vdda;
 U16 volatile u16_raw_cpu;
 U16 volatile u16_raw_dplus;

 u16_raw_vdda = Debug_LireVddaBrut();
 u16_raw_cpu = Debug_LireTempCpuBrut();
 u16_raw_dplus = Debug_LireDPlus();

 tu16_Data[u16_Index][0] = u16_raw_vdda;
 tu16_Data[u16_Index][1] = u16_raw_cpu;

 tu16_Data_2[u16_Index] = u16_raw_dplus;

 //printf("TEMP raw = %u\r\n", u16_raw);
 HAL_Delay(100);
 u16_Index++;
 if (100 <= u16_Index)
 {
 u16_Index = 0;
 }
 }
 /* ------- fin test pour debug ADC ---------- */

 

DebugTemp.c :

void Debug_ActiveCanauxInternesAdc1(void)
{
 LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),
 LL_ADC_PATH_INTERNAL_VREFINT | LL_ADC_PATH_INTERNAL_TEMPSENSOR);

 HAL_Delay(1);
}

U16 Debug_LireTempCpuBrut(void)
{
 ADC_ChannelConfTypeDef sConfig = {0};

 sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;

 if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 return 0xFFFF;
 }

 if(HAL_ADC_Start(&hadc1) != HAL_OK)
 {
 return 0xFFFE;
 }

 if(HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
 {
 return 0xFFFD;
 }

 return (U16)HAL_ADC_GetValue(&hadc1);
}

U16 Debug_LireVddaBrut(void)
{
 ADC_ChannelConfTypeDef sConfig = {0};

 sConfig.Channel = ADC_CHANNEL_VREFINT;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.SamplingTime = ADC_SAMPLETIME_181CYCLES_5;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;

 if(HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
 {
 return 0xFFFF;
 }

 if(HAL_ADC_Start(&hadc1) != HAL_OK)
 {
 return 0xFFFE;
 }

 if(HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
 {
 return 0xFFFD;
 }

 return (U16)HAL_ADC_GetValue(&hadc1);
}

U16 Debug_LireDPlus(void)
{
 ADC_ChannelConfTypeDef sConfig = {0};

 sConfig.Channel = ADC_CHANNEL_4;
 sConfig.Rank = ADC_REGULAR_RANK_1;
 sConfig.SingleDiff = ADC_SINGLE_ENDED;
 sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
 sConfig.OffsetNumber = ADC_OFFSET_NONE;
 sConfig.Offset = 0;

 if(HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
 {
 return 0xFFFF;
 }

 if(HAL_ADC_Start(&hadc2) != HAL_OK)
 {
 return 0xFFFE;
 }

 if(HAL_ADC_PollForConversion(&hadc2, 10) != HAL_OK)
 {
 return 0xFFFD;
 }

 return (U16)HAL_ADC_GetValue(&hadc2);
}

 

Best answer by azdepfr

@TDK, @Ozone Thanks for your comment.

I restart the issue description, and I re-send test software.

On a custom board, I use HRTIM to manage buck-boost MosFet.
HRTIM trigs ADC1 (VIN) and ADC2 (VOUT).

ADC1 Regular is used to : VREFINT, TEMPSENSOR
ADC2 Regular is used to : MosFetTemp1, MosFetTemp2, AnalogStartInfo

I haved issue by using TEMPSENSOR, between two conversions (100mS) some time I haved 10°C.

I tried on a Nucleo-F334R8 with STCubeIDE, I developped a soft to check.
The software can read 100 times (every 100mS) VREFINT(ADC1), TEMPSENSOR(ADC1) and an external signal(ADC2), then start HRTIM, then read 100 times analogs signals.

The software is executed in debug to be able to set breakpoint.
By using breakpoint, I can execute (or not) the first loop, then I can execute (or not) HRTIM start, then I execute the second loop.
The analog values are stored in a array (VREFINT and TEMPSENSOR in the same array), I read array in stop mode by using the debugger.
The issue is present on VREFINT, TEMPSENSOR and external signal. To simplify I describe only TEMPSENSOR.

test 1:
- read in first loop => TempSensor is stable 1739,1740,1739,1738,1740,1742 etc etc
- HAL_ADCEx_InjectedStart_IT called
- read in second loop => TempSensor is stable 1740, 1743, 1743, 1739 etc

test 2:
- NO read in first loop
- HAL_ADCEx_InjectedStart_IT called
- read in second loop => TempSensor is UNstable and wrong 1435, 1452, 1440, 1485, 1472, 1439, etc

test 3:
- NO read in first loop
- HAL_ADCEx_InjectedStart_IT NOT called
- read in second loop => TempSensor is stable 1738, 1736, 1740, 1739 , 1737 etc etc

test 4:
- read in first loop => TempSensor is stable
- HAL_ADCEx_InjectedStart_IT NOT called
- read in second loop => TempSensor is stable

So :
- if HAL_ADCEx_InjectedStart_IT is not called : TempSensor always stable (values are in a small range)
- if HAL_ADCEx_InjectedStart_IT is called :
-- if I execute the first loop : TempSensor always stable
-- if I don't execute the first loop :
--- Tempsensor is wrong ( 1430 to 1492 ) => cpu temperature > 100°C !!!
--- Tempsensor is not stable ( some time 60 units between two sample )

I use HAL_ADC_PollForConversion too read regular adc. (I tryed interrupt, but no effect).
I tried with/without HAL_ADC_Stop.
I tried to use only one conversion and reconfigure adc before start conversion, no effect.

At the end of last week I tryed DMA, it's ok, Tempsensor is alaways stable, with/without HAL_ADCEx_InjectedStart_IT and with/without read adc before start hrtim.

I read errata, I saw issue hrtim can disturb DAC, but nothing about hrtim/adc.

If there is a known limitation or recommended approach for mixing regular + injected conversions on STM32F334, I would be very interested.

 

I hope to be clear, sorry for my English !

 

Best regard's

10 replies

TDK
Super User
March 19, 2026

Nothing in the errata sheet about this.

Is this custom hardware? Can you show schematic? Are there solid VREF connections with bypass caps?

"If you feel a post has answered your question, please click ""Accept as Solution""."
Andrew Neil
Super User
March 19, 2026

@azdepfr wrote:

As soon as the HRTIM is initialized (even without starting it), the ADC regular conversion values become unstable.


What, exactly, do you mean by "unstable" ?

Please show some actual figures.

As @TDK said, please also show your hardware setup.

Do you see noise appear anywhere else in this system when this happens?

 

How to write your question to maximize your chances to find a solution

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
azdepfrAuthor
Associate II
March 19, 2026

Hello,

Thanks @TDK and @Andrew Neil for your replies.

Regarding the hardware:

This is a custom board, so I cannot share the full schematic, but I can provide some details:

  • VSSA is directly connected to GND

  • VDDA and VBAT are connected to +3.3 V

  • Each VDD pin has a 100 nF decoupling capacitor placed close to the pin

  • However, there is currently no dedicated capacitor directly on VDDA

Regarding VREF:

  • VREF+ is internally tied to VDDA (no external reference used)

Regarding the "unstable" behavior:

Here are actual measurements (raw ADC values for TEMPSENSOR):

  • Without HRTIM initialization: values are stable around 1735–1739

  • With HRTIM initialized (but not started): values drop and fluctuate between 1380–1480

This range does not seem realistic, as it would correspond to a CPU temperature of around 120°C.

Additional observations:

  • The issue appears even if HRTIM is not started

  • The issue is still present if GPIOs are not initialized (no MOSFET switching)

  • The same behavior is observed on external ADC channels (ADC2), not only on internal channels

Question:

Could this be related to:

  • VDDA decoupling (missing capacitor directly on VDDA)?

  • Internal analog interference between HRTIM and ADC?

  • ADC clock or sampling configuration?

I have not yet observed obvious noise elsewhere, but I will investigate further.

Any suggestions or similar experiences would be very helpful.

Best regards,

Andrew Neil
Super User
March 19, 2026

@azdepfr wrote:

This is a custom board, so I cannot share the full schematic,


Just because it's a custom doesn't mean you can't share it!

If it's confidential, you could raise a direct support case with ST: https://ols.st.com/s/ 

Without seeing a schematic, we obviously don't have the full picture!

Can you reproduce this on an ST board ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
azdepfrAuthor
Associate II
March 19, 2026

Hello,

Thanks @Andrew Neil for your suggestion.

You are right, testing on an ST evaluation board would help to clearly distinguish between a hardware issue and an MCU-related behavior.

At the moment, I have only tested this on our custom board. I will try to reproduce the issue on an ST board (for example NUCLEO or Discovery with STM32F3 + HRTIM) to confirm whether the behavior is the same.

Regarding the schematic, I understand your point. Unfortunately, I cannot share it publicly due to company restrictions, but I will consider opening a support ticket with ST if needed.

In parallel, I will also try to improve the VDDA decoupling (adding a capacitor directly on VDDA) and check if it impacts the measurements.

I will report back with the results.

Best regards,

TDK
Super User
March 19, 2026

Probably this is (unlikely) an undocumented deficiency in the silicon or (likely) there is more to the story here (hardware design error?). It's hard to know which from the outside, but my money is on the latter.

Reproducing on known good hardware would be a good next step. Barring that, reproducing on several different boards can also provide information. Attaching a minimal working example that shows the problem can help, but what you attached is pretty good.

I don't see any issues in the posted code. Don't have an F3 board to test.

Is VDDA connected to VDD? If not, is it always greater than VDD and provided first? These are requirements per the data sheet.

"If you feel a post has answered your question, please click ""Accept as Solution""."
azdepfrAuthor
Associate II
March 19, 2026

Hello,

Thanks @TDK for your detailed feedback.

Yes, VDDA is directly connected to VDD (both at +3.3 V), so it should meet the requirement of being at least equal to VDD and powered at the same time.

However, as mentioned earlier, there is currently no dedicated decoupling capacitor directly on VDDA, which might be an issue. I will add proper decoupling (100 nF + 1 µF close to VDDA/VSSA) and check if it improves the situation.

I agree that reproducing the issue on known good hardware would be a very useful step. I will try to run the same test on an ST evaluation board to determine whether this is related to our hardware design or not.

I will also try to reproduce the issue on another board of the same design to see if the behavior is consistent.

Regarding your comment about a potential hardware issue, I understand your point. The fact that the problem appears as soon as HRTIM is initialized (even without switching activity) suggests that enabling internal analog blocks may be affecting VDDA or the reference.

I will report back with the results after these tests.

Best regards,

azdepfrAuthor
Associate II
March 25, 2026

Hello,

I test on a Nucleo-F334, and I observe an unexpected behavior when mixing ADC regular and injected conversions on the same ADC.

The issue appears when starting injected conversions triggered by HRTIM.

Configuration

  • MCU: STM32F334
  • ADC used: ADC1
  • Regular channels:
    • VREFINT
    • TEMPSENSOR
  • Injected channel:
    • ADC_CHANNEL_1
    • Trigger: HRTIM_TRG2
  • HAL drivers (CubeMX generated project)

Test description

I built a minimal test project with:

  • ADC initialized normally
  • Internal channels enabled (VREFINT + TEMPSENSOR)
  • Regular conversions done by polling (no DMA, no interrupt)
  • Injected conversion started with:

HAL_ADCEx_InjectedStart_IT(&hadc1);

Test results

Test 1

  • Read VREFINT & TEMPSENSOR in a first loop → stable
  • Start injected conversion
  • Read again → stable

Test 2

  • No read before starting injected conversion
  • Start injected conversion
  • Read VREFINT & TEMPSENSOR → unstable

Test 3

  • No injected conversion
  • Read → stable

Test 4

  • Read first loop
  • No injected conversion
  • Read again → stable

Key observation

The instability appears only if:

  • injected conversion is started
  • AND no regular conversion was performed beforehand

It seems that performing at least one regular conversion before enabling injected conversions “stabilizes” the ADC behavior.

Additional checks

  • ADC calibration performed → no effect
  • Adding HAL_ADC_Stop() after conversions → no effect 

    Code excerpts

    Injected configuration:

    sConfigInjected.InjectedChannel = ADC_CHANNEL_1;
    sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1;
    sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_19CYCLES_5;
    sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_HRTIM_TRG2;
    sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;

    HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected);
    HAL_ADCEx_InjectedStart_IT(&hadc1);

    Regular read (simplified):

    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 10);
    value = HAL_ADC_GetValue(&hadc1);

 

Expected behavior

Regular conversions should remain stable regardless of whether injected conversions are started or not.

Actual behavior

Regular conversions become unstable depending on initialization sequence.

Question

Is this a known limitation or expected behavior of STM32F334 ADC?

More specifically:

  • Is there a required sequence when mixing regular and injected conversions?
  • Is an initial “dummy conversion” required after enabling internal channels?
  • Could this be related to ADC internal multiplexer behavior or known errata?

Thanks in advance for your help.

 

PS : I join CubeIDE project

Andrew Neil
Super User
March 25, 2026

What about your original observation that it seemed to be  starting HRTIM which caused the "instability" ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
azdepfrAuthor
Associate II
March 25, 2026

@Andrew Neil  Good point, thanks for raising this.

I initially suspected HRTIM because the issue appeared after enabling it in my main project.

However, after isolating the problem in a minimal test, I can clarify the behavior:

  • HRTIM initialization alone (MX_HRTIM1_Init) does NOT cause any instability
  • ADC regular readings remain fully stable as long as injected conversion is not started

The instability appears only when:

HAL_ADCEx_InjectedStart_IT(&hadc1);

is called, with the injected trigger configured from HRTIM.

So the key point seems to be:

  • not HRTIM initialization itself
  • but the activation of injected conversions (triggered by HRTIM)

Also, I observed that:

  • if at least one regular conversion is performed before starting injected conversion → stable
  • if not → regular readings become unstable

This suggests a dependency on the ADC internal state before injected conversions are enabled.

So at this stage, my understanding is that the issue is related to the interaction between:

  • ADC regular conversions (internal channels)
  • ADC injected conversions
  • and the HRTIM-triggered injection mechanism

rather than HRTIM alone.

Let me know if you think I should further isolate the trigger (for example by disabling HRTIM events while keeping injected configured).

azdepfrAuthor
Associate II
March 27, 2026

Hello,

I would like to share an update regarding my previous issue with ADC regular conversions becoming unstable when using injected conversions triggered by HRTIM on STM32F334.

 

  • ADC1 is used for:
    • injected conversions (triggered by HRTIM, for control loop)
    • regular conversions (VREFINT and TEMPSENSOR, for monitoring)
  • Regular conversions were initially handled using interrupt mode (HAL_ADC_Start_IT())

Observed behavior:

  • Without injected conversions → regular measurements are stable and correct
  • With injected conversions enabled → regular measurements become unstable or incomplete
  • Behavior was also sensitive to initialization sequence (e.g. performing some reads at startup changed the outcome)

Additional investigation

I verified that:

  • Polling mode works correctly:
    • both VREFINT and TEMPSENSOR are measured
    • values are stable and consistent
  • Therefore:
    • ADC configuration is correct
    • internal channels are correctly enabled
    • the issue is not related to hardware (VDDA, etc.

Solution using DMA

I reconfigured the regular group as:

  • Scan mode with 2 ranks:
    • Rank 1 = VREFINT
    • Rank 2 = TEMPSENSOR
  • DMA in normal mode (2 samples)
  • Triggered with:

HAL_ADC_Start_DMA(&hadc1, buffer, 2);

Result:

  • Both values are correctly acquired in all cases
  • Measurements remain stable even when injected conversions are active
  • No dependency on initialization sequence anymore

Conclusion

This strongly suggests that:

  • The ADC itself is working correctly
  • The issue is related to interrupt-based handling of regular conversions in scan mode
  • Mixing regular (interrupt mode) and injected conversions on the same ADC can lead to unreliable behavior (likely due to EOC/EOS flag handling and timing)

Using DMA for regular conversions avoids this issue completely and provides robust behavior.

 

For this application, the following architecture works reliably:

  • Injected conversions (HRTIM-triggered) → interrupt
  • Regular conversions → DMA (scan mode)
TDK
Super User
March 27, 2026

> As soon as the HRTIM is initialized (even without starting it), the ADC regular conversion values become unstable.

 

> Without HRTIM initialization: values are stable around 1735–1739

> With HRTIM initialized (but not started): values drop and fluctuate between 1380–1480

 

> HRTIM initialization alone (MX_HRTIM1_Init) does NOT cause any instability

 

With conflicting statements like these it's hard to provide any real help, or even trust what is being said is accurate. I suggest posting actual code being used rather than AI generated "summaries".

"If you feel a post has answered your question, please click ""Accept as Solution""."
Ozone
Principal
March 30, 2026

> With conflicting statements like these ...

IMHO already the use of terms like "unstable" in this matter reveal that the OP doesn't understand the underlying problem.

Execution of code in embedded systems does not happen in an abstract space, but on real hardware and peripherals with complex interactions. Any approach by coding tricks or statistics are bound to fail.

azdepfrAuthorBest answer
Associate II
March 30, 2026

@TDK, @Ozone Thanks for your comment.

I restart the issue description, and I re-send test software.

On a custom board, I use HRTIM to manage buck-boost MosFet.
HRTIM trigs ADC1 (VIN) and ADC2 (VOUT).

ADC1 Regular is used to : VREFINT, TEMPSENSOR
ADC2 Regular is used to : MosFetTemp1, MosFetTemp2, AnalogStartInfo

I haved issue by using TEMPSENSOR, between two conversions (100mS) some time I haved 10°C.

I tried on a Nucleo-F334R8 with STCubeIDE, I developped a soft to check.
The software can read 100 times (every 100mS) VREFINT(ADC1), TEMPSENSOR(ADC1) and an external signal(ADC2), then start HRTIM, then read 100 times analogs signals.

The software is executed in debug to be able to set breakpoint.
By using breakpoint, I can execute (or not) the first loop, then I can execute (or not) HRTIM start, then I execute the second loop.
The analog values are stored in a array (VREFINT and TEMPSENSOR in the same array), I read array in stop mode by using the debugger.
The issue is present on VREFINT, TEMPSENSOR and external signal. To simplify I describe only TEMPSENSOR.

test 1:
- read in first loop => TempSensor is stable 1739,1740,1739,1738,1740,1742 etc etc
- HAL_ADCEx_InjectedStart_IT called
- read in second loop => TempSensor is stable 1740, 1743, 1743, 1739 etc

test 2:
- NO read in first loop
- HAL_ADCEx_InjectedStart_IT called
- read in second loop => TempSensor is UNstable and wrong 1435, 1452, 1440, 1485, 1472, 1439, etc

test 3:
- NO read in first loop
- HAL_ADCEx_InjectedStart_IT NOT called
- read in second loop => TempSensor is stable 1738, 1736, 1740, 1739 , 1737 etc etc

test 4:
- read in first loop => TempSensor is stable
- HAL_ADCEx_InjectedStart_IT NOT called
- read in second loop => TempSensor is stable

So :
- if HAL_ADCEx_InjectedStart_IT is not called : TempSensor always stable (values are in a small range)
- if HAL_ADCEx_InjectedStart_IT is called :
-- if I execute the first loop : TempSensor always stable
-- if I don't execute the first loop :
--- Tempsensor is wrong ( 1430 to 1492 ) => cpu temperature > 100°C !!!
--- Tempsensor is not stable ( some time 60 units between two sample )

I use HAL_ADC_PollForConversion too read regular adc. (I tryed interrupt, but no effect).
I tried with/without HAL_ADC_Stop.
I tried to use only one conversion and reconfigure adc before start conversion, no effect.

At the end of last week I tryed DMA, it's ok, Tempsensor is alaways stable, with/without HAL_ADCEx_InjectedStart_IT and with/without read adc before start hrtim.

I read errata, I saw issue hrtim can disturb DAC, but nothing about hrtim/adc.

If there is a known limitation or recommended approach for mixing regular + injected conversions on STM32F334, I would be very interested.

 

I hope to be clear, sorry for my English !

 

Best regard's