2021-04-16 08:51 AM
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.
Solved! Go to Solution.
2021-04-16 09:32 AM
> I don't understand why.
Because this is how the timer is designed. This behaviour is documented in RM:
JW
2021-04-16 09:04 AM
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.
2021-04-16 09:32 AM
> I don't understand why.
Because this is how the timer is designed. This behaviour is documented in RM:
JW
2021-04-16 09:38 AM
Exactly
2021-04-16 10:50 AM
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.
2021-04-16 11:43 AM
What is "right edge aligned PWM"?
JW
2021-04-16 12:14 PM
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.