You are on page 1of 5

GetStartedWithPICs.

qxd 5/9/2006 3:26 PM Page 82

■ BY CHUCK HELLEBUYCK
GETTING STARTED WITH
THE LATEST IN PROGRAMMING MICROCONTROLLERS
PICs
USING THE PIC
EXTERNAL INTERRUPT
LIFE CAN THROW YOU IN MANY DIRECTIONS and
how we deal with it builds our character. This
happened to me recently while trying to get this
article out for Nuts & Volts. ■ FIGURE 1

M y life was interrupted. My


father, who has been battling
cancer, lost his battle and passed
I continue to help others with this
column.
interrupt. For example, your main
program loop is running along
fine and then a switch is pressed
away. My whole world was rocked. by a user and you want the main
Loss of a loved one is never easy
PIC INTERRUPTS loop of code to respond to it. If you
and a parent is devastating. My The same way interrupts in life run a loop constantly checking a
father taught me the basics of can happen, external events you port for a state change (high-to-low
electricity and he taught me so don’t want to miss in your PIC or low-to-high), there is no guaran-
much more. It's in his honor that project can be caught using an tee that your main loop will be fast
enough to see the switch press
LISTING 1: PICBasic Pro Program. happen at exactly the same time the
main loop polls the I/O pin. This is
‘ External interrupt example where hardware interrupts take
‘ PortB pin 7 Turn LED on. over. They run in the background
‘ Interrupt on PORTB.0 (INTE) turns LED off. and will pause the main loop of
‘ Program waits .5 seconds and turns LED back on. code to run an interrupt routine that
you write as a separate block of
led var PORTB.7 ‘Establish name for portb.7 code.
The PIC has one main external
OPTION_REG = %00111111 ‘ Enable PORTB pullups, and interrupt and it’s on PortB bit 0 or
‘ falling edge on B0 interrupt port pin B0. You can set it up to inter-
rupt on the rising edge (low-to-high)
On Interrupt Goto myint ‘ Define interrupt handler
or falling edge (high-to-low) of the
INTCON = $90 ‘ Enable INTE interrupt
interrupting signal. Both PICBasic Pro
‘*** Main Loop ******
and the Atom have Basic commands
loop: that make this an easy event to
High led ‘ Turn LED on control. The program in Listing 1
Goto loop ‘ Do it forever shows a very simple application for
PICBasic Pro.
‘ ****** Interrupt handler ******* The schematic is shown in Figure
Disable ‘ No interrupts past this point 1. The program simply lights an LED
myint: connected to the B7 I/O pin.
Low led ‘ If we get here, turn LED off When a switch connected to
Pause 500 ‘ Wait .5 seconds the external interrupt pin B0 is
INTCON.1 = 0 ‘ Clear interrupt flag pressed, the program jumps to the
Resume ‘ Return to main program interrupt routine and shuts the B7
Enable LED off for a half second and then
82 June 2006
GetStartedWithPICs.qxd 5/9/2006 3:26 PM Page 83

G E T T I N G S TA R T E D W I T H P I C s

