Maximum frequency for TMR0 Interrupt

Status
Not open for further replies.

thecritic

Member
I want to toggle a pin as fast as possible using TMR0.

I use this code (kind of pseudocode)
Code:
interrupt_isr()
{
           if(T0IF){

            togglepin();
            TMR0 = 255;
            T0IF = 0;

           }
}

What is the frequency I get? Well, due to 2 instruction delay if you write to TMR0, I should be getting an interrupt every third instruction cycle. With the pic (16f676) running on internal 4Mhz oscillator, 4 / 4 = 1Mhz is the clock for TMR0. Because it interrupts every third instruction cycle, it should give me a frequency of around 1/3 Mhz.

Am I correct? But Proteus ISIS simulation shows its just around 20Khz. How do you calculate the max possible frequency?
 
Check the assembler code generated by your C compiler. There will probably be 10 to 14 instructions for context saving and restore, then 4 inst for jump to interrupt and back out, and your interrupt contents are baout 6 or 7 insts. That's about 25 insts very best case, or about 40kHz but only IF you get it right and write the correct value to TMR0.

I think you need to re think your PIC choice and code operation if you need to do a task at 300kHz.
 
MPSIM is a great tool. Use Stopwatch to see timing values.
 
Last edited:
Thanks for clearing things up, Mr. RB. I really forgot to take into account the time spent on the ISR itself. So, Its impossible to interrupt every 3 instruction because for this you need to be interrupting from the ISR itself. And also the the extra-instruction generated for context saving and similar thing by C complier is an issue here.
I don't really need very fast frequency at the moment, just curious how much you can get.

@colin55; what ? How do I get a frequency of 500 khz? Why the glitch?

@atferrari Thanks. I am really loving it now. An accurarcy tool.

How do you convert your C code to Assembly code and do the MPLAB sim there. I want do see why a single C statment eats so much time?

And, after using the stopwatch, I am confused at this. With the PIC running from internal 4Mhz oscillator, how much time it takes for each Instruction? I thought (because of pipelining) its just 1/4Mhz = 0.25 us. Or I need to divide it by 4?
I thougt its only for TMR0 that we need to divide the clock by 4.

Thanks everybody.
 
ReRTFM

Fosc = 4 MHz > period T = 1/4000000 = 250 nsec

Tcy = 4T = 4 * 250 nsec = 1 usec

Reread the datasheet. Every 4 clock cycles you get one instruction dealt with.
 
Last edited:
Have a look in your compiler help file for details, the compiler should generate a .ASM file after compiling. You can look for that file and see what is in it.

I think the fastest non-glitched sqaure wave you can get is from this;
Code:
  movlw b'00000001'
loop
  xorwf PORTB
  goto loop
That produces a squarewave with 6 cycle loop or 1MHz / 6. (167kHz)

Or this;
Code:
loop
  bsf PORTB,0
  bcf PORTB,0
  goto loop
A 4 cycle waveform with 25% duty cycle at 1MHz / 4 (250kHz)
 
You don't even need to use the TMR0 interrupt flag. You can poll individual bits in the TMR0 register and have a pin switch high every time that bit switches high and vice versa for low.

Bit 0 transitions high to low and low to high every 1 count. Bit 1 transitions every two counts, bit 2 transitions every 4 counts, etc etc.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…