You are on page 1of 13

Harris Semiconductor

No. AN9702

February 1997

Harris Digital
Author: Christopher Mazzanti

Keypad Scan and LCD Interface for the CDP68HC05


Introduction
This application note details input/output interfaces to a Harris CDP68HC05 microcontroller. Being able to easily display text information to human operators and prompt for data input from a keypad is a very important part of what makes low cost 8-bit microcontrollers attractive. The LCD interface detailed within this application note is not directly to an LCD but rather to LCD modules with the Hitachi HD44780 LCD chipset, such as the Optrex 16202. The keypad scan interface uses the IRQ/Pull up mask options available on all B versions of Harris CDP68HC05 microcontrollers (i.e., CDP68HC05C8B). The pullup device and the interrupt function are disabled when the associated DDRB bit is set high. When its DDRB bit is a 1, each port B pin acts as a normal output regardless of whether or not the pullup/interrupt mask option has been selected. Thus the DDRB bit can be used as an interrupt enable for the interruptible port B pins. Care should be taken when re-enabling a port B interrupt to avoid false interrupts. False interrupts can be avoided by rst driving the PORTB bit high before clearing the DDRB bit. Further note that all DDRB bits are cleared by reset, thus enabling port B interrupts (no interrupt will be recognized until execution of the rst CLI instruction following reset).
VDD VDD MASK OPTION P PBn DDRB BIT n

Operation
This section is divided into two sections: Keypad Scan and LCD Interface. Each of these sections gives an overview of the operation of the hardware and software associated with each type of interface. KEYPAD SCAN INTERFACE The keypad scan interface described in this application note uses the Port B interrupt/pull-up mask option of the CDP68HC05C16B. Before an explanation of the keypad scanning routine, a brief description of these options is detailed. Port B Interrupts and Pullups Note: The Port B interrupts and pull ups described here are in terms of the CDP68HC05C4B, C8B and C16B. Port A interrupts and pull ups on the CDP68HC05J4B function similarly except where noted. In addition to being a standard bidirectional port, each bit of Port B has a mask option to connect a pullup device to the I/O pad and to simultaneously feed the input to the internal interrupt logic. When the mask option is not selected, each Port B pin behaves as a standard bidirectional port pin. When the mask option is selected, a pullup PMOS device with an impedance of approximately 20k is connected between the pad and VDD (see Figure 1B for Pullup Current IIN) and the input signal is inverted and internally ORed with the IRQ signal (refer to Figure 1A). The interrupt behavior of any port B pin which has the pullup/interrupt mask option activated is identical to the results one would achieve by externally ORing (active low) the signal with the IRQ signal.
Copyright

PORT CIRCUITRY TO INTERNAL INTERRUPT IRQ

OTHER PORT B INPUTS

FIGURE 1A. PORT B INTERRUPT AND PULLUP MASK OPTION


300 250 200 150 100 50

IIN , P-CHANNEL PULL UP DEVICE CURRENT (A)

1.0

2.0

3.0

4.0

5.0

6.0

VPD , PULL DOWN VOLTAGE (V)

FIGURE 1B. C4B, C8B, C16B P-FET PULL UP DEVICE CHARACTERIZATION CURVE

Harris Corporation 1997 1

Application Note 9702


Keypad Scanning The keypad scan routine detailed here is for a 16 key, 4 row by 4 column matrix keypad. Four of the keypad I/O port lines must be on a I/O port with the IRQ/Pull-up mask option set. These lines will detect a key press by causing an external hardware interrupt to be issued whenever any key is pressed. The other four port I/O lines connected to the keypad can be from any general purpose output port. Also, it is assumed that the IRQ edge/level option is set to edge only. The basic operation for scanning a keypad is quite simple. Four lines from the microcontroller connect to the row lines of the keypad. These are output lines that the MCU will strobe to determine which key is being pressed. The other four lines are connected to the column lines of the keypad and go straight to the IRQ/Pull-up I/O port lines of the MCU (Port B for the CDP68HC05C4B/C8B/C16B and Port A for the CDP68HC05J4B). These lines will always be in the input mode when scanning the keypad (See Figure 2). When waiting for a keypress, all four row lines (i.e., the output lines) will be driven low. The column lines (input lines) will be pulled up through their individual on-chip pull-up resistors. Whenever any key is pressed, the associated column line is pulled low (since it is now connected to a row line), causing a hardware interrupt to be issued. It is the responsibility of the IRQ service routine to determine if a key is being pressed and if so, to debounce it and gure out which one. While waiting for a key press, the 68HC05 will most likely have other things to do. To allow the MCU to go about its processing, all Harris 68HC05xxxB version microcontrollers have mask options that can make each one of the lines on a specic I/O port act like the IRQ pin when that particular line is pulled low in input mode. Thus, whenever one of these lines is pulled low, a hardware interrupt is issued. Internal active CMOS pull-up resistors are connected to the port so that the inputs are not oating when not connected to anything, causing inadvertent interrupts. Since all four row lines are driven low while waiting, any keypress will pull at least one line low, causing an IRQ interrupt. Without this port interrupt ability, the MCU would have to continuously scan the keypad to detect a keypress. This is the advantage of having the IRQ/Pull-up mask option enabled.
1 ROW LINES TO MCU OUTPUT 2 3 4 1 2 3 4