returns to the main loop of code that lights the LED once want the interrupt routine to be interrupted by
again. another button press while we are reacting to the
first one.
HOW IT WORKS ‘ ****** Interrupt handler *******
Disable ‘ No interrupts past this point
The program intially creates the constant “led” to myint:
simplify lighting the LED on B7.
The interrupt handler just pulls the B7 pin low to shut
led var PORTB.7 ‘Establish name for portb.7 off the LED and then pauses 500 milliseconds or a half
second.
Next comes the initialization of the registers. We
want to use the internal pull-up resistors built into the Low led ‘ If we get here, turn LED off
PIC PortB so we do that with a “0” at the most Pause 500 ‘ Wait .5 seconds
significant bit in the OPTION register. We also want
the external interrupt to happen when the switch on B0 Next, the program clears bit1 of the INTCON
is pulled to ground or on the falling edge. The second register. When the interrupt occurs, the PIC sets a bit (or
“0” does that. The rest of the setup establishes the flag) in the INTCON register. You would use this if
watchdog timer which has nothing to do with the more than one interrupt was being used on the PIC,
external interrupt. such as the timer interrupt we used in a previous
article. By checking the bits, we can determine in our
OPTION_REG = %00111111 ‘ Enable PORTB pullups and software what caused the interrupt. In this case we
‘ falling edge on B0 interrupt know, so we need to clear that flag before exiting the
interrupt routine. If we don’t clear it, PICBasic Pro will
PICBasic Pro takes care of most of the rest through jump us back into the interrupt routine as soon as we
Basic commands. The Basic command “ON INTERRUPT leave it.
GOTO label” tells the program where to jump to when the
external interrupt occurs. In this example, it jumps to the INTCON.1 = 0 ‘ Clear interrupt flag
label “myint.”
All interrupt routines have to end with the
On Interrupt Goto myint ‘ Define interrupt handler RESUME command. This clears the global interrupt bit
GIE in the INCON register and puts the program
The interrupts are shut off until the program enables counter back to the main loop where the program was
them by setting the proper bits in the interrupt control interrupted.
register “INTCON.” The most significant bit turns all
enabled interrupts on, but the only one enabled is the Resume ‘ Return to main program
“INTE” external interrupt bit, which is bit 4 in the INTCON
register. Finally, the ENABLE command re-establishes interrupts
beyond the interrupt routine.
INTCON = %10010000 ‘ Enable INTE interrupt
Enable
Now the program’s main loop of code
is run, which is just a loop that continually ■ FIGURE 2
sets the LED pin to high or on since the LED
is connected from the B7 pin to ground
through a resistor. This will continue until
the switch on B0 is pressed, causing the
interrupt.

‘*** Main Loop ******


loop:
High led ‘ Turn LED on
Goto loop ‘ Do it forever

When the interrupt occurs, the program


finishes the last Basic command and
then jumps to the “myint” label. Notice the
DISABLE command above the interrupt
handler. This prevents any interrupts from
happening for any code below it. We don’t
June 2006 83
GetStartedWithPICs.qxd 5/9/2006 3:26 PM Page 84

were pressed.
While all this is going on, the Atom
flashes a separate LED on C0 (Atom P8) in the
main loop to represent other functions that
can happen while waiting for the interrupt
to occur.

HARDWARE SETUP
The schematic shows the connections for
this project. The four switches are tied to P4
through P7 with a pull-up resistor to Vdd (five
volts). All the switches are connected to the
P0 external interrupt pins through the diodes.
The diodes have the anodes tied to the B0 pin
and the cathode connected to the switches.
This allows the B0 pin to see a low (0.7 V) sig-
nal when a switch is pressed. The LEDs that
indicate which switch was pressed are con-
nected to the C4 through C7 pins. The LED
connected to the C0 pin is the continuously-
flashing LED in the project picture. All this is
done easily with one of my Ultimate OEM
modules, but you can build it with a bare PIC
16F876A or Atom 28 pin Interpreter PIC
16F876A chip.

ATOM SOFTWARE
The software program (shown in Listing 2)
is really not that complex for something so
useful. This is considered an advanced topic
for the beginning Atom user, but you will see
■ FIGURE 3 that it’s not that difficult to understand. This
is because the Atom software makes using
interrupts very easy.
MULTIPLE INTERRUPTS WITH ATOM
This next example shows how easy it is to use the
external interrupt (EXTINT interrupt) in Atom Basic. This
HOW IT WORKS
example also shows a method many beginners would The program first establishes and sets up the external
not have thought of: use the external interrupt to interrupt and defines the label of where to go when the
capture more than one event by using it as a multiplexed external interrupt occurs.
interrupt. The setup is shown in Figure 2 and the
schematic is in Figure 3. This same setup can be used OnInterrupt ExtInt, ProgInt ‘ Setup the external interrupt
with PICBasic Pro, but you will see how the Atom
makes it even easier because we don’t have to set up all The external interrupt can happen when the P0 port
the registers. transitions from a low-to-high or high-to-low state. We
The hardware connections tie several switch inputs choose high-to-low with the SETEXTINT command and the
to the P0 pin through diodes, so different I/O pins can EXT_H2L option. This will make the interrupt happen when
activate the external interrupt. In fact, the project has we press the switch rather than when we let it go
four switches connected to the P4 through P7 pins, and (EXT_L2H).
all of them multiplex connected to the P0 pin through
diodes. When any of the switches are pressed, the setextint EXT_H2L ‘ Interrupt on High to Low signal
Atom program is interrupted from what it was doing and
reads the P4 to P7 ports to see which switch was Even though I show pull-up resistors on the
pressed. Then it lights LED(s) connected to PIC pins C4 schematic for the switches, I initially didn’t include one
through C7 (Atom P12 through P15) that line up with for the P0 pin, which was a mistake. It needs one to
the switch position(s) to show which switch or switches make sure the P0 pin is sitting at a known state, so I
84 June 2006
GetStartedWithPICs.qxd 5/11/2006 4:29 PM Page 85

