Interrupts

From MARS Wiki

Jump to: navigation, search

Contents

What is an interrupt?

An interrupt is a way for hardware -- rather than software -- to trigger a call to a subroutine. What this means is that each time a hardware counter overflows or an external pin changes state, the processor will jump to some predefined memory location and run the code located there.

Why do we care?

Interrupts make it easier to multitask. Your code can be chugging along doing one thing and still respond to external stimuli in a timely fashion.

Interrupts on the PIC16F628A

There are several things that need to be set up before we can depend on interrupts.

Timer0

Timer0 is an 8-bit timer/counter register that can be used to trigger interrupts. It can be configured to increment after the execution of each instruction or with each transition on the RA4/T0CKI pin of the chip. When all the appropriate registers are configured, it generates an interrupt every time it overflows from 255 to 0.

The OPTION register

The OPTION register is where we configure the prescaler. The prescaler is a divider that it inserted between Timer0 and its clock source. Its sole purpose is to make Timer0 interrupts occur less frequently. For our applications as an LED blinker, we set the prescaler to the maximum possible value, 1:256.

The INTCON register

We also have to set up the INTCON register to enable interrupts. It is here that we enable the Timer0 interrupt and also enable interrupts for the entire chip by setting a couple of bits correctly.

Code organization

On the PIC16F628A, an interrupt will always generate a call to the subroutine located at program address 4. This means that our code should look something like the following:

	org 0
	goto	start	;jump over the interrupt service routine for now

	org 4
	;put all the interrupt code here
	retfie

start	;continue booting the processor

	.
	.
	.

	end

Saving and restoring program context

Another major point is keeping track of what the processor was doing before the interrupt took place. If there was a certain value in W, we should keep it there lest the interrupted program get "confused." At a bare minimum, we need to back up the W and STATUS registers to maintain CPU state when we return from the interrupt. We can use the following code to do that:

	;Note: This code assumes that two memory locations '_w' and '_s' have been defined.  
	org 4
	
	movwf	_w
	swapf	status,w
	movwf	_s
	.
	.	;rest of interrupt code goes here
	.
	swapf	_s,w
	movwf	status
	movf	_w,w
	retfie

This code will immediately save W upon entry into the interrupt service routine, then it saves the STATUS register in such a way that the STATUS register is not changed in the process. The process is reversed at the end of the interrupt routine -- STATUS is restored, followed by W. Doing it in this order makes sure that W contains the correct data when the main program is returned to.

Personal tools