Keypad LCD Ds

13

Click here to load reader

Transcript of Keypad LCD Ds

Page 1: Keypad LCD Ds

Copyright © Harris Corporation 1997

1

Harris Semiconductor

Keypad Scan and LCD Interface for the CDP68HC05Author: Christopher Mazzanti

IntroductionThis application note details input/output interfaces to a Har-ris CDP68HC05 microcontroller. Being able to easily displaytext information to human operators and prompt for datainput from a keypad is a very important part of what makeslow cost 8-bit microcontrollers attractive. The LCD interfacedetailed within this application note is not directly to an LCDbut rather to LCD modules with the Hitachi HD44780 LCDchipset, such as the Optrex 16202. The keypad scan inter-face uses the IRQ/Pull up mask options available on all “B”versions of Harris CDP68HC05 microcontrollers (i.e.,CDP68HC05C8B).

OperationThis section is divided into two sections: Keypad Scan andLCD Interface. Each of these sections gives an overview ofthe operation of the hardware and software associated witheach type of interface.

KEYPAD SCAN INTERFACE

The keypad scan interface described in this application noteuses the Port B interrupt/pull-up mask option of theCDP68HC05C16B. Before an explanation of the keypad scan-ning 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 interms of the CDP68HC05C4B, C8B and C16B. Port A inter-rupts and pull ups on the CDP68HC05J4B function similarlyexcept where noted.

In addition to being a standard bidirectional port, each bit ofPort B has a mask option to connect a pullup device to theI/O pad and to simultaneously feed the input to the internalinterrupt logic. When the mask option is not selected, eachPort B pin behaves as a standard bidirectional port pin.

When the mask option is selected, a pullup PMOS devicewith an impedance of approximately 20kΩ is connectedbetween the pad and VDD (see Figure 1B for Pullup CurrentIIN) and the input signal is inverted and internally ORed withthe IRQ signal (refer to Figure 1A).

The interrupt behavior of any port B pin which has the pul-lup/interrupt mask option activated is identical to the resultsone would achieve by externally ORing (active low) the sig-nal with the IRQ signal.

The pullup device and the interrupt function are disabledwhen the associated DDRB bit is set high. When its DDRBbit is a 1, each port B pin acts as a normal output regardlessof whether or not the pullup/interrupt mask option has beenselected. Thus the DDRB bit can be used as an interruptenable for the interruptible port B pins. Care should be takenwhen re-enabling a port B interrupt to avoid false interrupts.False interrupts can be avoided by first driving the PORTBbit high before clearing the DDRB bit. Further note that allDDRB bits are cleared by reset, thus enabling port B inter-rupts (no interrupt will be recognized until execution of thefirst CLI instruction following reset).

FIGURE 1A. PORT B INTERRUPT AND PULLUP MASK OPTION

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

PBn

OTHER PORT B INPUTS

DDRB BIT n

MASK OPTION

P

TO INTERNAL

INTERRUPT

IRQ

PORT

VDDVDD

CIRCUITRY

0 1.0 2.0 3.0 4.0 5.0 6.0

50

100

150

200

250

300

VPD, PULL DOWN VOLTAGE (V)

I IN, P

-CH

AN

NE

L P

ULL

UP

DE

VIC

EC

UR

RE

NT

(µA

)

No. AN9702 February 1997 Harris Digital

Page 2: Keypad LCD Ds

2

Keypad Scanning

The keypad scan routine detailed here is for a 16 key, 4 rowby 4 column matrix keypad. Four of the keypad I/O port linesmust be on a I/O port with the IRQ/Pull-up mask option set.These lines will detect a key press by causing an externalhardware interrupt to be issued whenever any key ispressed. The other four port I/O lines connected to the key-pad can be from any general purpose output port. Also, it isassumed 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 linesof the keypad. These are output lines that the MCU willstrobe to determine which key is being pressed. The otherfour lines are connected to the column lines of the keypadand go straight to the IRQ/Pull-up I/O port lines of the MCU(Port B for the CDP68HC05C4B/C8B/C16B and Port A forthe CDP68HC05J4B). These lines will always be in the inputmode when scanning the keypad (See Figure 2). When wait-ing for a keypress, all four row lines (i.e., the output lines) willbe driven low. The column lines (input lines) will be pulled upthrough their individual on-chip pull-up resistors. Wheneverany key is pressed, the associated column line is pulled low(since it is now connected to a row line), causing a hardwareinterrupt to be issued. It is the responsibility of the IRQ ser-vice routine to determine if a key is being pressed and if so,to debounce it and figure out which one. While waiting for akey press, the 68HC05 will most likely have other things todo. To allow the MCU to go about it’s processing, all Harris68HC05xxxB version microcontrollers have mask optionsthat can make each one of the lines on a specific I/O port actlike the IRQ pin when that particular line is pulled low in inputmode. Thus, whenever one of these lines is pulled low, ahardware interrupt is issued. Internal active CMOS pull-upresistors are connected to the port so that the inputs are notfloating when not connected to anything, causing inadvertentinterrupts. Since all four row lines are driven low while wait-ing, any keypress will pull at least one line low, causing anIRQ interrupt. Without this port interrupt ability, the MCUwould have to continuously scan the keypad to detect a key-press. This is the advantage of having the IRQ/Pull-up maskoption enabled.

The IRQ service routine is where all of the keypad scanning,debouncing and key identification takes place. In the IRQservice routine, the first thing that has to be done is to deter-mine the source of the IRQ. If the user code is using the IRQpin of the MCU to connect to another peripheral (a Harris65C51 UART for example), the IRQ service routien mustdetermine if the interrupt came from the IRQ pin or from the

Port B pull-ups. Once the source of the IRQ has been deter-mined to be a keypress, the next thing to do is to debounceit. This needs to be done because switch bounce (caused bythe switch contacts closing, separating and the closingagain) can cause the 68HC05 to read the switch during abounce and incorrectly assume that no key is being pressed.To avoid this we use a 5ms timing delay loop. This delaygives the contacts plenty of time to bounce and settle intoposition. Now that the keypress has been detected anddebounced, the interrupt routine must now figure out whichkey is being pressed. To do this we read in the column bitsand test them sequentially to determine in which column akey is being pressed in. If two keys are being pressed simul-taneously, this scan routine will detect the one in the columnscanned first.