Port B pull-ups. Once the source of the IRQ has been determined to be a keypress, the next thing to do is to debounce it. This needs to be done because switch bounce (caused by the switch contacts closing, separating and the closing again) can cause the 68HC05 to read the switch during a bounce and incorrectly assume that no key is being pressed. To avoid this we use a 5ms timing delay loop. This delay gives the contacts plenty of time to bounce and settle into position. Now that the keypress has been detected and debounced, the interrupt routine must now gure out which key is being pressed. To do this we read in the column bits and test them sequentially to determine in which column a key is being pressed in. If two keys are being pressed simultaneously, this scan routine will detect the one in the column scanned rst. Once it has been determined which column the key is in, the service routine must now determine which row in that column the key is in, thus giving us the key location. At this point we write 1s to all of the row locations except for the rst one (i.e., row 1 in this case). We then test the column bit where we determined previously that the key being pressed was in. If this line is low, then we have found the key. If not, then we write 1s to all of the row lines except for row 2 and test the column again. In this way we can scan through the keypad and determine the exact location of the keypress. Running at 4MHz, the 68HC05 can scan the keypad much faster than a human can press a key and release it (even with the 5ms debounce delay). If the routine determines that no key is pressed, then it simply returns from the interrupt and continues from where it left off. The IRQ service routine in the assembly listing later in the document details the entire keypad scanning process. LCD INTERFACE Strictly speaking, the interface described here does not connect a 68HC05 with an LCD. To do so would require special control circuitry in the 68HC05 itself and many more I/O lines than are available even with the 40 pin CDP68HC05C16B. Rather, this interface is to the Hitachi LCD driver/display control chip set specically designed for controlling text LCD displays. These chips have become very standard in their interface and are used by many LCD module manufacturers such as Optrex. The LCD unit used for this application note is an Optrex DMC16202. This is a 16 character by 2 line display, although larger displays (in terms of character length and line count) work similarly. The standard LCD interface (as the Hitachi-interface will be referred to from now on) will need a maximum of 14 lines connected to the LCD module - 8 data, 3 control, 2 power and 1 contrast (see the LCD technical information for details on power supply and contrast connections) of which anywhere from 6 to 11 lines will need to be connected to the MCU. Data can be transferred to the LCD in either byte-wide transfers or nibble-wide transfers, but since all text to be displayed on the LCD is encoded in an 8-bit ASCII-like format, choosing four bit operation means that two transfer operations will be needed for every character sent to the LCD. 8bit transfers require more I/O port lines, but they do speed up LCD transfers and make the software interface a bit more

COLUMN LINES - TO MCU INPUT

FIGURE 2. 4x4 MATRIX KEYPAD

The IRQ service routine is where all of the keypad scanning, debouncing and key identication takes place. In the IRQ service routine, the rst thing that has to be done is to determine the source of the IRQ. If the user code is using the IRQ pin of the MCU to connect to another peripheral (a Harris 65C51 UART for example), the IRQ service routien must determine if the interrupt came from the IRQ pin or from the

Application Note 9702


simple. This application note contains a code to run the LCD in either 8-bit or 4-bit mode, depending upon assembler directives. Diagrams for the two types of LCD interface along with the keypad connections are shown below in Figures 3A and 3B. Both of these connections and the code associated with them read from the LCD and poll the LCD busy ag instead of using timing delays. Note that the four bit interface transfers data on the low nibble of the port, although the software could just as easily be changed to transfer on the high nibble of the port. When writing data to the LCD module, there are two types of transfers that can occur - a control write or a data write. Control writes are data sent to the LCD for conguration purposes such as setting the DDRAM address pointer (more about the DDRAM in the next paragraph), data interface length, and cursor display for example (a complete list of all of the control codes for the LCD is listed below). The RS control line to the LCD needs to be low for control code writes to the LCD. If the RS line is high, writes to the LCD are written to the DDRAM. Data written to the LCD module for display is written to RAM locations in the Hitachi interface chips and is echoed to the display. This RAM is known as Data Display RAM (DDRAM). Every display location on the LCD has an associated DDRAM location with it; there are even DDRAM locations that exist that are not displayed. The DDRAM has an internal address pointer so that data byte writes to the LCD will go to a specic location. This address pointer can be set up to increment or not to increment when data is written to the DDRAM. The address pointer can also be set directly by a control write. DDRAM display locations along with a table of all of the control codes for the LCD module are shown below in Figure 6 and Table 2, respectively. The E control line of the LCD module is used as the data strobe of the module. This is an active high pulse used to latch the data being written into the LCD or to signal the MCU that the data being read from the LCD is ready. Timing diagrams for write and read operations are shown in Figure 4 below.

PORT I/O 4 PORT B [7:4] PORT B [3:0] 4 68HC05C8B NOTE: IRQ/PULL-UP OPTION ON PORT B [7:4]

LCD RS E R/W

KEYPAD

ROW COLUMN

DATA [7:4] DATA [3:0]

FIGURE 3A. 8-BIT LCD INTERFACE WITH KEYPAD

68HC05J4B PORT I/O 4 PORT A [3:0]

LCD RS E R/W

KEYPAD ROW COLUMN

DATA [7:4]

4 PORT C [3:0] NOTE: IRQ/PULL-UP OPTION ON PORT A [3:0]

FIGURE 3B. 4-BIT LCD INTERFACE WITH KEYPAD


DISPLAY POSITION 8 9 10 11 12 07 47 08 48 09 49 0A 4A 0B 4B

1 LINE 1 LINE 2 00 40

2 01 41

3 02 42

4 03 43

5 04 44

6 05 45

7 06 46

13 0C 4C

14 0D 4D

15 0E 4E

16 0F 10 4F 50 11 51 ... ... DDRAM ADDRESSES (HEX)

UNSHIFTED 16 CHARACTER DISPLAY AREA

UPPER DDRAM ADDRESSES

FIGURE 4. DDRAM ADDRESSES AND LCD DISPLAY POSITION

Application Note 9702

RS tAS R/W PWEH E tER tEF tDSW DB0 ~ DB7 VALID DATA tCYCE tH tAH tAH

RS tAS R/W tAH

tER

PWEH

tAH

E tDDR DB0 ~ DB7

tEF tDHR VALID DATA tCYCE

FIGURE 5A. WRITE OPERATION TABLE 1. TIMING CHART ITEM Enable Cycle Time Enable Pulse Width, High Level Enable Rise and Decay Time Address Setup Time, RS, R/W-E Data Delay Time Data Setup Time Data Hold Time (Write Operation) Data Hold Time (Read Operation) Address Hold Time SYMBOL TCYCE PWEH tEr, tEf tAS tDDR tDSW tH tDHR tAH

