Skip to main content
SPetr.6
Associate II
Apr 16, 2021 3:51 PM UTC
Solved

Right edge aligned PWM

I've edited this post to make it more useful to others.

We are well into development of a board at work using an STM32F072RBT6 MCU. I just wrote a quick from scratch test using a NUCLEO-F072RB board to verify things. I'm not sure of the exact problem, but it appears TIM2 is adding 1 to the CCR. I have the timer configured that each count is 1 us, using PWM mode 1, and down-counting. If I write in a CCR of 0, I get a 1 us pulse. If I write in a CCR of 1, I get a 2 us pulse. If I write in a CCR of 2, I get 3 us pulse. You get the picture. I attached the demo project as a zip. I also setup TIM1, but used up-counting and it works as expected. main.c has some comments in it.

This topic has been closed for replies.
waclawek.jan
waclawek.janBest answer
Super User
Apr 16, 2021 4:32 PM UTC

> I don't understand why.

Because this is how the timer is designed. This behaviour is documented in RM:

0693W000008zoL3QAI.pngJW

6 replies

SPetr.6
SPetr.6Author
Associate II
Apr 16, 2021 4:04 PM UTC

OK. So TIM2 I had set for down counting and TIM1 for up counting. The "error" I am seeing is being caused by down counting, but I don't understand why.

waclawek.jan
waclawek.janBest answer
Super User
Apr 16, 2021 4:32 PM UTC

> I don't understand why.

Because this is how the timer is designed. This behaviour is documented in RM:

0693W000008zoL3QAI.pngJW

Apr 16, 2021 4:38 PM UTC

Exactly

waclawek.jan
Super User
Apr 16, 2021 6:43 PM UTC

What is "right edge aligned PWM"?

JW

SPetr.6
SPetr.6Author
Associate II
Apr 16, 2021 7:14 PM UTC

The PWM is high on the right side of the cycle. That is a higher CCR corresponds with a longer right sided high. With downcounting and PWM mode 1, you get this, but as you have pointed out, you can't achieve 0% duty cycle in this mode. I suppose I could stick with that mode and put in the condition that when I want 0% duty cycle, I just disable PWM for that channel, otherwise enable it and set the CCR as needed.

As we've been discussing, I did come up with this solution. Use up counting and PWM mode 2.

uint32_t max_ccr = __HAL_TIM_GET_AUTORELOAD(&htim2) + 1;
 uint32_t ccr = max_ccr - duty_cycle_ccr;
 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, ccr);

This works fine, but I was hoping to come up with a solution that doesn't involve having to do that math. All seems a bit odd why the downcounting method does not work.

I also don't understand what the difference between using PWM mode 1/2 or setting the polarity as active high/low. They seem to be two mechanisms that accomplish the same thing.