PICchip Interrupts

86 downloads 311 Views 14KB Size Report
Feb 3, 2010 ... The CCS C compiler does most of the dirty work required for interrupts. You write a function that gets called on interrupt, set the interrupt enable ...
PICchip Interrupts Interrupts are used to service action requests that either (1) must be serviced immediately, or (2) come at unknown intervals. The telephone is a good analogy for thinking about interrupts

INTERRUPT

INTERRUPT SERVICE TASK

BACKGROUND TASK

RETURN

Interrupt flow On interrupt, program jumps to location 0004 and executes whatever instructions start there. It is up to the programmer to locate the interrupt service routine there. A common way to structure asm code is (example from book “Easy Microcontrol’n)

start

isr

org goto

0x000 start

; assemble code starting at 0x000 ; on reset jump to real start

org goto

0x004 isr

; assemble code starting at 0x004 ; on interrupt jump to service routine

....main code goes here sleep

; end of main code

....interrupt service routine goes here retfie ; return from interrupt

Interrupt sources RBO

On edge change at pin B0 (= pin INT). Set bit in Option register to set which edge direction triggers the interrupt

Timer

On TMR0 overflowing from 0xFF to 0x00.

interrupts.doc

Page 1 of 3

2/3/2010

Port B change

When any of bits 4, 5, 6, or 7 of Port B change their state. Only those lines set as inputs can trigger the interrupt.

ADC

On A/D conversion complete

Serial

On receiving a serial character or on completion of sending a serial character

There are other interrupt sources as well; see the PICchip data sheet for the details. An interrupt will only occur if the interrupt enable bit for the source is set. No interrupts will occur unless the global interrupt bit is set.

Multiple interrupts If a interrupt from another source comes during an interrupt service routine, the code stays in the current routine. On completion, it will service the second interrupt. If two interrupts happen at the same time, both interrupt bits will be set. The user code placed at location 0x0004 determines which interrupt to service first.

Saving status The interrupt can come at any time so the interrupt service routine must save critical registers at the top of the ISR and restore at the end. The CPU automatically saves the program counter so that the RETFIE knows where to go. At a minimum, the user should save the W and Status registers. Here is an example taken from the 16F88 data sheet. MOVWF SWAPF MOVWF .... (ISR) SWAPF MOVWF SWAPF SWAPF RETFIE

W_TEMP STATUS,W STATUS_TEMP

;Copy W to TEMP register ;Swap status to be saved into W ;Save status to bank zero STATUS_TEMP register ;(Insert user code here)

STATUS_TEMP,W ;Swap STATUS_TEMP register into W STATUS ;Move W into STATUS register W_TEMP,F ;Swap W_TEMP W_TEMP,W ;Swap W_TEMP into W ;Return from interrupt

Interrupts in CCS C The CCS C compiler does most of the dirty work required for interrupts. You write a function that gets called on interrupt, set the interrupt enable bit and global interrupt bit in the main code and you are on your way. Read the CCS C help file for details. The only reason to write your own interrupt handler in asm is if you need to reduce the delay between the interrupt occurring and the isr.

interrupts.doc

Page 2 of 3

2/3/2010

Here is a snippet from a program that uses interrupts. #define BASECOUNT 100 int1 timetosend; int8 ans; void main(void) { //-------enable interrupts enable_interrupts(INT_RDA); enable_interrupts(INT_RTCC); enable_interrupts(GLOBAL);

// receive serial char // rtcc clock

//-------loop forever while (TRUE) {}

// action happens in isr

} /******************************************************* RTCC interrupt service routine *******************************************************/ #int_rtcc rtcc_isr() { set_timer0(BASECOUNT); timetosend=1;

//reset the counter //set a flag

} /******************************************************* RDA serial port character receive interrupt service routine *******************************************************/ #int_rda void serial_isr(void) { ans = getc(); }

//get the character

Interrupts are useful but can be tricky Interrupts can be difficult to program, particularly when there are multiple interrupts. For example, say your program is getting numbers over the serial line from a host PC and multiplying the numbers to the result of an A/D conversion. Now consider what happens if the serial character receive interrupt happens right in the middle of the multiply routine (a set of 6 or so assembly language instructions). When you return from the interrupt you might have half of the old number and half of the new number fresh from the PC. Or consider what happens if you get a second interrupt while you are in an interrupt service routine. Will you finish the ISR in time to catch the second before it is too late?

interrupts.doc

Page 3 of 3

2/3/2010

Suggest Documents