G E T T I N G S TA R T E D W I T H P I C s

turned the internal pull-up resistors on


in the software, which is available for P0 LISTING 2: Atom Software Program.
through P7 only. I could have left off
OnInterrupt ExtInt, ProgInt ‘ Setup the external interrupt
the switch pull-ups after that, but they setextint EXT_H2L ‘ Interrupt on High to Low signal
there, so I left them in. It works either setpullups PU_ON ‘ Turn on the internal pull-ups
way, but this shows how to use the enable ExtInt ‘ Turn on the external interupt
SETPULLUPS command and also how time var byte ‘ Establish variable Time
to add additional current drive from an trisc = %00000000 ‘ Make port C all outputs (P8-P15)
external pull-up. portc = %11111111 ‘ P12-P15 LEDs off, P8 on

setpullups PU_ON ‘ Turn on the inter- ‘**** Main Loop of Code ******
‘ nal pull-ups Main
high 8 ‘ Green LED turned on
Now we turn the External Interrupt for time = 1 to 100 ‘ Start delay loop count
on with the ENABLE command and the pause 1 ‘ Delay 1 millisecond
next ‘ Next delay count
EXTINT option. This is the way the
low 8 ‘ Green LED off
Atom software controls the INTCON
for time = 1 to 100 ‘ Start delay loop count
register for you. pause 1 ‘ Delay 1 millisecond
next ‘ Next delay count
enable ExtInt ‘ Turn on the external interrupt
Goto Main ‘ Loop back to main label
We establish a variable “time” to use
in a For-Next loop to flash the LED on C0 disable ‘ disable all interrupts from here down
(Atom P8).
‘**** Interrupt Routine ******
time var byte ‘ Establish variable Time ProgInt ‘ Interrupt routine label
portc.highnib = portb.highnib ‘ Make LEDs match switches
I write to the port registers directly
(TRISC and PORTC) to set up the P8, hold ‘ label for below
P12 through P15 ports. This is the same, if portb.highnib < %1111 then hold ‘ Wait for switches to be released
easy way you would do it if you were Resume ‘ This is how to exit interrupt
programming the PIC in PICBasic Pro.
This shows how the Atom gives you full control of the command it is working on before jumping to the interrupt
Microchip PIC 16F876A and how, once you learn one service routine. If I just used PAUSE 100 as the 100
compiler, you can easily learn another. millisecond delay, then the interrupt could occur when the
command started and the interrupt routine would not get
trisc = %00000000 ‘ Make port C all outputs (P8-P15) processed until 100 milliseconds later. By then, the switch
portc = %11111111 ‘ P12-P15 LEDs off, P8 on could have been released and the software would not
know which switch was pressed. This is why the delay is
broken into several commands that take very little time to
The main loop of code starts with the “main” label.
execute.
You can call it what you want, but this makes it easier for
The interrupt routine is very short, but I do something
me to understand when I look at my code many months
not normally done in an interrupt routine — I force it to
later. The main loop just flashes the green LED on port
stay there until the switch is released. First, the DISABLE
P8 on and off at a 100 millisecond rate. The reason it
command is issued to indicate all the commands below it
looks so long is because I break up the 100
cannot be interrupted.
millisecond delay into a FOR-NEXT loop with a one
millisecond delay repeated 100 times. I do this because disable ‘ disable all interrupts from here down
of the interrupt.
Main The interrupt service routine starts at label “ProgInt.”
high 8 ‘ Green LED turned on The first command looks complex, but is very simple. I
for time = 1 to 100 ‘ Start delay loop count
pause 1 ‘ Delay 1 millisecond
use the Atom option of reading and writing to the
next ‘ Next delay count registers directly. I read the switches P4 through P7,
low 8 ‘ Green LED off which form the bits of register PortB’s high nibble
for time = 1 to 100 ‘ Start delay loop count (upper four bits). Using the equal sign, I make P12
pause 1 ‘ Delay 1 millisecond
through P15, which form the PortC high nibble — the
next ‘ Next delay count
Goto Main ‘ Loop back to main label same state as the bits of PortB. Thus, I’m making the
LEDs match the state of the switches. Those that
When an interrupt occurs, the Atom will finish the are pressed (low) light the LEDs on P12 through P15.
June 2006 85
GetStartedWithPICs.qxd 5/11/2006 4:30 PM Page 86