FIGURE 5B. READ OPERATION

MEASURING CONDITION Write, Read Write, Read Write, Read Write, Read Read Write Write Read Write, Read

MIN 1000 450 140 195 10 20 10

TYP -

MAX 25 320 -

UNIT ns ns ns ns ns ns ns ns ns

The LCD interface contains a read/write control line that can allow the MCU to read data from the LCD module. Since the characters being displayed each have their own address location within the LCDs display RAM, they can be addressed and read just like any other peripheral RAM. Chances are that most applications will not need to do this. However, being able to read the LCD means that the LCD subroutines can check the status of the LCD busy ag. Each operation the LCD performs takes a certain amount of time to complete. Most of these times are around to 40s range, although some operations can take as long as 1.64ms to complete. With a MCU running at 4MHz, this can be quite a long time. During one of the operations, the LCD ignores all data transmissions until it is done. To avoid sending the LCD data that will be ignored, the MCU must either poll the busy ag by reading a control byte from the LCD or sit in delay loops until the LCD has completed its operation. The second alternative saves an I/O line (the LCD read/write bit would simply be tied low) but does require extra timing loops in the source program that may be unnecessary. Another drawback to using timing loops is that for every write to the LCD, at least 40s of MCU time will be wasted, most of it in unproductive delay loops. If the busy ag is only polled at the beginning of a write sequence, so if the MCU was doing other things between writes to the LCD (as would probably be the case), chances are that the LCD will almost always have time to complete a write cycle. If the LCD is busy when a write starts, then and only then will the 68HC05 wait for the LCD to complete its operation. If the operation is a clear display (or similar) that takes 1.64ms to complete, even more MCU time is wasted if timing loops are

used. Also, there is still the risk that the LCD is not nished with an operation even though the timing loop is nished. Reading the LCD has the drawback of the added I/O line and code complexity, but is assures that the LCD is done with previous operations before being written to. As long as I/O port constraints and code size permit it, we recommend polling the busy ag over timing loops.
7 4 1 0 8 5 2 9 6 3 C /

* +

FIGURE 6. ASCII KEYPAD ASSIGNMENT

Software The software routines written for this application note include all of those needed to interface a 4x4 matrix keypad and a 16x2 Optrex LCD display. Included in the assembly listing are all of the subroutines necessary to read data from the LCD, write data to the LCD and scan the keypad. Also included are some higher level subroutines (i.e., they call the LCD read/write routine WLCD and RLCD) to make string display a little easier. The basic function of the main program listed here is to wait for a keypress and display the key that was pressed. The LCD will be cleared and the cursor set to the home position when the C key is hit. Each of the 16 keys on the keypad have been assigned an ASCII value in a setup similar to a calculator keypad (Figure 6). All of the keypad scanning is done in the IRQ interrupt service routine.

Application Note 9702


TABLE 2. LCD COMMAND CODE CHART CODE INSTRUCTION Clear Display RS 0 R/W 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 0 DB1 DB0 0 1 DESCRIPTION Clears the display and returns cursor to home position. Returns cursor to home position. Also returns the display being shifted. Sets cursor increment (I/D) and display shift (S). Sets Display On/Off (D), cursor On/Off (C), Blink Cursor (B) Sets display/cursor shift (S/C) and direction of shift (R/L) Set interface length (DL), number of lines (N) and character font (F) Sets the Character Generator RAM address Sets the Data Display RAM address EXECUTION TIME (MAX) 1.64ms

Cursor at Home

1.64ms

Entry Mode Set

I/D

40s

Display On/Off

40s

Cursor/Display Shift Function Set

S/C

R/L

40s

DL

40s

CGRAM address set DDRAM address set Busy Flag/ Address Read CG/DDRAM Data Write CG/DDRAM Data Read

CGRAM Address

40s

DDRAM Address

40s

BF

Address Counter (Both DDRAM and CGRAM) Reads the Busy Flag (BF) and address counter contents. Write Data Writes data into DDRAM or CGRAM

40s

40s

Read Data

Reads data from DDRAM or CGRAM

40s

I/D: 0 = increment, 1 = decrement S: 0 = no shift, 1 = shift display S/C: Display Shift, 1 = Cursor Shift

R/L: 0 = Shift Left, 1= Shift Right DL: 0 = 4-bit, 1 = 8-bit N: 0 = 1 line, 1 = 2 lines

F: 0 = 5x7 dots, 1 = 5x10 dots BF: 0 = LCD ready, 1 = LCD Busy x = dont care

irqIsr - this is the IRQ interrupt service routine and where all of the keypad scanning and key identication takes place. The rst thing that is done here is a delay subroutine called debounce is called. The purpose of this routine is to give the switch contacts enough time to settle so that reads of the keypad wont produce erroneous results. This delay here is set for approximately 5ms (at 4MHz) but can easily be shorted or lengthened to suit different applications. Next, the columns of the keypad are scanned to see in which column the key being pressed is in. Note that this routine relays heavily on the keypad constants dened at the beginning of the assembly listing. Col is dened as the I/O port to which the keypad columns are connected. Likewise, row is the port to which the keypad row lines are connected. row1, row2, col1, etc., are the bits within the row and col ports that those respective keypad lines are connected to. In this way the keypad columns and rows can be moved to different port locations without changing the assembly code. Once the column that the key being pressed is in is identied, its value minus 1 (i.e., column 1 = 0) is stored in the RAM variable colID. Next the rows are scanned.

