2016-03-14 03:19 AM
Hello there,
I have a question regarding output compare mode with 32 bit timers in STM32F4 mcu. I have only one 32 bit timer that is free to use. I need to generate interrupts for 2 events. Those events should occur periodically with a set frequency. The frequency for event 1 is not corresponding to frequency of event 2 and vice versa. I need to dynamically change the frequency of the events from 1 Hz to 5 kHz. Normally I would use two 32 bit timers for that, but I only have one left. I cant use a 16 bit timer, because while the frequency lowers, I would have to change the prescaller. I want to keep the prescaller constant and only change period. This way I can use a simple equastion that will give me period for an applied frequency: ARR = (sysClk / ((PSC(i) + 1) * desiredFreq)) - 1; So my question is, can I maybe use 2 channels of a 32 bit timer and use OC interrupts with no outputs? Or does this work like with pwm, that I can only set ''width'' but overall frequency wont change? For example, can I set TIM5 frequency to 1 Hz and manipulate CCR1 and CCR2 to get interrupts with frequencies 1 kHz and 3 kHz independently? I would appreciate all help!2016-03-14 04:39 AM
What you can do is update the CCR1 and CCR2 registers in their respective interrupts.
So you set TIM5 to run at the full period (ARR=0xffffffff). In the CCR1 interrupt, you increment CCR1 with the period of the first frequency, and in the CCR2 interrupt, you increment CCR2 with the period of the second frequency. You need to disable the preload register so the updates of CCR1 and CCR2 take effect immediately. Note that both CCR1 and CCR2 can trigger in the same interrupt, so you need to handle either or both in your interrupt routine, based on the flags set in TIM5_status. Hope this helps, - Kristian.2016-03-14 04:48 AM
I get the idea.
And lets say I am at the end of the period with one of the channels, for example: CCR1 is 0xFFFF FF00 and I want to increment by 0x1FF. Should I then place value 1 in CCR1 for the next interrupt?2016-03-14 05:01 AM
No, the correct value from adding 0x1FF to 0xFFFF FF00 would be 0x0000 00FF. In general, if TIM5_ARR is set to the max 0xFFFF FFFF, you just use 32-bit unsigned integer overflow semantics. So just add the numbers in your code with uint32_t type or similar, and the values will wrap around correctly to match the timer values. So you won't need to handle the wrap-around explicitly.
- Kristian.2016-03-14 05:08 AM
I understand now. It was my mistake, instead of 0x1FF i wanted to add 0x100. It would indeed reload like you stated anyways. Thank you for help.