Interrupts

Interrupts are a very important concept in programming a robot. The 6811 has the ability to be working on a task, get interrupted by a higher priority task, dispatch it, and resume execution of the first task. So the interrupt temporarily suspends the main task, handles an interrupt service routine in response to some interrupt signal, and then return to the main task. On a Miniboard, things that can cause interrupt signals are

When an interrupt occurs, the 6811 takes several automatic steps to save what it was just doing and find what it needs to do. First, the 6811 will save registers onto the stack (CCR, A, B, X, Y, PC). Then the PC will be set to a specific area of memory depending upon what interrupt occurred. For example, if the Main Timer had overflowed, the PC would now be set to $FFDE. Every different interrupt (there are 22 possible) would have the PC set to a unique place in memory. These memory locations are all in the range $FFD6 to $FFFE. Notice that this is the very top of the memory map. As a programmer, you must put a "vector" at the unique memory location for every interrupt you expect to encounter. Continuing with the timer overflow example, the programmer must put a "vector" at memory location $FFDE. The "vector" is to be used as the new PC value when the interrupt occurs. Since it is an address, a vector is necessarily two bytes long. So the Timer Overflow vector would take up the bytes $FFDE and $FFDF. The address placed here at the vector location will be the next address visited by the PC, so the programmer should put the address of the Interrupt Service Routine there. The programmer does not have to calculate where the ISR will start though, because the assembler can do this automatically. Below is a template of a main program, with an ISR for Main Timer Overflow and two vectors:

	
	ORG	$F800	  	*Start of main at start of EEPROM
Main:	EQU *		
	Code	Here 
End:		     		*Main is done here
Timer_ISR: 	EQU *	   	*Start of ISR
	Interrupt Service RoutineHere 		
	RTI			*return from interrupt
	ORG	$FFDE	
	FDB	Timer_ISR	*Vector 1
	ORG	$FFFE	
	FDB	Main		*Vector 2
Notice the assembler directives ORG, EQU, and FDB. These are not 6811 mnemonics. Rather they are instructions to the assembler. The ORG assembler directive instructs the loader that the code following must start at this memory address. The EQU is used to make a label associated with a memory location. So the line "Timer_ISR EQU *" associates the current address with the label "Timer_ISR". The programmer does not have to calculate how long Main is and figure out where in memory Timer_ISR starts, instead the assembler can keep track of this. Lastly the FDB assembler directive instructs the assembler to place the following Full Double Byte directly into the code. So FDB $Timer_ISR will place the double byte address of the start of Timer_ISR into memory right here at the ORG'ed location.

So the Interrupt signal occurred (a Main Timer Overflow) and the registers were saved to the stack, and the PC went to the location specified at memory location $FFDE (namely to Timer_ISR) Now the I bit in the CCR is set (to prevent further interrupts) and the 6811 begins executing instructions in the Timer_ISR routine. The programmer may want to keep a count of how many times the main timer overflowed, or to take samples of data on the ports, or do some other imaginative thing during the Timer_ISR. But at the end of the Timer_ISR, the RTI (return from interrupt) instruction must appear. This RTI will have the effect of causing the 6811 to restore all the registers (remember they were saved on the stack) This means that what ever the 6811 was doing before the ISR, it will start right where it left off, because the PC is one of the restored registers. The accumulators, index registers, CCR, PC and even the SP (think about it) are all just as they were before the Interrupt signal. So the 6811 will load the next instruction from Main (where the PC now points) and move happily along.

ieeecs@hal.elee.calpoly.edu
BackBack to Table of Contents