Once it has been determined which column the key is in, theservice routine must now determine which row in that col-umn the key is in, thus giving us the key location. At thispoint we write “1”s to all of the row locations except for thefirst one (i.e., row 1 in this case). We then test the column bitwhere we determined previously that the key being pressedwas in. If this line is low, then we have found the key. If not,then we write “1”s to all of the row lines except for row 2 andtest the column again. In this way we can scan through thekeypad and determine the exact location of the keypress.Running at 4MHz, the 68HC05 can scan the keypad muchfaster than a human can press a key and release it (evenwith the 5ms debounce delay). If the routine determines thatno key is pressed, then it simply returns from the interruptand continues from where it left off. The IRQ service routinein the assembly listing later in the document details theentire keypad scanning process.

LCD INTERFACE

Strictly speaking, the interface described here does not con-nect a 68HC05 with an LCD. To do so would require specialcontrol circuitry in the 68HC05 itself and many more I/O linesthan are available even with the 40 pin CDP68HC05C16B.Rather, this interface is to the Hitachi LCD driver/display con-trol chip set specifically designed for controlling text LCD dis-plays. These chips have become very standard in theirinterface and are used by many LCD module manufacturerssuch as Optrex. The LCD unit used for this application noteis an Optrex DMC16202. This is a 16 character by 2 line dis-play, although larger displays (in terms of character lengthand line count) work similarly.

The standard LCD interface (as the Hitachi-interface will bereferred to from now on) will need a maximum of 14 linesconnected to the LCD module - 8 data, 3 control, 2 powerand 1 contrast (see the LCD technical information for detailson power supply and contrast connections) of which any-where from 6 to 11 lines will need to be connected to theMCU. Data can be transferred to the LCD in either byte-widetransfers or nibble-wide transfers, but since all text to be dis-played on the LCD is encoded in an 8-bit ASCII-like format,choosing four bit operation means that two transfer opera-tions will be needed for every character sent to the LCD. 8-bit transfers require more I/O port lines, but they do speed upLCD transfers and make the software interface a bit more

FIGURE 2. 4x4 MATRIX KEYPAD

COLUMN LINES - TO MCU INPUT

TO M

CU

OU

TP

UT

1 2 3

4

1

2

3

4

RO

W L

INE

S

Application Note 9702

Page 3: Keypad LCD Ds

3

simple. This application note contains a code to run the LCDin either 8-bit or 4-bit mode, depending upon assemblerdirectives. Diagrams for the two types of LCD interface alongwith the keypad connections are shown below in Figures 3Aand 3B. Both of these connections and the code associatedwith them read from the LCD and poll the LCD busy flaginstead of using timing delays. Note that the four bit interfacetransfers data on the low nibble of the port, although the soft-ware could just as easily be changed to transfer on the highnibble of the port.

When writing data to the LCD module, there are two types oftransfers that can occur - a control write or a data write. Con-trol writes are data sent to the LCD for configuration pur-poses such as setting the DDRAM address pointer (moreabout the DDRAM in the next paragraph), data interfacelength, and cursor display for example (a complete list of allof the control codes for the LCD is listed below). The RScontrol line to the LCD needs to be low for control codewrites to the LCD. If the RS line is high, writes to the LCD arewritten to the DDRAM.

Data written to the LCD module for display is written to RAMlocations in the Hitachi interface chips and is echoed to thedisplay. This RAM is known as Data Display RAM (DDRAM).Every display location on the LCD has an associatedDDRAM location with it; there are even DDRAM locationsthat exist that are not displayed. The DDRAM has an internaladdress pointer so that data byte writes to the LCD will go toa specific location. This address pointer can be set up toincrement or not to increment when data is written to theDDRAM. The address pointer can also be set directly by acontrol write. DDRAM display locations along with a table ofall of the control codes for the LCD module are shown belowin Figure 6 and Table 2, respectively.

The E control line of the LCD module is used as the datastrobe of the module. This is an active high pulse used to latchthe data being written into the LCD or to signal the MCU thatthe data being read from the LCD is ready. Timing diagramsfor write and read operations are shown in Figure 4 below.

FIGURE 3A. 8-BIT LCD INTERFACE WITH KEYPAD

FIGURE 3B. 4-BIT LCD INTERFACE WITH KEYPAD

FIGURE 4. DDRAM ADDRESSES AND LCD DISPLAY POSITION

4

4

NOTE: IRQ/PULL-UP OPTION ON PORT B [7:4]

KEYPAD

ROW

COLUMN

LCD

ER/W

RS

DATA [3:0]

DATA [7:4]

68HC05C8B

PORT I/O

PORT B [3:0]

PORT B [7:4]

68HC05J4B

PORT I/O

PORT C [3:0]

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

PORT A [3:0]

LCD

ER/W

RS

DATA [7:4]

KEYPAD

ROW

COLUMN4

4

40

00

UNSHIFTED 16 CHARACTER DISPLAY AREAUPPER DDRAMADDRESSES

LINE 1

LINE 2DDRAM ADDRESSES (HEX)

1DISPLAY POSITION

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

41

01

42

02

43

03

44

04

45

05

46

06

47

07

48

08

49

09

4A

0A

4B

0B

4C

0C

4D

0D

4E

0E

4F

0F

50

10

51

11

. . .

. . .

Application Note 9702

Page 4: Keypad LCD Ds

4

