2026-03-18 6:59 AM - last edited on 2026-03-19 1:41 AM by Gyessine
Hi,
I am currently working on a project where I want to adjust the duty cycle and trigger an ADC measurement on every counter rollover.
I managed to get the PWM running in center-aligned mode, but I’m having trouble triggering the counter rollover at the correct moment.
To verify whether the trigger is correct, I routed the output compare signal to an external pin and observed it on an oscilloscope.
The basic idea is to run an additional counter alongside the PWM. This counter should count up to ARR and then generate a trigger that starts the ADC conversion. Becuase in the center aligned mode two update event occurs both on CNT=0 and CNT=ARR.
On the oscilloscope, it looks like the trigger—presumably when CNT = 0 (at least that’s my assumption)—produces an edge.
Im using NUCLEO-G491RE.
What could I be missing here? What might be causing this behavior?
Yellow (PWM TIM8 Channel3), Blue (PWM TIM8 Channel1), Orange (Capture Compare TIM8 Channel 4)
Thank you in advance!
Simon
Solved! Go to Solution.
2026-03-19 3:09 AM
> I implemented this using a capture/compare configuration.
There is no "capture/compare" configuration. The individual channels in a timer can be set to either Output Compare (TIMx_CCMRx.CCxS = 0b00), or to Input Capture (all 3 other settings of TIMx_CCMRx.CCxS). You've set TIM8_CH4 (i.e. not "an additional counter alongside the PWM" as you've written in your initial post, but an additional channel in the same TIM8 where you've set CH1 and CH3 to PWM), to Output Compare; and, what's important in this context, to Toggle mode (by setting TIM8_CCMR2.OC4M=0b0011, even if it was Cube/HAL which set it for you). You've set - consistently to your initial description - TIM8_CCR4=TIM8_ARR (=1699), and thus the CH4 CCx signal - i.e. which you probably want to propagate to ADC via TRGO2 - should indeed provide a pulse when TIM8_CNT reaches TIM8_ARR.
Neither of the channels is inverted by setting TIMx_CCER.CCxP, and CH1 and CH3 are set to PWM1 mode (i.e. TIMx_CCMRx.OCxM=0b0110), for which:
which means, that:
so, as you see, TIM8_CH4 toggles exactly as you've set it, at TIM8_CNT=TIM8_ARR=1699.
The reason why it's different than your drawing of expected waveform is, that the polarity of PWM channels is opposite to what you expect. You can either change that or change to PWM2 mode; but note, that the pulse-high-length is then not given directly by TIM8_CCRx, but by TIM8_ARR - TIM8_CCRx.
JW
2026-03-18 1:42 PM
I don't understand, what's the problem. What is the expected behaviour and how is the observed one different from that? Maybe try too sketch a timing diagram.
> The basic idea is to run an additional counter alongside the PWM.
Do you display that additional counter's output in some way on that oscilloscope picture?
JW
2026-03-19 12:17 AM
Hi, I’m sorry if my previous explanation was unclear — I’ll try to describe it more precisely.
In my understanding, in center-aligned mode the counter (CNT) counts up to ARR and then back down to 0. I would like to trigger an ADC measurement exactly when CNT = ARR. However, I am not sure how to implement this correctly.
My approach was to use a second channel to generate a signal when CNT = ARR. I implemented this using a capture/compare configuration. To verify whether the trigger actually occurs at CNT = ARR, I routed the capture/compare signal to an output pin, which toggles when CNT reaches the compare value.
However, the oscilloscope measurement shows that the capture/compare signal (orange) toggles when CNT = 0, not when CNT = ARR.
Based on my understanding, the behavior should match the attached drawing: the edge of the capture/compare signal should trigger the ADC measurement, so that the measurement occurs in the center of the PWM.
Additionally, I have another question:
How can I ensure that all channels always start simultaneously?
I hope this explanation is clearer.
Best regards,
Simon
2026-03-19 3:09 AM
> I implemented this using a capture/compare configuration.
There is no "capture/compare" configuration. The individual channels in a timer can be set to either Output Compare (TIMx_CCMRx.CCxS = 0b00), or to Input Capture (all 3 other settings of TIMx_CCMRx.CCxS). You've set TIM8_CH4 (i.e. not "an additional counter alongside the PWM" as you've written in your initial post, but an additional channel in the same TIM8 where you've set CH1 and CH3 to PWM), to Output Compare; and, what's important in this context, to Toggle mode (by setting TIM8_CCMR2.OC4M=0b0011, even if it was Cube/HAL which set it for you). You've set - consistently to your initial description - TIM8_CCR4=TIM8_ARR (=1699), and thus the CH4 CCx signal - i.e. which you probably want to propagate to ADC via TRGO2 - should indeed provide a pulse when TIM8_CNT reaches TIM8_ARR.
Neither of the channels is inverted by setting TIMx_CCER.CCxP, and CH1 and CH3 are set to PWM1 mode (i.e. TIMx_CCMRx.OCxM=0b0110), for which:
which means, that:
so, as you see, TIM8_CH4 toggles exactly as you've set it, at TIM8_CNT=TIM8_ARR=1699.
The reason why it's different than your drawing of expected waveform is, that the polarity of PWM channels is opposite to what you expect. You can either change that or change to PWM2 mode; but note, that the pulse-high-length is then not given directly by TIM8_CCRx, but by TIM8_ARR - TIM8_CCRx.
JW
2026-03-19 3:20 AM
Ahh, that makes sense. Thank you very much for your excellent explanation — it helped me a lot.
Best regards,
Simon