Those that are not pressed (high) turn off those LEDs on gram jumps back to the main loop where it was interrupted.
P12 through P15. And I did all that in one command.
Easy, huh? hold ‘ label for below
if portb.highnib < %1111 then hold ‘ Wait for switches to
‘ be released
ProgInt ‘ Interrupt routine label
portc.highnib = portb.highnib ‘ Make LEDs match switches Resume ‘ This is how to exit
‘ interrupt
Now I test the PortB high nibble to see if any of the bits
are “0” indicating a switch is being held closed. I do this in
a continuous loop by jumping back to the hold label until all
NEXT STEPS
the switches are released. When the switches are all One thing you can try is to replace the main loop of
released, the RESUME command is executed and the pro- code with something more interesting than flashing an
LED. For example, you could add
software to drive an LCD display that
Atmel AVR based Micro64/128 shows how many times the switch
was pressed. That can be expanded
Embedded Controller Module on to do all kinds of things.
The switches can be replaced
8-Channel Analog to Digital Convertor with light sensors that detect when
Real Time Clock/Calender someone walks by. This way you are
29 Digital I/O creating a people counter with the
SPI & I2C Bus total count shown on the LCD screen.
Do you see how various sections from
Two Serial Ports previous articles can be combined
Serial Boot Loader together?
RS-232, 422 or 485
Selectable Baud CONCLUSION
Rates up to 250 Kbps I hope this introduction to inter-
Only 1.5 Cubic Inches rupts in Basic isn’t too brief. Over
Supports Assembly, Starting at Only time, you will find interrupts to be
BASIC and C Prog. Languages extremely useful. PICBasic Pro will
Inexpensive CodeVision C Compiler $119 - Single Qty actually allow you to use interrupts in
assembly so you don’t have to wait for
the Basic command to complete. This
is far more complicated and, in most
Start Developing cases, not needed. Atom Basic does
The Micro6/128 Development allow you to ignore the PIC register
Board takes the Micro64/128 I/O setup and has you read the PIC
pins and expands them out to 16F876A data sheets for register
solder pads and headers for ease details. This is why I call Atom the
of connection when developing. perfect beginner PIC compiler.
It also connects USART1 to RS-232 PICBasic Pro costs more and will work
drivers or directly to screw with many more PICs, but it’s also a
terminals for RS-422 or RS-485 professional compiler so it prepares
communication. USART0 is also you for programming in assembly
connected to RS-232 drivers. The much better than Atom. In either
RS-232 drivers are connected to case, having the ability to access the
two DB9 connectors. This board PIC features such as interrupts is
includes a prototyping area so the user can add external something other Basic-style modules
circuitry. There is an onboard voltage regulator for powering the won’t allow. This is why I like these
Micro64/128 and additional circuitry. The Micro64/64A/128/128A compilers. They get the beginner and
development system comes complete with a Micro64, Micro64A, even the intermediate user up to
Micro128 or Micro128A, a Micro64/128 Development Board, and a speed on what PICs can do.
power supply. As usual, email me if you have any
VISIT WWW.MICROMINT.COM FOR MORE questions or comments. I try to
answer everything as quickly as possi-
INFORMATION or Call 1-800-635-3355 ble. See you next month. NV
86 June 2006

You might also like