2018-03-19 03:34 AM
Hi at all,
I am working since some days with STM32 ( + HAL, CubeMX), because I need a Source for a PMW with variable Frequency, where f = 20..200kHz and Duty Cycle 0..100%.
To realize this I started with a regular PWM with a fixed Period. That worked fine.
Example:
int main(void) {
..
Misc...Init
...
MX_TIM2_Init(200); // where 200 is htim2.Init.Period
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 100);}
void MX_TIM2_Init(int period) {
...
}
however when I change the period, then I have to follow the steps:
HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_1); // Stop PWM
MX_TIM2_Init(40); // re-initialize the Timer2
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); // Start PWM again
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, 20); // Set Duty Cuyle
it worked too, but it is slow and needed ca. 1000us. I need a method to switch faster (~100us). There are a lot of tricky ways to use the Timer in STM32, but I am not experienced enough to find the right way.
Can you give me a hint, what could be the most promising way to generate a PWM with a varibale Frequency and a fast way to switch (<100us) the Frequency?
thanks in advance
Paul
2018-03-19 05:51 AM
Use ARR to change period, and CCRn to change duty cycle.
See the data sheet.
2018-03-20 01:55 AM
Thanks to dhenry, I did it with
TIM2->ARR = <value>; // Period
TIM2->CCR1 = <othervalue>; // guess CCR1 means Channel 1, Duty Cycle
it worked, however sometimes it was unpredictable. I guess, when I set CCR1 to a smaller value as CCR1 before and the current counter is larger than the new value of CCR1, the counter runs at its end (32bit) and than it follows the new CCR1 value.
So I came back to my original configuration and I found a mistake in my measurements. I forgot to subtract the runtime of my loop in which i let run my Timer Configuration. Now I found a really good time < 10us. STM32F411 (100MHz) seems to be fast. :D
best regards, STM32_
2018-03-20 04:16 AM
'
however sometimes it was unpredictable.'
set the timer to up/down mode.
2018-03-20 04:17 AM
Thanks to dhenry, I did it with
TIM2->ARR = <value>; // Period
TIM2->CCR1 = <othervalue>; //
guess CCR1 means Channel 1, Duty Cycle
It means Capture-Compare Register, chanel 1. For PWM output modes, it may mean duty.
it worked, however sometimes it was unpredictable. I guess, when I set CCR1 to a smaller value as CCR1
before and the current counter is larger than the new value of CCR1, the counter runs at its end (32bit) and than it follows the new CCR1 value.
This is why you should use register shadowing, both for the CCRx and ARR. Please read the timer chaper in Reference Manual.
JW