INTERRUPTS IN ASSEMBLY
Because accuracy is important in a real time clock
application, this is a great opportunity to introduce assembly language interrupts inserted into a Basic language
program. The problem with higher level languages is the
final assembly language code doesn’t easily clarify how
many internal clock cycles each high level instruction takes.
This program needs to respond quickly to the Timer 1 overflow so, in cases where you need to react quickly and know
exactly how many clock cycles occurs, assembly language
is the answer. The Microchip PICs make this even easier
because each assembly language command takes only one
internal clock cycle (except for branches and GOTOs).
To keep this clock accurate, I will use a small
section of assembly language inserted into a PICBasic
Pro program to handle the Timer1 overflow and interrupt.
This way, very few clock cycles are used to handle the
At this point, you might be thinking, I just learned how
to program PICs in Basic, why rush into learning assembly?
In my opinion, Basic better prepares you for assembly than
any other method. Basic allows you to get a program working inside a PIC along with learning how the programmer
works, how to wire the resonator or crystal, how to set up
the configuration, and how to establish
register and RAM (variables). It even
forces you to read the data sheets a little
bit. Writing assembly code after all that
is just learning a few new commands
that work on the bit level just like the
HIGH and LOW Basic commands do.
The software is written for PICBasic Pro. I wanted to
show how to mix assembly language and BASIC to achieve
an accurate real time clock. To get a quick response
to a Timer1 overflow, I chose to use assembly language
interrupts. This may seem a bit complex if you don’t know
assembly language, but it’s really not that difficult to understand. Let’s start at the beginning to explain this software.
I start by defining the fact I’m using a bootloader to
program the PIC and I’ll run that PIC at 20 MHz. Later on
we’ll set up the 32.768 kHz crystal running Timer1.
DEFINE LOADER_USED 1
DEFINE OSC 20
‘ Needed for bootloader redirect
‘ 20 MHz resonator
Next, all the DEFINES for the LCD are established. I’m
using PortB bits 4-7 for the data communication, bit 3 for
the E line, and bit 0 for the RS line. The R/W pin is just
grounded on the LCD for “write-only” operation. One of
the key setups here is the DEFINE LCD_DATAUS 100. I
found the default of 50 microseconds did not work well
with my LCD. I had to slow down the data transmission.
This is why I like to define all of the LCD setup rather than
rely on the defaults.
For this project, I’m going to drive a
2 x 16 LCD module to display the time
generated by the Timer1 overflow. The
software of the main loop will handle
converting the one-second overflow into
a meaningful clock display of hours :
minutes : seconds. The hardware
involved is not much different than my
original article that started this series
back in January. We do most of it in
The completed project is shown in
Figure 1. I built it on a breadboard again,
using one of my original prototype
Ultimate OEM modules, but a stand-alone PIC is a simple alternative. The
schematic in Figure 2 shows my setup.
The key component is the 32.768 kHz
crystal between the C0 and C1 pins of
the PIC. It also has two 22 pf capacitors
from the crystal leads to ground. The rest
of the circuit drives a 2 x 16 LCD. (I’ve
covered driving before.)
■ FIGURE 2
September 2006 91