The LCD interface contains a read/write control line that canallow the MCU to read data from the LCD module. Since thecharacters being displayed each have their own address loca-tion within the LCD’s “display RAM”, they can be addressedand read just like any other peripheral RAM. Chances are thatmost applications will not need to do this. However, being ableto read the LCD means that the LCD subroutines can checkthe status of the LCD busy flag. Each operation the LCD per-forms takes a certain amount of time to complete. Most ofthese times are around to 40µs range, although some opera-tions can take as long as 1.64ms to complete. With a MCUrunning at 4MHz, this can be quite a long time. During one ofthe operations, the LCD ignores all data transmissions until itis done. To avoid sending the LCD data that will be ignored,the MCU must either poll the busy flag by reading a controlbyte from the LCD or sit in delay loops until the LCD has com-pleted it’s operation. The second alternative saves an I/O line(the LCD read/write bit would simply be tied low) but doesrequire extra timing loops in the source program that may beunnecessary. Another drawback to using timing loops is thatfor every write to the LCD, at least 40µs of MCU time will bewasted, most of it in unproductive delay loops. If the busy flagis only polled at the beginning of a write sequence, so if theMCU was doing other things between writes to the LCD (aswould probably be the case), chances are that the LCD willalmost always have time to complete a write cycle. If the LCDis busy when a write starts, then and only then will the68HC05 wait for the LCD to complete it’s operation. If theoperation is a clear display (or similar) that takes 1.64ms tocomplete, even more MCU time is wasted if timing loops are

used. Also, there is still the risk that the LCD is not finishedwith an operation even though the timing loop is finished.Reading the LCD has the drawback of the added I/O line andcode complexity, but is assures that the LCD is done with pre-vious operations before being written to. As long as I/O portconstraints and code size permit it, we recommend polling thebusy flag over timing loops.

Software

The software routines written for this application note include allof those needed to interface a 4x4 matrix keypad and a 16x2Optrex LCD display. Included in the assembly listing are all ofthe subroutines necessary to read data from the LCD, writedata to the LCD and scan the keypad. Also included are somehigher level subroutines (i.e., they call the LCD read/write rou-tine WLCD and RLCD) to make string display a little easier. Thebasic function of the “main” program listed here is to “wait” for akeypress and display the key that was pressed. The LCD will becleared and the cursor set to the home position when the “C”key is hit. Each of the 16 keys on the keypad have beenassigned an ASCII value in a setup similar to a calculator key-pad (Figure 6). All of the keypad scanning is done in the IRQinterrupt service routine.

FIGURE 5A. WRITE OPERATION FIGURE 5B. READ OPERATION

TABLE 1. TIMING CHART

ITEM SYMBOL MEASURING CONDITION MIN TYP MAX UNIT

Enable Cycle Time TCYCE Write, Read 1000 - - ns

Enable Pulse Width, High Level PWEH Write, Read 450 - - ns

Enable Rise and Decay Time tEr, tEf Write, Read - - 25 ns

Address Setup Time, RS, R/W-E tAS Write, Read 140 - - ns

Data Delay Time tDDR Read - - 320 ns

Data Setup Time tDSW Write 195 - - ns

Data Hold Time (Write Operation) tH Write 10 - - ns

Data Hold Time (Read Operation) tDHR Read 20 - - ns

Address Hold Time tAH Write, Read 10 - - ns

RS

R/W

E

DB0 ~ DB7

tAHtAS

PWEH tAH

tEF

tCYCE

tHtDSW

tER

VALIDDATA

RS

R/W

E

DB0 ~ DB7

tAHtAS

PWEH tAH

tEF

tCYCE

tDHRtDDR

tER

VALIDDATA

FIGURE 6. ASCII KEYPAD ASSIGNMENT

7

4

1

0

8

5

2

.

9

6

3

C

/

*-

+

Application Note 9702

Page 5: Keypad LCD Ds

5

• irqIsr - this is the IRQ interrupt service routine and whereall of the keypad scanning and key identification takesplace. The first thing that is done here is a delay subrou-tine called debounce is called. The purpose of this rou-tine is to give the switch contacts enough time to settle sothat reads of the keypad won’t produce erroneous results.This delay here is set for approximately 5ms (at 4MHz)but can easily be shorted or lengthened to suit differentapplications. Next, the columns of the keypad arescanned to see in which column the key being pressed isin. Note that this routine relays heavily on the keypadconstants defined at the beginning of the assembly list-ing. “Col” is defined as the I/O port to which the keypadcolumns are connected. Likewise, “row” is the port towhich the keypad row lines are connected. “row1”, “row2,“col1”, etc., are the bits within the “row” and “col” portsthat those respective keypad lines are connected to. Inthis way the keypad columns and rows can be moved todifferent port locations without changing the assemblycode. Once the column that the key being pressed is in isidentified, it’s value minus 1 (i.e., column 1 = 0) is storedin the RAM variable colID. Next the rows are scanned.

This is done in a loop where each row line is individuallydriven low while the others are high and the columnschecked for a keypress. When the row that the key is in isidentified, it’s row location is stored in rowID the sameway as the column number was stored in colID. Now thatthe row and column of the key are known, colID androwID are put together (rowID:colID) to form a uniquefour bit ID of the key that was pressed (This method canbe used to scan keypads up to 16x16). This ID number isthen used as an offset into a table (keyTable). The tablehere simply contains the ASCII values of the keys for dis-play on the LCD. This ASCII value for the key that waspressed is stored in the RAM variable “keyData” for returnto the main routine. The “keyFlag” variable also has it’s bit0 set to indicate to the main program that a keypress hasoccurred. Before the RTI is issued, this particular routinewaits until the key is released. This is done because thekey being pressed could interfere with accesses to theLCD and cause false interrupts to be issued. If the key-pad does not share I/O ports with another peripheral, thispart of the routine can be removed.

TABLE 2. LCD COMMAND CODE CHART

INSTRUCTION

CODE

DESCRIPTIONEXECUTIONTIME (MAX)RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0

Clear Display 0 0 0 0 0 0 0 0 0 1 Clears the display and returns cursorto home position.

1.64ms

Cursor at Home 0 0 0 0 0 0 0 0 1 x Returns cursor to home position.Also returns the display being shifted.

1.64ms

Entry Mode Set 0 0 0 0 0 0 0 1 I/D S Sets cursor increment (I/D) and dis-play shift (S).

40µs

Display On/Off 0 0 0 0 0 0 1 D C B Sets Display On/Off (D), cursorOn/Off (C), Blink Cursor (B)

40µs

Cursor/DisplayShift

0 0 0 0 0 1 S/C R/L x x Sets display/cursor shift (S/C) and di-rection of shift (R/L)

40µs

Function Set 0 0 0 0 1 DL N F x x Set interface length (DL), number oflines (N) and character font (F)

40µs

CGRAMaddress set

0 0 0 1 CGRAM Address Sets the Character Generator RAMaddress