This is done in a loop where each row line is individually driven low while the others are high and the columns checked for a keypress. When the row that the key is in is identied, its row location is stored in rowID the same way as the column number was stored in colID. Now that the row and column of the key are known, colID and rowID are put together (rowID:colID) to form a unique four bit ID of the key that was pressed (This method can be used to scan keypads up to 16x16). This ID number is then used as an offset into a table (keyTable). The table here simply contains the ASCII values of the keys for display on the LCD. This ASCII value for the key that was pressed is stored in the RAM variable keyData for return to the main routine. The keyFlag variable also has its bit 0 set to indicate to the main program that a keypress has occurred. Before the RTI is issued, this particular routine waits until the key is released. This is done because the key being pressed could interfere with accesses to the LCD and cause false interrupts to be issued. If the keypad does not share I/O ports with another peripheral, this part of the routine can be removed.

Application Note 9702


hex2asc - This is a simple but useful little subroutine for converting hexadecimal nibbles into ASCII bytes. For any hex number sent to this routine in the low nibble of ACCA, its ASCII value will be returned. txlcd1 - This is one of a pair of text string display routines written for the LCD interface. This routine uses a constant dened in the assembler as mesPage and a variable in IX as a pointer to the beginning of the message. The disadvantage to this is that ALL of the text messages must reside in the same 256 byte page (i.e., $09xx). The advantage of this routine is that it is smaller than txlcd2, it requires only one parameter to be setup prior to being called (IX) and it only uses 1 byte of RAM (no RAM is used except for that used in wclcd and wdlcd if the contents of ACCA are not preserved). The format for the message is <control byte, message, $00>. The control byte is used for positioning the LCD cursor before the write (i.e., $80 would send the cursor to position 0, line 1). The message part is simply ASCII text. The $00 at the end is essential because this is how the routine knows the message is nished. txlcd2 - This is the other text string display routine developed for the LCD interface. This routine is more complex and uses 4 bytes of RAM but it does have the advantage that the LCD message can be anywhere in memory. The location of the message is passed to the subroutine in ACCA and IX in the form ACCA:IX. In the subroutine, another subroutine is set up in RAM and it is this routine that is used to get the bytes of the message. If this routine is used, it is important that a $C6 is stored to ramSub1 and a $81 is stored to ramSub4. These are the LDA (extended) and RTS opcodes for the RAM subroutine. If the user program does not wish to load both ACCA and IX (IX may be being used as a counter) then the message address can be stored directly in ramSub2:ramSub3 before calling the program. In this case the rst two lines of the subroutine could be deleted. wclcd - This is the subroutine called for writing a control byte, contained in ACCA, to the LCD. The meat of this subroutine, like that of wdlcd, is the routine wlcd. The wclcd part simply sets the RS control line of the LCD low, indicating a control write. wdlcd - Same as wclcd except that the RS control line of the LCD is set high indicating a data write to the LCD. wlcd - This is one of the two main LCD interface subroutines. This routine takes a byte passed to it in the accumulator and writes it to the LCD. It is important to remember that the RS control line is not affected by this subroutine, so writes to the LCD will almost always call either wclcd or wdlcd instead. This routine requires several RAM bytes to properly preserve the state of the LCD data port upon exit (this is important when using the port i/o for both LCD and keypad interface). If the state of the LCD data port is not important in that only the LCD is connected to these lines, the RAM variables lcdTemp5 and lcdTemp6 can be removed from this routine. The rst thing that happens when wlcd is called is that the state of the RS bit is preserved. This is important because when the subroutine rclcd is called to check the LCD busy ag, the RS bit will return clear. Wlcd will loop innitely until the ag is clear. When the ag is clear, the RS bit is restored and the E strobe is lowered. The byte sent to the routine is loaded and, if the 4bit assemble option, the byte is shifted right four times, added to the previous port data and written to the LCD output. If the 4bit option is not set, the entire byte is simple written to the LCD port. After the write, the E strobe is pulled high followed by two NOPs for timing (this gives a 2ms pulse width at 4MHz. More may be needed at higher frequencies), after which time the E strobe is lowered. At this point the 8-bit interface is done, but the 4-bit interface still has to write the lower nibble of the data byte to the LCD port and strobe the LCD again. rclcd - This is the subroutine called for reading a control byte from the LCD and returned to the calling program in ACCA. The meat of this subroutine, like that of rdlcd, is the routine rlcd. The rclcd part simply sets the RS control line of the LCD low, indicating a control read. rdlcd - Same as rclcd except that the RS control line of the LCD is set high indicating a data read from the LCD. rlcd - this subroutine is a second of the two major LCD interface subroutines. Like wlcd, this routine has the 4bit assembler option for a 4-bit/8-bit LCD interface. lcdini - this subroutine is an important one to call before any of the other LCD interface routines are called. When the LCD module powers up, its default state is usually not what is desired. In this routine the data interface length is set along with the cursor type and increment, the display is then turned on and cleared. If these operations are not performed, the other LCD routines will not work. This subroutine also sets up the RS, E and R/W LCD control lines as outputs. The ramSub1 and ramSub4 locations are initialized here, but these lines can be removed if the main program does not use txlcd2. kbiIni - this is a simple subroutine that initializes the I/O ports to which the keypad is connected. In the example program, the 4-bit LCD interface has the rows of the keypad connected to PC0:3. In the 8-bit interface, the rows of the keypad are connected to PB4:7. In both cases the columns of the LCD are connected to PB0:3. This program uses the scans input from the keypad from the columns, so PB0:3 are set to input mode. The output bits connected to the rows are made outputs and they are all forced low, so that when any key on the keypad is pressed, an IRQ will be issued.

Application Note 9702


