interrupts, higher frequency

Thread Starter

conanav

Joined Jun 14, 2008
14
Hello All

I am currently using interrupts with the pic18f2520 TMR0 timer in order to obtain delays. I am trying to obtain as large frequency as possible for the timer in order to be able to set the smallest possible delays. If my understanding is correct, if I have a 10 MHZ external clock and i set the starting val of TMR0 = 255, and PRESCALER to 1:1 I should be able to obtain clock pulses every 100 ns, thus allowing delays remotly resembling this value(<1us is close enough). However for some reason when i set the TMR =255 and scaler to 1:1 I do not see any output pulses, same case for scaler 1:2, only when i set it to around 1:4 i start to see pulses but they are at about 35-40 us and thats not even close to my desired frequency(period~1us).This is my code and maybe one of you can find what I should change in order to adjust this.

Thanks
//--------------------------------------------------------------------
Code:

unsigned cnt;


void interrupt() {
cnt++;
TMR0L = 254;
INTCON = 0x20; // Set T0IE, clear T0IF
}

void main() {
ADCON1 = 0x0F;
T0CON = 0b11000011; // prescaler 1:16
TRISB = 0;
PORTB = 0xFF;
TMR0L = 255;
INTCON = 0xA0;
cnt = 0;

do {
if (cnt == 1) {
PORTB = ~PORTB; // LEDs
cnt = 0;
} while(1);
}
 

hgmjr

Joined Jan 28, 2005
9,027
//--------------------------------------------------------------------
Code:

Rich (BB code):
unsigned cnt; 
 
 
void interrupt() 
{ 
    cnt++; 
    TMR0L = 254; 
    INTCON = 0x20; // Set T0IE, clear T0IF 
} 
 
void main() 
{ 
    ADCON1 = 0x0F; 
    T0CON = 0b11000011; // prescaler 1:16 
    TRISB = 0; 
    PORTB = 0xFF; 
    TMR0L = 255; 
    INTCON = 0xA0; 
    cnt = 0; 
 
    do 
    { 
        if (cnt == 1) 
        { 
            PORTB = ~PORTB; // LEDs 
            cnt = 0; 
        } while(1); 
    }
}
Reformatted using code tags....

There was a missing curly-bracket in your source code. I assume it was a typo in the post since it is clear that program compiling was not a problem.

Since you are interested in maximizing your interrupt service routine's rate of execution, you may want to remove the timer reload from inside the routine. Any unecessary time spent inside the interrupt service routine increases the minimum frequency that you can achieve.

hgmjr
 

Thread Starter

conanav

Joined Jun 14, 2008
14
thanks nanovate and hgmjr. These small delays are slowly becoming my Everest when it comes to my lacking knowledge of PICs. I can bring them down to 15-20us with max code optimization(same interrupt technique as above), and smaller prescaler. I got it running at 1:8 with different timer0 initialization value but still it isn't close to my desired freq. I thought that if the interrupt takes 4 clock cycles then with 10 MHz external clock I should be able to get pulses at 2.5 MHz or every 400 ns.

Hgjr: By the "timer reload inside the routine" do you mean "TMR0L=254;". If i remove it won't the timer reset itself to 0 after overflow, and give me 255 counts instead of a single count?

Nanovate: I am only starting to learn about PWM and CCP modules on the chip. I know that PWM can be used to modulate the pulse period in order to obtain analog voltage output but how can I override the delay limitations of the interrupt function that I have listed above. If you could elaborate a little on these two modes(PWM and CCP) I would be very grateful. Better yet, If you have used either one or both modes, could you tell me how small did you get the delay to be?
 

nanovate

Joined May 7, 2007
666
I thought that if the interrupt takes 4 clock cycles then with 10 MHz external clock I should be able to get pulses at 2.5 MHz or every 400 ns
The problem is that the device has a certain latency ... I forgot how many instructions... between when the interrupt occurs and the ISR is executed. There is also a RETI-type instruction (return from interrupt) that is executed before going back to the main program. This is in addition to what the ISR has to do.

You can get rid of cnt and just toggle the pin inside the ISR. The way you have the code the ISR has to increment the cnt then the do-while has to evaluate cnt then it toggles-- more instructions between toggles.

BTW a 10MHZ external clock is PLL'd to 40MHz internally so that you can get ~10MIPS. If the PLL is not enabled then you are getting ~2.5MIPS.
 

Thread Starter

conanav

Joined Jun 14, 2008
14
ooohhh, thats the deal with the internal PLL clock. I thought the external specifies the FOsc, so now i can deal with 40 MHz instead of 10MHz so theoretically i shoudl be able to drop the period below 1us.
 

nanovate

Joined May 7, 2007
666
The PIC18s are 4 clocks per instruction (mostly) so a 10MHz external that gets PLL'd to 40MHz takes about 100ns per instruction. If you can do the toggling w/less than 10 instructions then yes you can go below 1us.
 
Top