cancel
Showing results for 
Search instead for 
Did you mean: 

Right edge aligned PWM

SPetr.6
Associate II

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.

1 ACCEPTED SOLUTION

Accepted Solutions

> I don't understand why.

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

0693W000008zoL3QAI.pngJW

View solution in original post

6 REPLIES 6
SPetr.6
Associate II

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.

> I don't understand why.

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

0693W000008zoL3QAI.pngJW

Exactly

Wow, ok. Thanks for clearly pointing that out. What I am trying to come up with is a native way to perform right edge aligned PWM and this is what I came up with.​ Any advice on the proper way of doing this would be much appreciated.

What is "right edge aligned PWM"?

JW

SPetr.6
Associate II

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.