HARRIS Semiconductor (c)1990 - 1996 68HC05 Assembler Version 2.6 Filename: LCD2.LST Source Created: 01/13/97, 00:20 am Assembled: 01/13/97, 00:20:06 00001 ;***************************************************************************** 00002 ; aaaaaaaaaaaa 00003 ; rH""""HHHH""""Hr 00004 ; HHH HHHH HHH COPYRIGHT 1995,1996,1997 00005 ; ,-. ,-. ,-. HARRIS SEMICONDUCTOR 00006 ; __/ |_/ |_/ |__ 00007 ; sss ssss sss 00008 ; HH HHHH HH 00009 ; "HHHHHHHHHHHH" 00010 ; 00011 ; File: lcd.s 00012 ; 00013 ; Version: 1.0 00014 ; 00015 ; Author: Christopher Mazzanti 00016 ; 00017 ; Date: Wed 01-07-96 00018 ; 00019 ; Description: 00020 ; The following is a file of subroutines created for inter00021 ; afacing a 68HC05 MCU with a LCD module containing the Hitachi 00022 ; HD44780 LCD interface chip and a 16 key (4x4 matrix) keypad. 00023 ; The main program used to test out these subroutines prints a 00024 ; text message to the LCD prompting for data and displays char00025 ; acters corresponding to the keys that are pressed. This program 00026 ; was tested out on a CDP68HC05C16B wired so that both 4 and 8 00027 ; bit interfaces to the LCD could be tried out. Note that if 00028 ; the four bit interface is chosen, the LCD must be connected to 00029 ; the lower nibble of the port. 00030 ; Hardware Setup: 4 bit 8 bit LCD Keypad 00031 ; ---------------00032 ; PC3 PB7 DB7 row 4 00033 ; PC2 PB6 DB6 row 3 00034 ; PC1 PB5 DB5 row 2 00035 ; PC0 PB4 DB4 row 1 00036 ; PB3 PB3 DB3 col 4 (IRQ) 00037 ; PB2 PB2 DB2 col 3 (IRQ) 00038 ; PB1 PB1 DB1 col 2 (IRQ) 00039 ; PB0 PB0 DB0 col 1 (IRQ) 00040 ; PC7 PC7 RS 00041 ; PC6 PC6 R/W 00042 ; PC6 PC5 E 00043 ;***************************************************************************** 00044 #include c:\6805\c16b.s --------------------- START OF INCLUDE C:\6805\C16B.S -------------------00001 #nolist 00125 #list ----------------------- END OF INCLUDE C:\6805\C16B.S --------------------00045 00046 ;***************************************************************************** 00047 ; Define Statements: The following constants must be defined for the 00048 ; the proper operation of the LCD and keypad interface 00049 ; subroutines/interrupt service routines: 00050 ; 4bit - this constant defines the LCD interface. 00051 ; lcd - the I/O port to which the LCD is connected. 00052 ; row - the I/O port to which the rows of the keypad are connected 00053 ; row1, row2, etc. - bit pos. in the row I/O port of each row 00054 ; col - the I/O port connected to the columns of the keypad. 00055 ; col1, col2, etc. - bit pos. in the column I/O port of each column 00056 ; lcdctl - I/O port connected to the control lines of the LCD 00057 ; rw - bit pos. of the rw LCD control line in the lcdctl port 00058 ; rs - bit pos. of the rs LCD control line in the lcdctl port 00059 ; e - bit pos. of the e LCD control line in the lcdctl port 00060 ; rowMask - a special mask used in keypad scanning 00061 ; colMask - a special mask used in keypad scanning 00062 ;***************************************************************************** 00063 00064 $0001 = 1 4bit equ 1 ;used to set data interface length 00065 TRUE #if 4bit ;set up constants for 4 bit interface 00066 $0002 = 2 lcd equ portc 00067 $0002 = 2 row equ portc 00068 $0000 = 0 row1 equ 0 00069 $0001 = 1 row2 equ 1 00070 $0002 = 2 row3 equ 2 00071 $0003 = 3 row4 equ 3

Application Note 9702


00072 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140 00141 00142 00143 00144 00145 00146 00147 00148 00149 00150 00151 00152 00153 00154 00155 00156 00157 00158 00159 FALSE #else #endif = = = = = = = = = 2 7 5 6 1 0 1 2 3 15 15 lcdctl rs e rw col col1 col2 col3 col4 rowMask colMask equ equ equ equ equ equ equ equ equ equ equ portc 7 5 6 portb 0 1 2 3 2!row1+2!row2+2!row3+2!row4 2!col1+2!col2+2!col3+2!col4 ;set up constants for 8 bit interface

$0002 $0007 $0005 $0006 $0001 $0000 $0001 $0002 $0003

$000F = $000F =

;***************************************************************************** ; RAM Variables: The following RAM locations must be allocated for the ; proper use of the LCD and keypad scanning subroutines. ; lcdTemp1-6 - temp storage locations used by WLCD and RLCD. These ; can be used by the main program in between calls. ; ramSub1-4 - used to create a RAM subroutine, used by TXLCD2 only. ; rowID - used as temp storage for row detection in keypad scanning ; colID - used as temp storage for column detection ; scanMask - used to hold scanning mask during keypad scan ; keyFlag - used as keypad status (bit 0 only) ; keyData - used to store key ID from keypad scan routine ;***************************************************************************** 0050 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D $0000 = $0001 = 005E 0180 0180 0181 0182 0184 0185 0188 018B 018E 0190 0193 0195 0197 019A 019C 019F 01A1 01A2 01A5 01A7 01A9 01AB 01AD 01B0 01B2 01B4 01B7 01B9 01BC 9C 9B 125D 4F C73FDF CD0311 CD0230 AE00 CD024C A606 AE07 CD0260 A6C0 CD0277 3F5D 9A waitKey 015DFD break 3F5D B65E A143 2705 CD027B 20F0 clrLine AE0F CD024C A6C0 CD0277 20E4 ldx jsr lda jsr bra #clearMes&$FF txlcd1 #$C0 wclcd waitKey ;clear line 2 ;reposition cursor clr lda cmp beq jsr bra keyFlag keyData #'C' clrLine wdlcd waitKey ;clear keypad flag ;get keypad data ;check for "C" ;if C, clear line 2 ;else write character ;get another key brclr 0,keyFlag,* ;wait for key press section vars, $50 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 ds 1 equ 0 equ 1 ds 1 section code, $180 rsp sei bset clra sta jsr jsr ldx jsr lda ldx jsr lda jsr clr cli