40µs

DDRAMaddress set

0 0 1 DDRAM Address Sets the Data Display RAM address 40µs

Busy Flag/Address Read

0 1 BF Address Counter (Both DDRAM and CGRAM) Reads the Busy Flag (BF) and ad-dress counter contents.

40µs

CG/DDRAMData Write

1 0 Write Data Writes data into DDRAM or CGRAM 40µs

CG/DDRAMData Read

1 1 Read Data Reads data from DDRAM or CGRAM 40µs

I/D: 0 = increment, 1 = decrementS: 0 = no shift, 1 = shift displayS/C: Display Shift, 1 = Cursor Shift

R/L: 0 = Shift Left, 1= Shift RightDL: 0 = 4-bit, 1 = 8-bitN: 0 = 1 line, 1 = 2 lines

F: 0 = 5x7 dots, 1 = 5x10 dotsBF: 0 = LCD ready, 1 = LCD Busyx = don’t care

Application Note 9702

Page 6: Keypad LCD Ds

6

• hex2asc - This is a simple but useful little subroutine forconverting hexadecimal nibbles into ASCII bytes. For anyhex number sent to this routine in the low nibble of ACCA,it’s ASCII value will be returned.

• txlcd1 - This is one of a pair of text string display routineswritten for the LCD interface. This routine uses a constantdefined in the assembler as mesPage and a variable in IXas a pointer to the beginning of the message. The disad-vantage to this is that ALL of the text messages mustreside in the same 256 byte page (i.e., $09xx). The advan-tage of this routine is that it is smaller than txlcd2, itrequires only one parameter to be setup prior to beingcalled (IX) and it only uses 1 byte of RAM (no RAM is usedexcept for that used in wclcd and wdlcd if the contents ofACCA are not preserved). The format for the message is<control byte, message, $00>. The control byte is used forpositioning the LCD cursor before the write (i.e., $80would send the cursor to position 0, line 1). The messagepart is simply ASCII text. The $00 at the end is essentialbecause this is how the routine knows the message is fin-ished.

• txlcd2 - This is the other text string display routine devel-oped for the LCD interface. This routine is more complexand uses 4 bytes of RAM but it does have the advantagethat the LCD message can be anywhere in memory. Thelocation of the message is passed to the subroutine inACCA and IX in the form ACCA:IX. In the subroutine,another subroutine is set up in RAM and it is this routinethat is used to get the bytes of the message. If this routineis used, it is important that a $C6 is stored to ramSub1and a $81 is stored to ramSub4. These are the LDA(extended) and RTS opcodes for the RAM subroutine. Ifthe user program does not wish to load both ACCA and IX(IX may be being used as a counter) then the messageaddress can be stored directly in ramSub2:ramSub3before calling the program. In this case the first two linesof the subroutine could be deleted.

• wclcd - This is the subroutine called for writing a controlbyte, contained in ACCA, to the LCD. The meat of thissubroutine, like that of wdlcd, is the routine wlcd. Thewclcd 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 ofthe LCD is set high indicating a data write to the LCD.

• wlcd - This is one of the two main LCD interface subrou-tines. This routine takes a byte passed to it in the accumu-lator and writes it to the LCD. It is important to rememberthat the RS control line is not affected by this subroutine,so writes to the LCD will almost always call either wclcd orwdlcd instead. This routine requires several RAM bytes toproperly preserve the state of the LCD data port upon exit(this is important when using the port i/o for both LCD andkeypad interface). If the state of the LCD data port is notimportant in that only the LCD is connected to these lines,the RAM variables lcdTemp5 and lcdTemp6 can beremoved from this routine. The first thing that happenswhen wlcd is called is that the state of the RS bit is pre-served. This is important because when the subroutine

rclcd is called to check the LCD busy flag, the RS bit willreturn clear. Wlcd will loop infinitely until the flag is clear.When the flag is clear, the RS bit is restored and the Estrobe is lowered. The byte sent to the routine is loadedand, if the 4bit assemble option, the byte is shifted rightfour times, added to the previous port data and written tothe LCD output. If the 4bit option is not set, the entire byteis simple written to the LCD port. After the write, the Estrobe is pulled high followed by two NOPs for timing (thisgives a 2ms pulse width at 4MHz. More may be needed athigher frequencies), after which time the E strobe is low-ered. At this point the 8-bit interface is done, but the 4-bitinterface still has to write the lower nibble of the data byteto the LCD port and strobe the LCD again.

• rclcd - This is the subroutine called for reading a controlbyte from the LCD and returned to the calling program inACCA. The meat of this subroutine, like that of rdlcd, is theroutine rlcd. The rclcd part simply sets the RS control lineof the LCD low, indicating a control read.

• rdlcd - Same as rclcd except that the RS control line ofthe LCD is set high indicating a data read from the LCD.

• rlcd - this subroutine is a second of the two major LCDinterface subroutines. Like wlcd, this routine has the 4bitassembler option for a 4-bit/8-bit LCD interface.

• lcdini - this subroutine is an important one to call beforeany of the other LCD interface routines are called. Whenthe LCD module powers up, its default state is usually notwhat is desired. In this routine the data interface length isset along with the cursor type and increment, the display isthen turned on and cleared. If these operations are notperformed, the other LCD routines will not work. This sub-routine also sets up the RS, E and R/W LCD control linesas outputs. The ramSub1 and ramSub4 locations are ini-tialized here, but these lines can be removed if the mainprogram does not use txlcd2.

• kbiIni - this is a simple subroutine that initializes the I/Oports to which the keypad is connected. In the exampleprogram, the 4-bit LCD interface has the rows of the key-pad connected to PC0:3. In the 8-bit interface, the rows ofthe keypad are connected to PB4:7. In both cases the col-umns of the LCD are connected to PB0:3. This programuses the scans input from the keypad from the columns,so PB0:3 are set to input mode. The output bits connectedto the rows are made outputs and they are all forced low,so that when any key on the keypad is pressed, an IRQwill be issued.

Application Note 9702

Page 7: Keypad LCD Ds

7

