cancel
Showing results for 
Search instead for 
Did you mean: 

Timer channel 1 running ''regular timer'' and channel 2 generating square wave. How?

arnold_w
Senior
Posted on November 15, 2017 at 16:40

I am working with the stm32f4-discovery development board and I need to share timer 3 for two purposes:

1.  Regular timer that can be scheduled with 1 ms accuracy:

scheduleTimer3(uint16_t delayMs, EventCallback_t callback)

This is easy to implement, I have set the prescalar (TIM3->PSC) so that the timer increments every 1 ms and then I set TIM3->CCR1 to the desired

delay

Ms

. TIM3->ARR is set to 0xFFFF which means the biggest delay I can accomplish is 65535 ms and that's fine.

2.  A square wave with frequency of roughly 60 Hz (55 - 64 Hz is fine) on the pin connected to timer 3 channel 2. This is also fairly easy to achieve by itself, I just use PWM and set TIM3->ARR to 1000/60 = 16 and TIM3->CCR2 = 

TIM3->ARR/2.

But how can I do both 1 and 2 at the same time? The problem with this approach is that they require different TIM3->ARR values at the same time. Of course, I can use the lower TIM3-ARR value and then increment a counter in interrupts and only call the callback when a number of interrupts has occurred, but it seems inefficient. Surely there must be a better way to do this. Can someone please help me?

5 REPLIES 5
Posted on November 15, 2017 at 16:46

The TIM has a single counting element.

One could use toggle mode on the pin with the square wave, and keep advancing the CCRx while keeping ARR maximal.

For periodics set the CCRx = CNT + n

If you have SysTick running at 1 KHz, schedule things there with a list of events and a down count to firing.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 15, 2017 at 17:01

I have disabled SYSTICK so it doesn't exist in my product. Is there no way to keep TIM3->ARR at maximum and generate a square wave automatically, without having to do processing in interrupts?

Posted on November 15, 2017 at 17:40

No, not really. It's one of the areas in which the TIM design doesn't work with you.

You could set the square ware up at 60 Hz, I'd do that at sub-millisecond counts. Then for up to 15-16 ms delays use a CCRx = (CNT + n) % (ARR + 1) to set a firing point

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 15, 2017 at 17:58

One option is to use DMA to reload CCRx from a precalculated table (no shadow of course).

JW

S.Ma
Principal
Posted on November 16, 2017 at 05:13

The HW goal is to reduce the SW timing stress by few order of magnitude.

If you need 60Hz PWM, you need 0.17msec

If your PWM has 100 steps (percentage), your timer LSB count will be 0.0017msec=1.7us or lower.

16 bit timer will get you at 1.7 x 65k = 111 msec roughly as maximum delay with PWM.

Then you need to create a RAM array to place all the PWM counter values to toggle at the right time or 2000x16 bit values = 4kbyte of SRAM. Everytime you need to change the percentage, you recalc all the values on the fly.

This being the most extreme. If you get modest with around 10 msec timer overflow (ARR lower), things might compromize. The array benefit is you can modulate your PWM which sometime is interesting, sometime not.

Your questions sound like the core frequency is very low that msec SW management becomes critical.

Don't know if the timer repeat counter can be used to relax some of these generic concept implementation.

Use the HW to make the best compromize for your specific needs.