SUB irFrameTmr_LSB, #1
SUBB irFrameTmr_MSB, /C
The purpose of this code is to decrement irFrame Tmr
when it's greater than zero. Since irFrame Tmr is a
word (two bytes), the easiest way to check for zero (in
Assembly) is to OR the upper and lower bytes together. If
the result is zero, the JZ instruction will cause the code to
jump to FT_Exit. If irFrame Tmr is not zero, then it gets
decremented. We have to use two instructions to do this
because it's a two byte value.
To enable this timer for the SIRCS window, we set
it to 3600 as this is the number of 12. 5 microsecond
interrupt cycles in 45 milliseconds. This is done inside
TX_SIRCS20 using a constant called MS_450.
Once the frame timer is started, we create the start
pulse by activating the IR LED (anode high) and waiting
2.4 milliseconds; the DELAY_TIX subroutine takes care of
the timing in the foreground.
After the start pulse, we drop into a loop that will
transmit the 12-bit command code — LSB-first. The IR LED
is activated and then the proper delay is inserted: 1.2 milliseconds for a 1 bit or 0.6 milliseconds for a 0 bit. Per the
spec, there is a 0.6 millisecond
off-time between each bit. The
IR code is shifted right after
each bit to position the next. A
second loop is used to transmit
the eight-bit device code, again
LSB-first. In all, 20 bits have
Finally, we wait for the 45
millisecond timer to expire
before exiting. This allows the
TX_SIRCS20 routine to be
called successively without
violating the timing
requirements of the protocol.
You're probably wondering:
What happens when the
interrupt triggers in the middle
of TX_SIRCS20 — won't the
bank setting be thrown off?
Good question, and the
answer is no. At the start of
the interrupt, the SX automatically saves a few key registers
— one of them is the FSR (bank
pointer) — and this is restored
when the interrupt terminates.
others have written a boatload of material on LCD
interfacing in the pages of Nuts & Volts so I'm not going
to go into detail here except to say that I'm using a four-bit
interface to minimize I/O requirements (see Figure 3).
This means, though, that writing to the LCD requires two
nibble writes. This is handled by LCD_OUT which also
preserves the backlight control pin and the RS line
(command or character mode) of the LCD.
One of the choices I made was to forego reading the
LCD busy flag. This means that there is standardized
timing built into the write cycle and that I have to
remember to include a two millisecond or greater delay
after using the clear ($01) and home ($02) commands.
The initialization code disables window scrolling so the
home command should never be needed; remembering a
short delay after clearing the LCD won't be a problem
While I don't anticipate needing the backlight for
this project, I've added control from the port and a
manual switch — just in case I'm doing some late-night
ACCEPTING USER INPUT
My intervalometer has three modes: setup, run, and
manual. These modes can be handled with a three-position toggle switch and two I/O bits. For entering
information, I'm using the other six bits on the same port
Suffice it to say that I and
■ FIGURE 3. LCD interface.
March 2009 19