0 1

lcdTemp1 lcdTemp2 lcdTemp3 lcdTemp4 lcdTemp5 lcdTemp6 ramSub1 ramSub2 ramSub3 ramSub4 rowID colID scanMask keyFlag keyin imask keyData

;\ ; | ; | ; | ; | ;/ ;\ ; | ; | ;/ ;\ ; | ; | ; | ; | ; | ;/

These locations are used for temp storage in the LCD subroutines

These locations are used for the LCD subroutine TXLCD2 only

Used for the keypad scan ISR

imask,keyFlag option lcdIni kbiIni #msg&$FF txlcd1 #msg2/256 #msg2&$FF txlcd2 #$C0 wclcd keyFlag

;interrupts masked ;set C16B IRQ to edge only ;initialize LCD ;initialize keypad ;send 1st half of lcd message ;send 2nd half of lcd message

;position LCD to beginning of ;line 2 ;clear keypad flag ;enable interrupts

Application Note 9702


00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 00176 00177 00178 00179 00180 00181 00182 00183 00184 00185 00186 00187 00188 00189 00190 00191 00192 00193 00194 00195 00196 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 00207 00208 00209 00210 00211 00212 00213 00214 00215 00216 00217 00218 00219 00220 00221 00222 00223 00224 00225 00226 00227 00228 00229 00230 00231 00232 00233 00234 00235 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** IRQISR **** ; ; This is the interrupt service routine called whenever any ; ; key on the keypad is pressed. This routine includes a 5ms ; ; debounce delay to avoid erroneous keypresses from switch ; ; bounce. The keypad is then checked. If no key is being ; ; pressed, the routine will simply return. If a key is pressed ; ; this routine will display it's assigned character on the LCD ; ; If the "C" key is pressed, line 2 of the LCD will be cleared ; ; and the cursor returned to the beginning of the line. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; irqIsr 01BE 01C1 01C3 01C6 01C8 01CB 01CD 01D0 01D2 01D5 01D8 01DA 01DC 01DE 01E0 01E2 01E4 01E6 01E8 01EA 01EC 01ED 01EF 01F0 01F2 01F4 01F6 01F8 01F9 01FB 01FD 01FF 0201 0202 0203 0205 0206 0209 020B 020D 020F 0211 0212 0214 CD0216 3F5B 010112 3C5B 03010D 3C5B 050108 3C5B 070103 CC01F6 scanRow A603 B75A A6F7 B75C rowLoop B602 AA0F B45C B702 B601 AAF0 43 260A 99 365C 3A5A 2AEA noKey AD38 80 gotKey B602 A4F0 B702 B65A 48 48 BB5B 97 D60220 B75E 105D release B601 AAF0 43 26F9 20E0 debounce 0216 0218 0219 021A 021C 021D 021F 0220 0224 0228 022C A609 debounce1 5F debounce2 5A 26FD 4A 26F9 81 3738392F keyTable 3435362A 3132332D 302E432B decx bne deca bne rts db debounce2 debounce1 clrx lda #$09 lda ora coma bne bra col #~colMask release noKey ;wait for key to be released lda and sta lda lsla lsla add tax lda sta bset row #~rowMask row rowID ;drive all rows low again ;needed for 8 bit routine ;form ofset from rowID:colID bsr rti kbiIni ;when done (or no key) re-init ;keypad port & return lda ora and sta lda ora coma bne sec ror dec bpl row #rowMask scanMask row col #~colMask gotKey scanMask rowID rowLoop ;get keypad row ;make keypad row all "1"s ;mask row ;get keypad column ;set non column bits to 1 ;test results (no key = 0) ;if not 0, found key ;set carry bit for rotate ;shift row scan bit right ;decrement to shift next row ;loop for all 4 rows lda sta lda sta #$03 rowID #~(2!row4) scanMask ;set up row ID ;for scan of row 4 ;set up scan mask jsr clr brclr inc brclr inc brclr inc brclr jmp debounce colID col1,col,scanRow colID col2,col,scanRow colID col3,col,scanRow colID col4,col,scanRow noKey ;5ms debounce ;clear column ID # ;check column 1 for key ;check column 2 for key ;check column 3 for key ;check column 4 for key ;if none, quit ISR

colID keyTable,x keyData 0,keyFlag ;use rowID:colID as offset ;get key ID from table ;store to keyData ;set keypress flag

;and quit ;\ ; | ; | ; | ; | ~5ms delay loop ; | for debouncing keypress ; | ; | ; | ;/ ;keypad lookup table

"789/456*123-0.C+"

00236 00237 00238

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** kbiIni **** ;

Application Note 9702


00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00250 00251 00252 00253 00254 00255 00256 00257 00258 00259 00260 00261 00262 00263 00264 00265 00266 00267 00268 00269 00270 00271 00272 00273 00274 00275 00276 00277 00278 00279 00280 00281 00282 00283 00284 00285 00286 00287 00288 00289 00290 00291 00292 00293 00294 00295 00296 00297 00298 00299 00300 00301 00302 00303 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 00319 00320 ; This routine is used to set up the keyboard i/o ports for ; ; the scanning routine. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; kbiIni 0230 0232 0234 0236 0238 023A 023C 023E 0240 0242 B605 A4F0 B705 B606 AA0F B706 B602 A4F0 B702 81 lda and sta lda ora sta lda and sta rts col+4 #~colMask col+4 row+4 #rowMask row+4 row #~rowMask row ;column are inputs

;make rows outputs ;and load w/ 0's

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** HEX2ASC **** ; ; This routine converts a hexadecimal number in the low nibble ; ; of ACCA to ASCII for output to the LCD ; ; Calls: None Modified: ACCA ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0243 0245 0247 0249 024B AB30 A13A 2B02 AB07 81 HEX2ASC ADD CMP BMI ADD RTS #$30 #$3A SKIP #$07

