2
\$\begingroup\$

I want to understand how the PIC instruction timing works. I've written the code below, and it toggles PORTB, pin 3. I analyze the results with an oscilloscope.

The PIC runs on 8MHz internal clock = 2MHz instruction clock (i.e. 500ns/single word instruction).

The oscilloscope shows me square waves with a period of 14*500ns.

My questions are:

  1. I want to match the observed square wave with the corresponding instructions. My idea is if I start at a rising edge I would say I've toggled LATB soo my chain of events is

btg -> retfie -> nop -> (now i'm guessing..) goto 0x000008 -> nop -> goto highPriInt -> nop -> btg

Is this correct? another idea would be

btg -> retfie -> nop -> nop (in loop) -> something for 1 cycle -> goto highPriInt -> nop -> btg

Question 2:

I never reset any interrupt flags but the highPriInt is called all the time. I know the 'retfie' command resets GIE bit but I thought I would have to clear the TMR0IF bit before another Timer interrupt could occur??

Best regards R

 ORG 0x000000 ; Action on reset goto main ORG 0x000008 ; High priority interrupt vector goto highPriInt ORG 0x000018 ; Low priority interrupt vector goto lowPriInt main: clrf PORTB ; Clear port B clrf TRISB ; Set all as outputs movlw 0xFF ; Set Fosc to 8MHz iorwf OSCCON, 1 movlw 0x5F ; Setup Timer0, not started yet! movwf T0CON bsf INTCON, 5 ; Enable Timer0 interrupts bsf INTCON, 7 ; Enable globla interrupts bsf T0CON, 7 ; Enable Timer0 loop: nop bra loop highPriInt: btg LATB, 3 ; Toggles Port B pin 3 retfie lowPriInt: retfie END 
\$\endgroup\$
7
  • \$\begingroup\$ Note that branch instructions take two cycles on most PIC devices. This is because the program counter is more than 8 bits wide, so must load two values to execute it. \$\endgroup\$ Commented Oct 9, 2015 at 17:13
  • \$\begingroup\$ Yes, that is why I added the 'nop's after each branching \$\endgroup\$ Commented Oct 9, 2015 at 19:10
  • \$\begingroup\$ Which PIC are you referring to? \$\endgroup\$ Commented Oct 9, 2015 at 19:39
  • \$\begingroup\$ Sorry forgot to write that. I'm using PIC18F4550 \$\endgroup\$ Commented Oct 9, 2015 at 19:42
  • \$\begingroup\$ Many, if not all 8-bit PICs take 4 cycles to implement an instruction. \$\endgroup\$ Commented Oct 9, 2015 at 20:01

2 Answers 2

1
\$\begingroup\$

In most cases with the PIC 12/16/18F if you don't clear the interrupt flag then the interrupt service routine will continue to fire.

From this Microchip document (page 3):

Generally the interrupt flag bit(s) must be cleared in software before re-enabling the global interrupt to avoid recursive interrupts.

Therefore the behaviour you are seeing is by design - you need to clear T0IF to prevent further interrupts from firing.

\$\endgroup\$
0
\$\begingroup\$

Interrupt routines keep being called if you don't reset the interrupt pending flag. This is true for many other CPU's as well, so it's always good practice to clear the interrupt pending flag at the end of your ISR routine.

On PICs and some other (older) CPUs you may also see that 1 interrupt "vector" is shared for multiple interrupts. In that case you should use the pending flag to execute the specific interrupt handler code and clear the flag within that handler.

I do not recommend clearing (all) interrupt pending flags willy-nilly at the end of the ISR routine without branching. In that case you could reset a pending flag (and miss the ISR) that was triggered while the CPU was handling another ISR.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.