HARRIS Semiconductor (c)1990 - 199668HC05 Assembler Version 2.6Filename: LCD2.LSTSource Created: 01/13/97, 00:20 amAssembled: 01/13/97, 00:20:0600001 ;*****************************************************************************00002 ; aaaaaaaaaaaa00003 ; rH""""HHHH""""Hr00004 ; HHH HHHH HHH COPYRIGHT 1995,1996,199700005 ; ,-. ,-. ,-. HARRIS SEMICONDUCTOR00006 ; __/ |_/ |_/ |__00007 ; sss ssss sss00008 ; HH HHHH HH00009 ; "HHHHHHHHHHHH"00010 ;00011 ; File: lcd.s00012 ;00013 ; Version: 1.000014 ;00015 ; Author: Christopher Mazzanti00016 ;00017 ; Date: Wed 01-07-9600018 ;00019 ; Description:00020 ; The following is a file of subroutines created for inter-00021 ; afacing a 68HC05 MCU with a LCD module containing the Hitachi00022 ; HD44780 LCD interface chip and a 16 key (4x4 matrix) keypad.00023 ; The main program used to test out these subroutines prints a00024 ; text message to the LCD prompting for data and displays char-00025 ; acters corresponding to the keys that are pressed. This program00026 ; was tested out on a CDP68HC05C16B wired so that both 4 and 800027 ; bit interfaces to the LCD could be tried out. Note that if00028 ; the four bit interface is chosen, the LCD must be connected to00029 ; the lower nibble of the port.00030 ; Hardware Setup: 4 bit 8 bit LCD Keypad00031 ; ----- ----- --- ------00032 ; PC3 PB7 DB7 row 400033 ; PC2 PB6 DB6 row 300034 ; PC1 PB5 DB5 row 200035 ; PC0 PB4 DB4 row 100036 ; 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 RS00041 ; PC6 PC6 R/W00042 ; PC6 PC5 E00043 ;*****************************************************************************00044 #include c:\6805\c16b.s

--------------------- START OF INCLUDE C:\6805\C16B.S --------------------00001 #nolist00125 #list

----------------------- END OF INCLUDE C:\6805\C16B.S ---------------------0004500046 ;*****************************************************************************00047 ; Define Statements: The following constants must be defined for the00048 ; the proper operation of the LCD and keypad interface00049 ; 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 connected00053 ; row1, row2, etc. - bit pos. in the row I/O port of each row00054 ; 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 column00056 ; lcdctl - I/O port connected to the control lines of the LCD00057 ; rw - bit pos. of the rw LCD control line in the lcdctl port00058 ; rs - bit pos. of the rs LCD control line in the lcdctl port00059 ; e - bit pos. of the e LCD control line in the lcdctl port00060 ; rowMask - a special mask used in keypad scanning00061 ; colMask - a special mask used in keypad scanning00062 ;*****************************************************************************0006300064 $0001 = 1 4bit equ 1 ;used to set data interface length00065 TRUE #if 4bit ;set up constants for 4 bit interface00066 $0002 = 2 lcd equ portc00067 $0002 = 2 row equ portc00068 $0000 = 0 row1 equ 000069 $0001 = 1 row2 equ 100070 $0002 = 2 row3 equ 200071 $0003 = 3 row4 equ 3

Application Note 9702

Page 8: Keypad LCD Ds

8

00072 FALSE #else ;set up constants for 8 bit interface00079 #endif0008000081 $0002 = 2 lcdctl equ portc00082 $0007 = 7 rs equ 700083 $0005 = 5 e equ 500084 $0006 = 6 rw equ 60008500086 $0001 = 1 col equ portb00087 $0000 = 0 col1 equ 000088 $0001 = 1 col2 equ 100089 $0002 = 2 col3 equ 200090 $0003 = 3 col4 equ 30009100092 $000F = 15 rowMask equ 2!row1+2!row2+2!row3+2!row400093 $000F = 15 colMask equ 2!col1+2!col2+2!col3+2!col40009400095 ;*****************************************************************************00096 ; RAM Variables: The following RAM locations must be allocated for the00097 ; proper use of the LCD and keypad scanning subroutines.00098 ; lcdTemp1-6 - temp storage locations used by WLCD and RLCD. These00099 ; can be used by the main program in between calls.00100 ; ramSub1-4 - used to create a RAM subroutine, used by TXLCD2 only.00101 ; rowID - used as temp storage for row detection in keypad scanning00102 ; colID - used as temp storage for column detection00103 ; scanMask - used to hold scanning mask during keypad scan00104 ; keyFlag - used as keypad status (bit 0 only)00105 ; keyData - used to store key ID from keypad scan routine00106 ;*****************************************************************************0010700108 0050 section vars, $5000109 0050 lcdTemp1 ds 1 ;\00110 0051 lcdTemp2 ds 1 ; |00111 0052 lcdTemp3 ds 1 ; | These locations are used for temp00112 0053 lcdTemp4 ds 1 ; | storage in the LCD subroutines00113 0054 lcdTemp5 ds 1 ; |00114 0055 lcdTemp6 ds 1 ;/00115 0056 ramSub1 ds 1 ;\00116 0057 ramSub2 ds 1 ; | These locations are used for the00117 0058 ramSub3 ds 1 ; | LCD subroutine TXLCD2 only00118 0059 ramSub4 ds 1 ;/00119 005A rowID ds 1 ;\00120 005B colID ds 1 ; |00121 005C scanMask ds 1 ; | Used for the keypad scan ISR00122 005D keyFlag ds 1 ; |00123 $0000 = 0 keyin equ 0 ; |00124 $0001 = 1 imask equ 1 ; |00125 005E keyData ds 1 ;/0012600127 0180 section code, $1800012800129 0180 9C rsp00130 0181 9B sei00131 0182 125D bset imask,keyFlag ;interrupts masked00132 0184 4F clra00133 0185 C73FDF sta option ;set C16B IRQ to edge only00134 0188 CD0311 jsr lcdIni ;initialize LCD00135 018B CD0230 jsr kbiIni ;initialize keypad00136 018E AE00 ldx #msg&$FF ;send 1st half of lcd message00137 0190 CD024C jsr txlcd100138 0193 A606 lda #msg2/256 ;send 2nd half of lcd message00139 0195 AE07 ldx #msg2&$FF00140 0197 CD0260 jsr txlcd200141 019A A6C0 lda #$C0 ;position LCD to beginning of00142 019C CD0277 jsr wclcd ;line 200143 019F 3F5D clr keyFlag ;clear keypad flag00144 01A1 9A cli ;enable interrupts00145 waitKey00146 01A2 015DFD brclr 0,keyFlag,* ;wait for key press00147 break00148 01A5 3F5D clr keyFlag ;clear keypad flag00149 01A7 B65E lda keyData ;get keypad data00150 01A9 A143 cmp #'C' ;check for "C"00151 01AB 2705 beq clrLine ;if C, clear line 200152 01AD CD027B jsr wdlcd ;else write character00153 01B0 20F0 bra waitKey ;get another key00154 clrLine00155 01B2 AE0F ldx #clearMes&$FF ;clear line 200156 01B4 CD024C jsr txlcd100157 01B7 A6C0 lda #$C0 ;reposition cursor00158 01B9 CD0277 jsr wclcd00159 01BC 20E4 bra waitKey

