cancel
Showing results for 
Search instead for 
Did you mean: 

Syncronous Timers

DetlefS
Associate III

Hi,

I'm running two timers on STM32F303 which do square wave output on two hardware pins. They are clocked by the 72MHz internal clock. They count down to 0 and reload from ARR register, which sets the output frequency. The two timers run perfectly syncronous, i.e the CNT registers of the timers have a constant offset.

Then I permanently have to switch the frequency for both timers by modifying the ARR registers.  As a result the CNT registers of the two timers begin to slip, i.e. the offset is changing.

I suspect the following: I modify the two ARR registers consecutively. I check for CNT counters to be high enough so no reload takes place while modifying the ARR registers.  Maybe an interrupt happens in between ARR update for the first counter and ARR update for the second counter. So one CNT register is updated from the old ARR value, the other from the new one. So the two counter values begin to slip.

 

I use the eval board for STM32F303 and initialize all to the default values with CubeIDE12. I hope and I'm quite sure I killed all interrupt sources, but there are hidden corners in CubeIDE. When I check the runtime of an arbitrary set of code I get changing numbers of systicks for that code. I'm running the board over the USB debug setup from the host, so the debug may kick in with interrupts.

 

How can I switch off all interrupt, especially with regard to CubeIDE and debug mode from host?

 

Thank you.

Cheers

Detlef

 

2 REPLIES 2
MasterT
Lead

If I need two timers in sync, than configure both of them in slave mode and add one more Master timer. Than to do PWM reconfig,  I stopped master timer, change two slaves configuration, and than start master.

TDK
Guru

__disable_irq() will globally disable all interrupts. It would be fine to call this while you update the registers.

__disable_irq();
TIM1->ARR = xxx;
TIM2->ARR = xxx;
__enable_irq();

You should re-check to ensure TIM1->CNT is in the appropriate range after you disable interrupts and before you set ARR.

Using systick to time events isn't the most precise thing. And it will be invalid if you have interrupts disabled. It would be better to use DWT->CYCCNT or a 32-bit timer.

Your method for resetting the timers should work. If they're upcounting, which is typical, you would wait for them to overflow (i.e. have a low CNT), then update. If you know which one is behind the other, and they're only off by a few counts, this should be straightforward.

If you feel a post has answered your question, please click "Accept as Solution".