2
\$\begingroup\$

I'm running the MCU off the high speed (16MHz, confirmed) internal oscillator and I've configured timer 1 to overflow with maximum overflow frequency:

/* No system clock pre-division, overflow upon reaching 0x0001 (starting from 0x0000) */
TIM1_TimeBaseInit(0, TIM1_CounterMode_Up, 0x0001, 0);

Once in the timer 1 overflow handling routine, I toggle a pin. For some reason I'm getting only getting a 32kHz square wave on that pin (hence 64kHz interrupt frequency).

Why is it so slow?

The same problem occurs with other timers as well.

Update: Ok, so I ran the timer with reasonable settings. Below are results for:

500 counts 500

300 counts 300

200 counts (unstable as hell) 200

100 counts 100

50 counts (frequency is the same down to 0 counts) 50

\$\endgroup\$
  • \$\begingroup\$ Is there a clock configuration tool for the STM8? STM clocKS are complicated, with different bus clocks and master clocks, and the tools help \$\endgroup\$ – Scott Seidman Nov 14 '14 at 11:32
  • 1
    \$\begingroup\$ Assume we aren't familiar with the function TIM1_TimeBaseInt() (I know I'm not), so break it down for us - tell us what the parameters mean, what you expect them to do, and what they actually seem to be doing. \$\endgroup\$ – Majenko Nov 14 '14 at 11:32
  • \$\begingroup\$ @Majenko-notGoogle First parameter: clock prescaler. Basically works like f_tmr1 = f_sysclk / prescaler + 1. I left it at 0 to use sysclk (16MHz) directly. Second: Timer mode, counter-up basically means timer is counting from 0 to some value. When the value is reached, interrupt occurs and counter is reset to 0. Third: Value to which the timer is counting. Fourth: Not sure, i think it's to lengthen time between interrupts, i'm not using that. Function performs exactly as expected. \$\endgroup\$ – andrey g Nov 14 '14 at 13:18
2
\$\begingroup\$

Ok, so the CPU is running at 16MHz. You have a "count to" value of 1. The counter starts at 0. After 1 tick the counter will be at 1, so the interrupt occurs and the counter resets.

Second tick you enter the ISR and start pushing registers to the stack. The counter increases to 1, so the interrupt occurs and the counter resets.

Third tick, you're still in the ISR from before, still pushing registers on to the stack, and you will be for the foreseeable future. But you want it to enter the ISR again, and you're already there. So the interrupt is delayed.

Fourth tick. You're still pushing to the stack, the counter increases to 1, so the interrupt triggers. The interrupt is already queued, so nothing at all happens. The counter resets to 0.

Eventually, after many many many ticks, and missed interrupts, you finish the ISR and return to normal program flow. Immediately the ISR runs again because of the delayed interrupt from earlier, and the whole cycle starts again.

What you are trying to do - run an interrupt every other CPU clock tick, is not physically possible. Interrupts take time to execute.

You cannot trigger an interrupt faster than the interrupt takes to process.

\$\endgroup\$
1
\$\begingroup\$

You should test this with a more realistic "count to" number. There are clock ticks associated with entering and leaving interrupts, and you shouldn't expect good functionality with an interrupt every few ticks. Try it with 100 or 200, and let us know what happens. I still wouldn't expect the timer to be as slow as it is, even with your settings, but you should build a realistic test case.

With the updated figs, the period for the 100 count is about 38 microsecs, so the 100-count ticks are at about 19 microsec

(19e-6)/100 would be the clock count rate, = 19e-8.

1/19e-8 = 5.3 MHz

I'm not sure what speed your bus is programmed to go at

\$\endgroup\$
  • \$\begingroup\$ I've added examples you suggested. There is nothing running in the program except for interrupt handling (I do take care of the interrupt flag). \$\endgroup\$ – andrey g Nov 14 '14 at 17:10
  • 1
    \$\begingroup\$ @andreyg -- what is the time scale of those captures? \$\endgroup\$ – Scott Seidman Nov 14 '14 at 17:35
  • \$\begingroup\$ It's show in the interface below - 10us. \$\endgroup\$ – andrey g Nov 14 '14 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.