Application Note 9702

Page 9: Keypad LCD Ds

9

0016000161 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00162 ; **** IRQISR **** ;00163 ; This is the interrupt service routine called whenever any ;00164 ; key on the keypad is pressed. This routine includes a 5ms ;00165 ; debounce delay to avoid erroneous keypresses from switch ;00166 ; bounce. The keypad is then checked. If no key is being ;00167 ; pressed, the routine will simply return. If a key is pressed ;00168 ; this routine will display it's assigned character on the LCD ;00169 ; If the "C" key is pressed, line 2 of the LCD will be cleared ;00170 ; and the cursor returned to the beginning of the line. ;00171 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0017200173 irqIsr00174 01BE CD0216 jsr debounce ;5ms debounce00175 01C1 3F5B clr colID ;clear column ID #00176 01C3 010112 brclr col1,col,scanRow ;check column 1 for key00177 01C6 3C5B inc colID00178 01C8 03010D brclr col2,col,scanRow ;check column 2 for key00179 01CB 3C5B inc colID00180 01CD 050108 brclr col3,col,scanRow ;check column 3 for key00181 01D0 3C5B inc colID00182 01D2 070103 brclr col4,col,scanRow ;check column 4 for key00183 01D5 CC01F6 jmp noKey ;if none, quit ISR00184 scanRow00185 01D8 A603 lda #$03 ;set up row ID00186 01DA B75A sta rowID ;for scan of row 400187 01DC A6F7 lda #~(2!row4) ;set up scan mask00188 01DE B75C sta scanMask00189 rowLoop00190 01E0 B602 lda row ;get keypad row00191 01E2 AA0F ora #rowMask ;make keypad row all "1"s00192 01E4 B45C and scanMask ;mask row00193 01E6 B702 sta row00194 01E8 B601 lda col ;get keypad column00195 01EA AAF0 ora #~colMask ;set non column bits to 100196 01EC 43 coma ;test results (no key = 0)00197 01ED 260A bne gotKey ;if not 0, found key00198 01EF 99 sec ;set carry bit for rotate00199 01F0 365C ror scanMask ;shift row scan bit right00200 01F2 3A5A dec rowID ;decrement to shift next row00201 01F4 2AEA bpl rowLoop ;loop for all 4 rows00202 noKey00203 01F6 AD38 bsr kbiIni ;when done (or no key) re-init00204 01F8 80 rti ;keypad port & return00205 gotKey00206 01F9 B602 lda row00207 01FB A4F0 and #~rowMask ;drive all rows low again00208 01FD B702 sta row ;needed for 8 bit routine00209 01FF B65A lda rowID ;form ofset from rowID:colID00210 0201 48 lsla00211 0202 48 lsla00212 0203 BB5B add colID00213 0205 97 tax ;use rowID:colID as offset00214 0206 D60220 lda keyTable,x ;get key ID from table00215 0209 B75E sta keyData ;store to keyData00216 020B 105D bset 0,keyFlag ;set keypress flag00217 release00218 020D B601 lda col ;wait for key to be released00219 020F AAF0 ora #~colMask00220 0211 43 coma00221 0212 26F9 bne release00222 0214 20E0 bra noKey ;and quit0022300224 debounce ;\00225 0216 A609 lda #$09 ; |00226 debounce1 ; |00227 0218 5F clrx ; |00228 debounce2 ; | ~5ms delay loop00229 0219 5A decx ; | for debouncing keypress00230 021A 26FD bne debounce2 ; |00231 021C 4A deca ; |00232 021D 26F9 bne debounce1 ; |00233 021F 81 rts ;/0023400235 0220 3738392F keyTable db "789/456*123-0.C+" ;keypad lookup table 0224 3435362A 0228 3132332D 022C 302E432B0023600237 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00238 ; **** kbiIni **** ;

Application Note 9702

Page 10: Keypad LCD Ds

10

