[Return to Home Page]

ECE 445 Wiki : Topics : PICCCSCInterrupts

[Login]


PIC CCS C Interrupts HOW-TO

Introduction

If you’re reading this we’ll assume you are either researching microcontroller interrupts in an effort to decide between polling or interrupt driven routines, or you have decided to use interrupts and are learning the ropes. The hope is that I can communicate what I’ve learned about interrupts and show you just how easy they can be with the CCS C compiler.

Necessary Elements

First we consider the necessary elements to handle interrupts. You will need to enable the interrupts in your program with the function ‘enable_interrupts(level)’. This is done on 2 levels. First is the ‘global’ level, think of this as the main power switch for your interrupts without which no single interrupt can operate. The second level is the individual interrupt and follows the form ‘int_xxxx’. Continuing with the power switch analogy, you can think of each of the individual interrupts as toggle switches that set the state of the program. Note that you can also disable interrupts in your program if you need to execute code uninterrupted you do this with the function ‘disable_interrupts(level)’; disabling at the ‘global’ level leaves the individual interrupts active. Now we need to learn how to define the interrupt service routine, or ISR. With the CCS C compiler this is really simple, you use the pre-processor command ‘#int_xxxx’, where ‘int_xxxx’ is the individual interrupt you are using, followed by the interrupt handler function. This is the beauty of the compiler, you don’t need to save and restore the machine state, clear flags, or any of the other things you might do in ASM. So that rounds out all the required elements for interrupts. Let’s take a look at a simple example of an external interrupt signal.

Code Example

Say I have a button that I want to press and have the PIC blink an LED until the button is pressed again. This can be done very simply with an interrupt. For our purposes I’ll be using the PIC16F877 microcontroller. Below is a program that executes this:

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

BYTE blink = 0;

#int_rb
void button_isr() {
	delay_ms (20);  //debounce
	if( !input(PIN_B4) && !blink )
		blink = 1;
	else
		if( !input(PIN_B4) && blink )
			blink = 0;
}

void main() {
	enable_interrupts(global);
	enable_interrupts(int_rb);

	ext_int_edge( H_TO_L );

	do {
		if(blink){
			output_high(PIN_D1);
			delay_ms(500);
			output_low(PIN_D1);
			delay_ms(500);
		}
	} while (TRUE);
}

Let’s look briefly at what the program does:

#int_rb
void button_isr() {
	delay_ms (20);  //debounce
	if( !input(PIN_B4) && !blink )
		blink = 1;
	else
		if( !input(PIN_B4) && blink )
			blink = 0;
}

Here we have the interrupt function, we wait 20ms to let the button state settle before it is read, this is just a quick and dirty way to debounce the button and keep this example simple for better practice consider setting a timer instead. Remember that since the button bounces you will have to handle cases where an interrupt was generated because the button was pressed and because it was released. This ‘if else’ statement handles that.

void main() {
	enable_interrupts(global);
	enable_interrupts(int_rb);

	ext_int_edge( H_TO_L );

	do {
		if(blink){
			output_high(PIN_D1);
			delay_ms(500);
			output_low(PIN_D1);
			delay_ms(500);
		}
	} while (TRUE);
}

Here we have enabled interrupts on both levels, and then we set the external interrupt to be generated on a High to Low transition with ‘ext_int_edge( H_TO_L)’. After that we just simply alternate between high and low outputs on the pin the LED is connected too.

int_rb Note

So there you have it, wire it up and give it a shot.

To get a list of the interrupts available to your PIC look in the .h file. If you haven’t already, you will find the ‘Ccsc.chm’ compiled HTML help file very useful.

PmWiki can't process your request

Cannot acquire lockfile

We are sorry for any inconvenience.