SKIP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** TXLCD1 **** ; ; This routine takes the ASCII message pointed to by ; ; mesPage:X and displays it on the LCD. This routine ass; ; umes the entire message in on memory page mesPage. This ; ; routine is smaller than TXLCD2 because it only increments ; ; one value (X) and only uses 1 RAM location (mesPage). The ; ; first byte of the message pointed to should be the control ; ; code for placement of the message in the LCD. The last ; ; byte of the message MUST be $00. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TXLCD1 024C 024E 0251 0253 0254 0257 0259 025B 025D 025F B750 D60600 AD24 mesloop 5C D60600 2704 AD20 20F6 B650 81 incx lda beq bsr bra mesLoopDone lda rts mespage,x mesLoopDone wdlcd mesLoop lcdtemp1 ;increment pointer into message ;get next byte of message ;check for $00 (end of message) ;send byte to LCD as data ;loop until end of message ;restore ACCA sta lda bsr lcdTemp1 mespage,x wclcd ;PRESERVE ACCA AND IX ;get first byte of message ;and use it as control (position LCD)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** TXLCD2 **** ; ; This routine takes the ASCII message pointed to by ; ; ACCA:IX and displays it on the LCD. This routine uses ; ; more RAM than TXLCD2 but does have the advantage that the ; ; text message can be anywhere in memory. This routine uses ; ; four bytes of memory (in addition to temp locations) and ; ; is slighly longer than TXLCD1. The first byte of the ; ; message pointed to should be the control code for place; ; ment of the message in the LCD. The last byte of the ; ; message MUST be $00. ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TXLCD2 0260 0262 0264 0266 0268 026A 026C 026E 0270 0272 B757 BF58 BD56 AD0F mesloop2 3C58 2602 3C57 noIncHi BD56 2704 AD07 jsr beq bsr ramSub1 mesLoopDone2 wdlcd ;get next byte on message ;check for end of message ($00) ;if not end, write data to LCD inc bne inc ramSub3 noIncHi ramSub2 ;increment message pointer low byte ;ckeck for overflow, increment high byte of ;necessary sta stx jsr bsr ramSub2 ramSub3 ramSub1 wclcd ;store ACCA and IX for subroutine jump ;use ram subroutine to get byte ;position LCD

10

Application Note 9702


00321 00322 00323 00324 00325 00326 00327 00328 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387 00388 00389 00390 00391 00392 00393 00394 00395 00402 00403 00404 00405 00406 00407 00408 0274 0276 20F2 81 bra mesLoopDone2 rts mesLoop2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** WCLCD **** ; ; This routine takes the contents of ACCA and writes it to ; ; the LCD as a conrtol byte. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 0277 0279 1F02 2002 WCLCD BCLR BRA RS,LCDCTL WLCD ;Pull RS line low for control ;byte write

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** WDLCD **** ; ; This routine takes the contents of ACCA and writes it to ; ; the LCD as a data byte. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 027B 1E02 WDLCD BSET rs,LCDCTL ;Pull RS line high for data byte write

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** WLCD **** ; ; This subroutine takes the contents of ACCA and writes it ; ; to the LCD. This routine polls the LCD busy flag and ; ; waits until it is low before writing to the LCD. This ; ; This routine does NOT control the RS bit of the LCD, so ; ; the contents of ACCA may be either display data or ; ; control data. This routine has a conditional assembly ; ; flag "4bit" that controls the LCD interface length. If ; ; the 4 bit interface is chosen, data is transfered on the ; ; low nibble of the port. ; ; RAM used: ; ; lcdTemp2 - byte to send ; ; lcdTemp3 - RS preserved for RCLCD call ; ; lcdTemp4 - preserved LCD port data ; ; lcdTemp5 - preserved LCD DDR port data ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

WLCD 027D 027F 0281 0283 0285 0287 0289 028B 028D 028F 0291 0293 0295 0297 TRUE 0299 029B 029D 029F 02A1 02A3 02A5 02A7 02A9 02AB 02AC 02AD 02AE 02AF FALSE B751 B602 A480 B752 waitLcd AD47 A580 26FA B652 BA02 B702 B606 B754 1D02 1B02 #if 4bit B602 A4F0 B753 AA0F B702 B606 AA0F B706 B651 44 44 44 44 BB53 #else #endif B702 1A02 9D 1B02 sta bset NOP bclr lcd e,lcdctl e,lcdctl ;port data and store to LCD i/o port ;raise E strobe to LCD ;timing delay for 2us pulse width ;lower E strobe lda and sta ora sta lda ora sta lda lsra lsra lsra lsra add lcd #$F0 lcdTemp4 #$0F lcd lcd+4 #$0F lcd+4 lcdTemp2 ;get current port data ;and preserve in RAM ;make IRQ bits high before setting DDRs ;to avoid false interrupts bsr bit bne lda ora sta lda sta bclr bclr rclcd #$80 waitLcd lcdTemp3 lcdctl lcdctl lcd+4 lcdTemp5 rw,lcdctl E,lcdctl ;read control bit of the LCD ;to make sure no internal write ;operation is going on. Loop until ;busy flag is clear ;\ ; |-restore state of RS bit ;/ sta lda and sta lcdTemp2 lcdctl #2!rs lcdTemp3 ;save data byte in ACCA ;save state of RS bit

;set LCD for write operation ;lower E strobe line

;make lower nibble of LCD port output ;get data byte stored previously ;shift upper nibble to lower nibble, ;fill rest with 0's.

lcdTemp4

;combine with upper nibble of current data

02B1 02B3 02B5 02B6

11

Application Note 9702