00239 ; This routine is used to set up the keyboard i/o ports for ;00240 ; the scanning routine. ;00241 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0024200243 kbiIni00244 0230 B605 lda col+4 ;column are inputs00245 0232 A4F0 and #~colMask00246 0234 B705 sta col+400247 0236 B606 lda row+4 ;make rows outputs00248 0238 AA0F ora #rowMask ;and load w/ 0's00249 023A B706 sta row+400250 023C B602 lda row00251 023E A4F0 and #~rowMask00252 0240 B702 sta row00253 0242 81 rts0025400255 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00256 ; **** HEX2ASC **** ;00257 ; This routine converts a hexadecimal number in the low nibble ;00258 ; of ACCA to ASCII for output to the LCD ;00259 ; Calls: None Modified: ACCA ;00260 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0026100262 0243 AB30 HEX2ASC ADD #$3000263 0245 A13A CMP #$3A00264 0247 2B02 BMI SKIP00265 0249 AB07 ADD #$0700266 024B 81 SKIP RTS0026700268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00269 ; **** TXLCD1 **** ;00270 ; This routine takes the ASCII message pointed to by ;00271 ; mesPage:X and displays it on the LCD. This routine ass- ;00272 ; umes the entire message in on memory page mesPage. This ;00273 ; routine is smaller than TXLCD2 because it only increments ;00274 ; one value (X) and only uses 1 RAM location (mesPage). The ;00275 ; first byte of the message pointed to should be the control ;00276 ; code for placement of the message in the LCD. The last ;00277 ; byte of the message MUST be $00. ;00278 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0027900280 TXLCD100281 024C B750 sta lcdTemp1 ;PRESERVE ACCA AND IX00282 024E D60600 lda mespage,x ;get first byte of message00283 0251 AD24 bsr wclcd ;and use it as control (position LCD)00284 mesloop00285 0253 5C incx ;increment pointer into message00286 0254 D60600 lda mespage,x ;get next byte of message00287 0257 2704 beq mesLoopDone ;check for $00 (end of message)00288 0259 AD20 bsr wdlcd ;send byte to LCD as data00289 025B 20F6 bra mesLoop ;loop until end of message00290 mesLoopDone00291 025D B650 lda lcdtemp1 ;restore ACCA00292 025F 81 rts0029300294 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00295 ; **** TXLCD2 **** ;00296 ; This routine takes the ASCII message pointed to by ;00297 ; ACCA:IX and displays it on the LCD. This routine uses ;00298 ; more RAM than TXLCD2 but does have the advantage that the ;00299 ; text message can be anywhere in memory. This routine uses ;00300 ; four bytes of memory (in addition to temp locations) and ;00301 ; is slighly longer than TXLCD1. The first byte of the ;00302 ; message pointed to should be the control code for place- ;00303 ; ment of the message in the LCD. The last byte of the ;00304 ; message MUST be $00. ;00305 ;00306 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0030700308 TXLCD200309 0260 B757 sta ramSub2 ;store ACCA and IX for subroutine jump00310 0262 BF58 stx ramSub300311 0264 BD56 jsr ramSub1 ;use ram subroutine to get byte00312 0266 AD0F bsr wclcd ;position LCD00313 mesloop200314 0268 3C58 inc ramSub3 ;increment message pointer low byte00315 026A 2602 bne noIncHi ;ckeck for overflow, increment high byte of00316 026C 3C57 inc ramSub2 ;necessary00317 noIncHi00318 026E BD56 jsr ramSub1 ;get next byte on message00319 0270 2704 beq mesLoopDone2 ;check for end of message ($00)00320 0272 AD07 bsr wdlcd ;if not end, write data to LCD

Application Note 9702

Page 11: Keypad LCD Ds

11

00321 0274 20F2 bra mesLoop200322 mesLoopDone200323 0276 81 rts0032400325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00326 ; **** WCLCD **** ;00327 ; This routine takes the contents of ACCA and writes it to ;00328 ; the LCD as a conrtol byte. ;00329 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0033000331 0277 1F02 WCLCD BCLR RS,LCDCTL ;Pull RS line low for control00332 0279 2002 BRA WLCD ;byte write0033300334 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00335 ; **** WDLCD **** ;00336 ; This routine takes the contents of ACCA and writes it to ;00337 ; the LCD as a data byte. ;00338 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0033900340 027B 1E02 WDLCD BSET rs,LCDCTL ;Pull RS line high for data byte write0034100342 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00343 ; **** WLCD **** ;00344 ; This subroutine takes the contents of ACCA and writes it ;00345 ; to the LCD. This routine polls the LCD busy flag and ;00346 ; waits until it is low before writing to the LCD. This ;00347 ; This routine does NOT control the RS bit of the LCD, so ;00348 ; the contents of ACCA may be either display data or ;00349 ; control data. This routine has a conditional assembly ;00350 ; flag "4bit" that controls the LCD interface length. If ;00351 ; the 4 bit interface is chosen, data is transfered on the ;00352 ; low nibble of the port. ;00353 ; RAM used: ;00354 ; lcdTemp2 - byte to send ;00355 ; lcdTemp3 - RS preserved for RCLCD call ;00356 ; lcdTemp4 - preserved LCD port data ;00357 ; lcdTemp5 - preserved LCD DDR port data ;00358 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;003590036000361 WLCD00362 027D B751 sta lcdTemp2 ;save data byte in ACCA00363 027F B602 lda lcdctl ;save state of RS bit00364 0281 A480 and #2!rs00365 0283 B752 sta lcdTemp300366 waitLcd00367 0285 AD47 bsr rclcd ;read control bit of the LCD00368 0287 A580 bit #$80 ;to make sure no internal write00369 0289 26FA bne waitLcd ;operation is going on. Loop until00370 ;busy flag is clear00371 028B B652 lda lcdTemp3 ;\00372 028D BA02 ora lcdctl ; |-restore state of RS bit00373 028F B702 sta lcdctl ;/0037400375 0291 B606 lda lcd+400376 0293 B754 sta lcdTemp500377 0295 1D02 bclr rw,lcdctl ;set LCD for write operation00378 0297 1B02 bclr E,lcdctl ;lower E strobe line0037900380 TRUE #if 4bit00381 0299 B602 lda lcd ;get current port data00382 029B A4F0 and #$F0 ;and preserve in RAM00383 029D B753 sta lcdTemp4 ;make IRQ bits high before setting DDRs00384 029F AA0F ora #$0F ;to avoid false interrupts00385 02A1 B702 sta lcd00386 02A3 B606 lda lcd+400387 02A5 AA0F ora #$0F ;make lower nibble of LCD port output00388 02A7 B706 sta lcd+400389 02A9 B651 lda lcdTemp2 ;get data byte stored previously00390 02AB 44 lsra ;shift upper nibble to lower nibble,00391 02AC 44 lsra ;fill rest with 0's.00392 02AD 44 lsra00393 02AE 44 lsra00394 02AF BB53 add lcdTemp4 ;combine with upper nibble of current data00395 FALSE #else00402 #endif0040300404 02B1 B702 sta lcd ;port data and store to LCD i/o port00405 02B3 1A02 bset e,lcdctl ;raise E strobe to LCD00406 02B5 9D NOP ;timing delay for 2us pulse width00407 02B6 1B02 bclr e,lcdctl ;lower E strobe00408

Application Note 9702

Page 12: Keypad LCD Ds

12

