Issue
145 August 2002
Driving
the NKK Smartswitch
Part
2: Graphics and Text
GRAPHIC
GENERATION
It’s
possible to create a graphic image to cover the full
24 × 36 pixels of the display. As with characters, the
image is broken into a bit pattern for every row of
the graphic image.
Rather
than use large blocks of program memory, I restricted
the graphics size to a maximum of 16 × 16. This requires
32 bytes per image. I also tacked on 2 bytes to describe
the width and height of the image (in pixels), which
would work out to 34 bytes. In addition, I limited this
to five images because I am not great at graphics (so
far I have only managed a fair representation of a maple
leaf). The image is included in LCDmem.c as image zero.
The generation of images one to four is left to your
"image-ination."
The
image should be left and top justified within the 16
× 16 matrix so that the first bit of the image is at
pictures[x], iBitPattern[0] bit 15. Creation of an image
is a lot of work, so once again I resorted to Excel.
I used an extended version of the Excel workbook described
earlier. You can also download this file from the Circuit
Cellar web site.
It’s
possible to expand the size of these images by modifying
the program in a few areas. The images are contained
in a structure called pictures, defined in LCDmem.c
and repeated as a header in LCDmem.h. iBitPattern would
have to be re-declared as an unsigned long type to cater
to the increased number of horizontal pixels and the
number of rows would have to be incremented from 16
in the iBitPattern[16] declaration.
In
addition, the procedure Load-Graphic in the Command.c
module would need to have the iMask modified to a long
unsigned type and its initialization (iMask = 0x8000;)
changed to suit the larger image. You can also increase
the number of images by changing the array declaration
pictures[5] in LCDmem.c and LCDmem.h, and by adding
in the values for the graphics in the constant array.
THE
USER INTERFACE
Before
I bore you to tears with a description of the software
operation, I want to demonstrate how the user interface
works. You can download the command sequences and photos
showing the results of the commands from the Circuit
Cellar web site.
As
you can see, Photo 1 is a mixture of graphics symbols,
bit manipulation, and text entry. For all of the command
sequences presented, I’ve ignored stating that the interface
must poll cCMDs[0] and wait until bit 0 is zero. I have
also omitted stating that setting bit 0 of cCMDs[0]
to one should happen after all of the other bytes have
been set up in order to initiate the action.
|

(Click
here to enlarge)
|
Photo
1—This flag is actually created in four steps. First,
a large block is written across the screen. Second,
a gap is opened up in the middle of the block, creating
the effect of the sidebars. Third, the maple leaf
is inserted into the gap. Finally, the text is written
in the bottom line. |
SOFTWARE
OPERATION
The
code for the previously described functions is contained
in the module Command.c. The decoding for the commands
occurs in the procedure ProcessCommand(), which is a
simple C language switch construction.
The
heart of all these functions is locating the bit in
RAM where the function will start being implemented.
This procedure is GenPixel, which takes the pixel number
as an integer parameter and generates a value for three
variables: cPixRow, cPixColByte, and cPixColMask. These
are then used to address a byte in RAM as cMatrix [cPixRow][cPixColByte]
and the particular bit is contained on cPixColMask (see
Listing 1).
| Listing
1—GenPixel identifies the byte and bit associated
with a particular pixel through a composite pointer
using cPixRow, cPixColByte, and cPixColMask. |
Rather
than deal with each item in a given row, the items are
handled individually, row by row. For instance, a letter
will be copied from the character generator table to
RAM before the next character is analyzed.
Another
interesting procedure is IncPixPnt, which will increment
the pixel being dealt with along a line, changing the
cPixColMask and cPixColByte when necessary (see Listing
2). Each time a new row is started, the pixel pointer
is set 40 pixels ahead of the pointer to the beginning
of the current line. No attempt has been made to check
for pixels beyond the limits of the RAM matrix. Remember
that the leftmost pixel has a numeric value greater
than the pixels to the right of it on the same line.
| Listing
2—IncPixPnt increments the compound pointer
to point to the bit associated with the next pixel
on the right. |