00409 00410 00411 00412 00413 00414 00415 00416 00417 00418 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 00434 00435 00436 00437 00438 00439 00440 00441 00442 00443 00444 00445 00446 00447 00448 00449 00450 00451 00452 00453 00454 00455 00456 00457 00458 00459 00460 00461 00462 00463 00464 00465 00466 00467 00468 00469 00470 00471 00472 00473 00474 00475 00476 00477 00478 00479 00480 00481 00482 00483 00484 00485 00486 00487 00488 00496 00497 TRUE 02B8 02BA 02BC 02BE 02C0 02C2 02C3 #if 4bit B651 A40F BB53 B702 1A02 9D 1B02 #endif 02C5 02C7 02C9 02CB 02CD B654 B706 B653 B702 81 lda sta lda sta RTS lcdTemp5 lcd+4 lcdTemp4 lcd ;\ ; | ; | restore previous DDR and port data ; / lda and add sta bset nop bclr lcdTemp2 #$0F lcdTemp4 lcd e,lcdctl e,lcdctl ;get LCD data byte for next nibble ;transfer ;combine with current port data ;and write it to the LCD port ;raise E strobe to LCD ;timing delay for 2us pulse width (4MHz) ;lower E strobe

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** RCLCD **** ; ; This routine reads a byte from the LCD as a control byte ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RCLCD 02CE 02D0 1F02 2002 bclr bra rs,lcdctl rlcd

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** RDLCD **** ; ; This routine reads a byte from the LCD as a control byte ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RDLCD 02D2 1E02 bset rs,lcdctl

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** RLCD **** ; ; This subroutine reads a byte from the LCD module and re- ; ; turns it in ACCA. This routine does not control the RS ; ; bit of the LCD module, this should be done by either ; ; RCLCD or RDLCD. This routine has a conditional assembly ; ; flag "4bit" that controls the LCD interface length. If ; ; the 4 bit interface is chosen, data is transfered on the ; ; low nibble of the port. ; ; RAM used ; ; lcdTemp4 - preserved LCD port data ; ; lcdTemp5 - preserved LCD DDR data ; ; lcdTemp6 - temp store LCD read ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RLCD 02D4 02D5 02D7 02D9 02DB 02DD 02DF 9B B606 B754 1C02 1B02 B602 B753 sei lda sta bset bclr lda sta lcd+4 lcdTemp5 rw,lcdctl E,lcdctl lcd lcdTemp4 ;mask interrupts (need only if LCD port ;has interruptable pins on it) ;\ preserve LCD DDR port ;/ ;set LCD for read operation ;lower E

TRUE 02E1 02E3 02E5 02E7 02E9 02EA 02EC 02EE 02F0 02F1 02F2 02F3 02F4 02F6 02F8 02FA 02FC 02FE 0300 FALSE 0302

#if 4bit B606 A4F0 B706 1A02 9D B602 A40F 1B02 48 48 48 48 1A02 B755 B602 A40F 1B02 BB55 B755 #else #endif B653 lda lcdTemp4 lda and sta bset nop lda and bclr lsla lsla lsla lsla bset sta lda and bclr add sta lcd+4 #$F0 lcd+4 E,lcdCtl lcd #$0F E,lcdCtl ;make lcd port input ;make LCD port input ;raise strobe for data ;delay ;get high nibble ;mask and shift ;lower strobe

E,lcdCtl lcdTemp6 lcd #$0F E,lcdCtl lcdTemp6 lcdTemp6

;first nibble read, get 2nd ;store high nibble ;get low nibble ;lower strobe ;put nibbles together

12

Application Note 9702


00498 00499 00500 00501 00502 00503 00504 00505 00506 00507 00508 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 00520 00521 00522 00523 00524 00525 00526 00527 00528 00529 00530 00531 00532 00533 00535 00536 00537 00538 00539 00540 00541 00542 00543 00544 00545 00546 00547 00548 00549 00550 0304 0306 0308 030A 030C 030F 0310 B702 B654 B706 B655 025D01 9A no_cli 81 rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; **** lcdIni **** ; ; This routine configures the LCD. Parameters are set as ; ; follows: ; ; 1. The cursor is set to increment (move left to right) ; ; 2. The cursor is set to not shift with the incoming data ; ; 3. Turns the display on ; ; 4. Sets data length, number of display lines and font ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; lcdIni 0311 0313 0315 0317 0319 031B 031D 031F 0321 0323 0325 TRUE 0327 FALSE 0329 032C 032E 0331 0333 0336 0338 033B 033D B750 A6C6 B756 A681 B759 B606 AAE0 B706 B602 A41F B702 #if 4bit A62F #else #endif CD0277 A606 CD0277 A60F CD0277 A601 CD0277 B650 81 jsr lda jsr lda jsr lda jsr lda rts wclcd #$06 wclcd #$0F WCLCD #01 wclcd lcdTemp1 ;set display to increment ;turn display on ;clear DDRAM and reset address pointer ;restore ACCA lda #$2F ;set data interface (4 bit) sta lda sta lda sta lda ora sta lda and sta lcdTemp1 #$C6 ramSub1 #$81 ramSub4 lcdctl+4 #(2!rs+2!e+2!rw) lcdctl+4 lcdctl #~(2!rs+2!e+2!rw) lcdctl ;preserve ACCA ;\ ; |These lines can be deleted if ; |TXLCD2 is not used ;/ ;\ ; | ; | Set RS, E and RW port bits ; | bits to output, clear all bits ; | ;/ sta lda sta lda brset cli lcd lcdTemp5 lcd+4 lcdTemp6 imask,keyFlag,no_cli

0600 0600 0604 0607 060B 060F 0613 0617 061B 061F 3FF4 3FF4 3FF6 3FF8 3FFA 3FFC 3FFE

80507265 msg 737300 85206120 msg2 6B657900 C0202020 clearMes 20202020 20202020 20202020 202000

section mesPage, $600 db $80,"Press",$00 db db $85," a key",$00 $C0,"

;message page

",$00

00551 00552 00553 00554 00555 00556 00557 00558

0180 0180 0180 01BE 0180 0180

section vectors, $3FF4 dw code dw code dw code dw irqIsr dw code dw code

13

You might also like