00409 TRUE #if 4bit00410 02B8 B651 lda lcdTemp2 ;get LCD data byte for next nibble00411 02BA A40F and #$0F ;transfer00412 02BC BB53 add lcdTemp4 ;combine with current port data00413 02BE B702 sta lcd ;and write it to the LCD port00414 02C0 1A02 bset e,lcdctl ;raise E strobe to LCD00415 02C2 9D nop ;timing delay for 2us pulse width (4MHz)00416 02C3 1B02 bclr e,lcdctl ;lower E strobe00417 #endif0041800419 02C5 B654 lda lcdTemp5 ;\00420 02C7 B706 sta lcd+4 ; |00421 02C9 B653 lda lcdTemp4 ; | restore previous DDR and port data00422 02CB B702 sta lcd ; /00423 02CD 81 RTS0042400425 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00426 ; **** RCLCD **** ;00427 ; This routine reads a byte from the LCD as a control byte ;00428 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0042900430 RCLCD00431 02CE 1F02 bclr rs,lcdctl00432 02D0 2002 bra rlcd0043300434 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00435 ; **** RDLCD **** ;00436 ; This routine reads a byte from the LCD as a control byte ;00437 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0043800439 RDLCD00440 02D2 1E02 bset rs,lcdctl0044100442 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00443 ; **** RLCD **** ;00444 ; This subroutine reads a byte from the LCD module and re- ;00445 ; turns it in ACCA. This routine does not control the RS ;00446 ; bit of the LCD module, this should be done by either ;00447 ; RCLCD or RDLCD. This routine has a conditional assembly ;00448 ; flag "4bit" that controls the LCD interface length. If ;00449 ; the 4 bit interface is chosen, data is transfered on the ;00450 ; low nibble of the port. ;00451 ; RAM used ;00452 ; lcdTemp4 - preserved LCD port data ;00453 ; lcdTemp5 - preserved LCD DDR data ;00454 ; lcdTemp6 - temp store LCD read ;00455 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0045600457 RLCD00458 02D4 9B sei ;mask interrupts (need only if LCD port00459 ;has interruptable pins on it)00460 02D5 B606 lda lcd+4 ;\ preserve LCD DDR port00461 02D7 B754 sta lcdTemp5 ;/00462 02D9 1C02 bset rw,lcdctl ;set LCD for read operation00463 02DB 1B02 bclr E,lcdctl ;lower E00464 02DD B602 lda lcd00465 02DF B753 sta lcdTemp4004660046700468 TRUE #if 4bit00469 02E1 B606 lda lcd+4 ;make lcd port input00470 02E3 A4F0 and #$F0 ;make LCD port input00471 02E5 B706 sta lcd+400472 02E7 1A02 bset E,lcdCtl ;raise strobe for data00473 02E9 9D nop ;delay00474 02EA B602 lda lcd ;get high nibble00475 02EC A40F and #$0F ;mask and shift00476 02EE 1B02 bclr E,lcdCtl ;lower strobe00477 02F0 48 lsla00478 02F1 48 lsla00479 02F2 48 lsla00480 02F3 48 lsla00481 02F4 1A02 bset E,lcdCtl ;first nibble read, get 2nd00482 02F6 B755 sta lcdTemp6 ;store high nibble00483 02F8 B602 lda lcd ;get low nibble00484 02FA A40F and #$0F00485 02FC 1B02 bclr E,lcdCtl ;lower strobe00486 02FE BB55 add lcdTemp6 ;put nibbles together00487 0300 B755 sta lcdTemp600488 FALSE #else00496 #endif00497 0302 B653 lda lcdTemp4

Application Note 9702

Page 13: Keypad LCD Ds

13

00498 0304 B702 sta lcd00499 0306 B654 lda lcdTemp500500 0308 B706 sta lcd+400501 030A B655 lda lcdTemp600502 030C 025D01 brset imask,keyFlag,no_cli00503 030F 9A cli00504 no_cli00505 0310 81 rts0050600507 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;00508 ; **** lcdIni **** ;00509 ; This routine configures the LCD. Parameters are set as ;00510 ; follows: ;00511 ; 1. The cursor is set to increment (move left to right) ;00512 ; 2. The cursor is set to not shift with the incoming data ;00513 ; 3. Turns the display on ;00514 ; 4. Sets data length, number of display lines and font ;00515 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0051600517 lcdIni00518 0311 B750 sta lcdTemp1 ;preserve ACCA0051900520 0313 A6C6 lda #$C6 ;\00521 0315 B756 sta ramSub1 ; |These lines can be deleted if00522 0317 A681 lda #$81 ; |TXLCD2 is not used00523 0319 B759 sta ramSub4 ;/0052400525 031B B606 lda lcdctl+4 ;\00526 031D AAE0 ora #(2!rs+2!e+2!rw) ; |00527 031F B706 sta lcdctl+4 ; | Set RS, E and RW port bits00528 0321 B602 lda lcdctl ; | bits to output, clear all bits00529 0323 A41F and #~(2!rs+2!e+2!rw) ; |00530 0325 B702 sta lcdctl ;/00531 TRUE #if 4bit00532 0327 A62F lda #$2F ;set data interface (4 bit)00533 FALSE #else00535 #endif00536 0329 CD0277 jsr wclcd00537 032C A606 lda #$06 ;set display to increment00538 032E CD0277 jsr wclcd00539 0331 A60F lda #$0F ;turn display on00540 0333 CD0277 jsr WCLCD00541 0336 A601 lda #01 ;clear DDRAM and reset address pointer00542 0338 CD0277 jsr wclcd00543 033B B650 lda lcdTemp1 ;restore ACCA00544 033D 81 rts005450054600547 0600 section mesPage, $600 ;message page00548 0600 80507265 msg db $80,"Press",$00 0604 73730000549 0607 85206120 msg2 db $85," a key",$00 060B 6B65790000550 060F C0202020 clearMes db $C0," ",$00 0613 20202020 0617 20202020 061B 20202020 061F 2020000055100552 3FF4 section vectors, $3FF400553 3FF4 0180 dw code00554 3FF6 0180 dw code00555 3FF8 0180 dw code00556 3FFA 01BE dw irqIsr00557 3FFC 0180 dw code00558 3FFE 0180 dw code

Application Note 9702