You are on page 1of 33

AN587

Interfacing PICmicro MCUs to an LCD Module


Author:
Code:

Mark Palmer
Mark Palmer/Scott Fink
Microchip Technology Inc.

TABLE 1:
Control
SIgnal

Function

Causes data/control state to be latched


Rising Edge =
Latches control state
(RS and R_W)
Falling Edge =
Latches data

INTRODUCTION
This application note interfaces a midrange PICmicro
device to a Hitachi LM032L LCD character display
module, with a two line by twenty character display. LCD
modules are useful for displaying text information from a
system. In large volume applications, the use of custom
LCD displays becomes economical. The routines provided should be a good starting point for users whose
applications implement a custom LCD. This source code
should be compatible with the PIC16C5X devices, after
modifications for the special function register
initialization, but has not been verified on those devices.

OPERATION
The Hitachi LM032L LCD character display module can
operate in one of two modes. The first (and default)
mode is the 4-bit data interface mode. The second is
the 8-bit data interface mode. When operating in 4-bit
mode, two transfers per character / command are
required. 8-bit mode, though easier to implement (less
program memory) requires four additional I/O lines.
The use of 8-bit mode is strictly a program memory size
vs. I/O trade-off. The three most common data interfaces from the microcontroller are:
1.
2.
3.

An 8-bit interface.
A 4-bit interface, with data transfers on the high
nibble of the port.
A 4-bit interface, with data transfers on the low
nibble of the port.

CONTROL SIGNAL FUNCTIONS

RS

Register Select Control


1 = LCD in data mode
0 = LCD in command mode

R_W

Read / Write control


1 = LCD to write data
0 = LCD to read data

A single source file, with conditional assembly is used


to generate each of these three options. This requires
two flags. The flags and their results are shown in
Table 2.

TABLE 2:

CONDITIONAL ASSEMBLY
FLAGS

Flags
Four_bit Data_HI

Result

4-bit mode. Data


transferred on the low
nibble of the port.

4-bit mode. Data


transferred on the high
nibble of the port.

8-bit mode.

The LCD module also has three control signals, Enable


(E), Read/Write (R_W), and Register Select (RS). The
function of each control signal is shown in Table 1.

1997 Microchip Technology Inc.

DS00587B-page 1

AN587
Figure 1, Figure 2, and Figure 3 show the block diagrams for the three different data interfaces. The
LCD_CNTL and LCD_DATA lines are user definable to

FIGURE 1:

their port assignment. This is accomplished with


EQUate statements in the source code. See Appendices B, C, and D.

8-BIT DATA INTERFACE


LM032L
VCC (2)

PIC16CXXX

R1 (10 k)
LCD_CNTL

Port

RS (4)
R_W (5)
E (6)

VO (3)
R2 (330)
VSS (1)

LCD_DATA
Port<7:0>

FIGURE 2:

DB7 (14) : DB0 (7)

4-BIT MODE; DATA TRANSFERRED ON THE HIGH NIBBLE OF THE PORT


LM032L
VCC (2)

PIC16CXXX

R1 (10 k)
LCD_CNTL

Port

RS (4)
R_W (5)
E (6)

VO (3)
R2 (330)
VSS (1)

LCD_DATA
Port<7:4>

FIGURE 3:

DB7 (14) : DB4 (11)


DB3 (10) : DB0 (7)

4-BIT MODE; DATA TRANSFERRED ON THE LOW NIBBLE OF THE PORT


LM032L
VCC (2)

PIC16CXXX

R1 (10 k)
LCD_CNTL

Port

RS (4)
R_W (5)
E (6)

VO (3)
R2 (330)
VSS (1)

LCD_DATA
Port<3:0>

DS00587B-page 2

DB7 (14) : DB4 (11)


DB3 (10) : DB0 (7)

1997 Microchip Technology Inc.

AN587
LCDs (drivers) are slow devices when compared to
microcontrollers. Care must be taken from having
communication occur too quickly. The software will
need to control communicaton speed and timing to
ensure the slow LCD and fast microcontroller can stay
synchronized. The timing requirements of the LM032L
are shown in Appendix A. We recommend that the
complete specifications of the LM032L be acquired
from Hitachi or a Hitachi distributor. The literature numbers are CE-E613Q and M24T013 for a LM032L display driver.

command needs to specify the data transfer width (4-or


8-bit). Then a delay of 4.6 ms must be executed before
the LCD module can be initialized. Some of the LCD
module commands are:

When the module powers up, the default data transfer


mode is 8-bit. The initialization sequence only requires
commands that are 4-bit in length. The last initialization

The initialization flow for the module is shown in


Figure 4.

FIGURE 4:

1 or 2 lines of characters
Display on /off
Clear display
Increment / do not increment character address
pointer after each character
Load character address pointer

INITIALIZATION FLOW FOR LCD MODULE

1) When interface is 8 bits long:

1) When interface is 4 bits long:

Power ON

Power ON

Wait more than 1.5 ms


after VDD rises to 4.5V

Wait more than 1.5 ms


after VDD rises to 4.5V

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0
0
0
1
1
x
x
x
x

RS R/W DB7 DB6 DB5 DB4


0
0
0
0
1
1

BF cannot be checked before this instruction


Function set (interface is 8 bits long)

Wait more than 4.1 ms

Wait more than 4.1 ms

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0
0
0
1
1
x
x
x
x

RS R/W DB7 DB6 DB5 DB4


0
0
0
0
1
1

BF cannot be checked before this instruction


Function set (interface is 8 bits long)

Wait more than 100 s

Wait more than 100 s

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0
0
0
1
1
x
x
x
x

RS R/W DB7 DB6 DB5 DB4


0
0
0
0
1
1

RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0


0 0
0
0
1
1
N
F
x
x
0

I/D

Initialization ends

1997 Microchip Technology Inc.

RS R/W DB7 DB6 DB5 DB4


0
0
0
0
1
0
0
0
0
0
1
0
0
0
N
F
x
x
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
1 I/D S

BF cannot be checked before this instruction


Function set (interface is 8 bits long)

Function set (set interface to be 4 bits long).


Interface is 8 bits long.
Function Set
Display OFF
Display ON
Entry Mode Set

Interface is 8/4 bits long.


Specify the number of
display lines and character
font.
The number of display lines
and character font cannot
be changed afterwards.

Initialization ends

DS00587B-page 3

AN587
After initialization, each character address is
individually addressable. Figure 5 shows the structure
of the command to specify the character address.

FIGURE 5:

The program example implemented here uses the


character auto increment feature. This automatically
increments the character address pointer after each
character is written to the display.

CHARACTER ADDRESS
COMMAND FORMAT

DB7

DB0

Figure 6 shows the display data positions supported by


the display driver as well as the characters actually
displayed by the module (the non-shaded addresses).

CONCLUSION

LINE

DD ADDR
The Hitachi LM032L character display module is well
suited for displaying information. The selection of 4-bit
or 8-bit data transfer mode is strictly a program memory
size vs. I/O resource trade-off. The supplied code is
easily used in any of three common data interfaces.
The source is easily modifiable to a designers specific
application needs. Other display modules/drivers
maybe implemented with the appropriate modifications. Table 3 shows the resource requirements for the
three subroutines SEND_CHAR, SEND_COMMAND, and
BUSY_CHECK in the various data interface modes.

Address(1)
Line number

0 = line1
1 = line2

Set DD RAM Address


Note 1: Not all addresses are usable.

The Hitachi Display Drive (HD44780A) has 80 bytes of


RAM. The LM032L modules only use 40 bytes of the
available RAM (2 x 20 characters). It is possible to use the
remaining RAM locations for storage of other information.

FIGURE 6:

DISPLAY DRIVER (DD) RAM LOCATIONS

digit

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

33 34 35 36 37 38 39 40

Display position

line-1

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14

20 21 22 23 24 25 26 27

DD RAM address
(Hexadecimal)

line-2

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

60 61 62 63 64 65 66 67

Note:

TABLE 3:

Shaded locations are not displayed on the LM032L display module.

RESOURCE REQUIREMENTS
Program
Memory

Data
Memory

8-bit

32

PICDEM-2(1)

4-bit, Data transferred on the high nibble


of the port.

53

PICDEM-2(1)

4-bit, Data transferred on the high nibble


of the port.

53

Low-Power Real-Time Clock Board


(AN582)

Mode

Verified On

Note 1: Jumper J6 must be removed.

DS00587B-page 4

1997 Microchip Technology Inc.

AN587
APPENDIX A: LM032L TIMING REQUIREMENTS
TABLE A-1:

TIMING CHARACTERISTICS

Parameter #

Symbol

TCYC

PWEH

TER, TEF

Enable rise / fall time

TAS

RS, R/W set-up time

TDDR

Data delay time

TDSU

TH

FIGURE A-1:

Characteristics

Min.

Typ.

Max.

Unit

Enable cycle time

1.0

Enable pulse width

450

25

140

320

Data setup time

195

Hold time

20

DATA WRITE INTERFACE TIMING

RS

2.2V
0.6V

2.2V
0.6V

4
R/W

0.6V

0.6V
7

0.6V

2.2V

2.2V

0.6V

0.6V

6
Valid
Data

2.2V
0.6V

DB7:DB0

2.2V
0.6V

FIGURE A-2:

DATA READ INTERFACE TIMING


RS

2.2V
0.6V

2.2V
0.6V
4

R/W

7
2.2V

2.2V
7

0.6V

2.2V

3
DB7:DB0

2.2V

0.6V

0.6V

5
2.2V
0.4V

Valid
Data

2.2V
0.4V

Note:

Refer to Hitachi documentation for the most current timing specifications.

1997 Microchip Technology Inc.

DS00587B-page 5

AN587
TABLE A-2:
Pin No.

LM032L PIN CONNECTION


Symbol

Level

Function

VSS

0V

Ground

VDD

+5V

Power Supply(+)
Ground

VO

RS

H/L

L: Instruction Code Input


H: Data Input

R/W

H/L

H: Data Read (LCD moduleMPU)


L: Data Write (LCD moduleMPU)

H,HL

DB0

H/L

DB1

H/L

DB2

H/L

10

DB3

H/L

Data Bus Line

11

DB4

H/L

Note (1), (2)

12

DB5

H/L

13

DB6

H/L

14

DB7

H/L

Enable Signal

In the HD44780, the data can be sent in either two 4-bit operations or one 8-bit operation, This flexibility allows an
interface to both 4- and 8-bit MPUs.
Note 1: When interface data is 4-bits long, data is transferred using only 4 lines of DB7:DB4 (DB3:DB0 are not
used). Data transfer between the HD44780 and the MPU completes when 4-bits of data is transferred twice.
Data of the higher order 4 bits (contents of DB7:DB4 when interface data is 8-bits long) is transferred first
and then lower order 4 bits (contents of DB3:DB0 when interface data is 8-bits long).
2: When interface data is 8-bits long, data is transferred using 8 data lines of DB7:DB0.

DS00587B-page 6

1997 Microchip Technology Inc.

1997 Microchip Technology Inc.

00000006
00000086

00000001
00000000

00000000
00000001

0000009F

LOC OBJECT CODE


VALUE

LM032L.ASM

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00001
00002
00238
00016
00017
00018
00019
00020
00021
00022
00069
00023
00024
00025
00026
00027
00028
00029
00030
00031

PAGE

Program = LM032L.ASM
Revision Date:
5-10-94
1-22-97

Compatibility with MPASMWIN 1.40

This program interfaces to a Hitachi (LM032L) 2 line by 20 character display


module. The program assembles for either 4-bit or 8-bit data interface, depending
on the value of the 4bit flag. LCD_DATA is the port which supplies the data to
the LM032L, while LCD_CNTL is the port that has the control lines ( E, RS, RW ).
In 4-bit mode the data is transfer on the high nibble of the port ( PORT<7:4> ).

9:43:02

0
1

9F

include <lm032l.h>
list

EQU
EQU

EQU

;
Four_bit
EQU TRUE
Data_HI
EQU FALSE
;
;
if ( Four_bit && !Data_HI )
;
LCD_DATA
EQU PORTB
LCD_DATA_TRIS
EQU TRISB

FALSE
TRUE

ADCON1

; Selects 4- or 8-bit data transfers


; If 4-bit transfers, Hi or Low nibble of PORT

include <p16c64.inc>
LIST
; P16C64.INC Standard Header File, Version 1.01 Microchip Technology, Inc.
LIST

;
;
;
;
;
;
;
;
;
;
;
;

4-7-1997

LIST P=16C64
ERRORLEVEL -302

LINE SOURCE TEXT

MPASM 01.40.01 Intermediate

APPENDIX B: 8-BIT DATA INTERFACE LISTING

Please check the Microchip BBS for the latest version of the source code. Microchips Worldwide Web Address: www.microchip.com; Bulletin Board Support:
MCHIPBBS using CompuServe (CompuServe membership not required).

AN587

DS00587B-page 7

DS00587B-page 8

0008

0004
0004
0004
0005
0006
0007

1283
1407
1007
2804

0000
0000 2808

00000030

00000000
00000001
00000002

00000005

00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
else
;
LCD_DATA
EQU PORTD
LCD_DATA_TRIS
EQU TRISD
;
endif
;
LCD_CNTL
EQU PORTA
;
;
;
; LCD Display Commands and Control Signal names.
;
if ( Four_bit && !Data_HI )
;
E
EQU 0
; LCD Enable control line
RW
EQU 1
; LCD Read/Write control line
RS
EQU 2
; LCD Register Select control line
;
else
;
E
EQU 3
; LCD Enable control line
RW
EQU 2
; LCD Read/Write control line
RS
EQU 1
; LCD Register Select control line
;
endif
;
;
TEMP1
EQU 0x030
;
org
RESET_V
; RESET vector location
RESET
GOTO
START
;
;
; This is the Periperal Interrupt routine. Should NOT get here
;
page
org
ISR_V
; Interrupt vector location
PER_INT_V
ERROR1
BCF STATUS, RP0
; Bank 0
BSF PORTC, 0
BCF PORTC, 0
GOTO ERROR1
;
;
;
START
; POWER_ON Reset (Beginning of program)

AN587

1997 Microchip Technology Inc.

1997 Microchip Technology Inc.

1283
0185
0186
0187
0188
0189
1010

1683
0185
30F0
0086
0187
1407
0188
0189
140C
1781
1283

000F
0010
0011
0012
0013
0014
0015

0016
0017
0018
0019
001A
001B
001C
001D
001E
001F
0020

0022 3002

0022

0021 0185

0183
018B
018C
1683
3000
0081
018C

0008
0009
000A
000B
000C
000D
000E

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
; Bank 1
; The LCD module does not like to work w/ weak pull-ups
;
; Disable all peripheral interrupts

; Do initialization (Bank 0)

BSF
CLRF
MOVLW
MOVWF
CLRF
BSF
CLRF
CLRF
BSF
BSF
BCF

BCF
CLRF
CLRF
CLRF
CLRF
CLRF
BCF

MOVLW
MOVWF

STATUS, RP0
TRISA
0xF0
TRISB
TRISC
TRISC, T1OSO
TRISD
TRISE
PIE1, TMR1IE
OPTION_REG,NOT_RBPU
STATUS, RP0

STATUS, RP0
PORTA
PORTB
PORTC
PORTD
PORTE
T1CON, TMR1ON

0xFF
ADCON1

DISPLAY_INIT
if ( Four_bit && !Data_HI )
MOVLW
0x02
endif
;
if ( Four_bit && Data_HI )
MOVLW
0x020

RB7 - 4 inputs, RB3 - 0 outputs


RC Port are outputs
RC0 needs to be input for the oscillator to function
RD Port are outputs
RE Port are outputs
Enable TMR1 Interrupt
Disable PORTB pull-ups
Select Bank 0

Select Bank 1
RA5 - 0 outputs

; Command for 4-bit interface high nibble

; Command for 4-bit interface low nibble

; ALL PORT output should output Low.

;
;
;
;
;
;
;
;
;
;
;

; Timer 1 is NOT incrementing

; Bank 0
; ALL PORT output should output Low.

;
; Port A is Digital.

If using device with A/D, these two instructions are required.

STATUS
INTCON
PIR1
STATUS, RP0
0x00
OPTION_REG
PIE1

page
;
; Initialize the LCD Display Module
;
CLRF
LCD_CNTL

;***
;***
;***
;
;
;
;

CLRF
CLRF
CLRF
BSF
MOVLW
MOVWF
CLRF

AN587

DS00587B-page 9

DS00587B-page 10

2829

3006
00B3
01B4
0BB4
2829
0BB3

0031 3008

002E 0086
002F 1405
0030 1005

002D 3002

002D

0026
0027
0028
0029
002A
002B
002C
002C

0023 0086
0024 1405
0025 1005

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
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
MOVWF
BSF
BCF

LCD_DATA
LCD_CNTL, E
LCD_CNTL, E

if ( !Four_bit )
MOVLW
0x038
endif

endif

;
;
;

; Command for 8-bit interface

;
; This routine takes the calculated times that the delay loop needs to
; be executed, based on the LCD_INIT_DELAY EQUate that includes the
; frequency of operation. These uses registers before they are needed to
; store the time.
;
LCD_DELAY
MOVLW
LCD_INIT_DELAY
;
MOVWF
MSD
; Use MSD and LSD Registers to Initialize LCD
CLRF
LSD
;
LOOP2
DECFSZ LSD, F
; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO
LOOP2
;
DECFSZ MSD, F
;
END_LCD_DELAY
GOTO
LOOP2
;
;
; Command sequence for 2 lines of 5x7 characters
;
CMD_SEQ
;
if ( Four_bit )
if ( !Data_HI )
MOVLW
0X02
; 4-bit low nibble xfer
else
MOVLW
0X020
; 4-bit high nibble xfer
endif
;
else
; 8-bit mode
MOVLW
0X038
endif
;
MOVWF
LCD_DATA
; This code for both 4-bit and 8-bit modes
BSF
LCD_CNTL, E
;
BCF
LCD_CNTL, E
;
;
if ( Four_bit )
; This code for only 4-bit mode (2nd xfer)
if ( !Data_HI )
MOVLW
0x08
; 4-bit low nibble xfer
else

AN587

1997 Microchip Technology Inc.

1997 Microchip Technology Inc.

304D
2063
3069
2063
3063
2063
3072
2063
306F
2063
3063
2063
3068
2063
3069
2063
3070
2063

003D
003E
003F
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
004A
004B
004C
004D
004E

0051 3000
0052
0052 00B0

004F 30C0
0050 2072

300C
2072
3001
2072
3006
2072
3080
2072

0035
0036
0037
0038
0039
003A
003B
003C

0032 0086
0033 1405
0034 1005

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
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E

0x080
;
;
;

; 4-bit high nibble xfer

dispmsg
movwf

movlw

movlw
call

TEMP1

B11000000
SEND_CMD

;TEMP1 holds start of message address

;Demonstration of the use of a table to output a message


;Table address of start of message

;Address DDRam first character, second line

;
; Busy Flag should be valid after this point
;
MOVLW
DISP_ON
;
CALL
SEND_CMD
;
MOVLW
CLR_DISP
;
CALL
SEND_CMD
;
MOVLW
ENTRY_INC
;
CALL
SEND_CMD
;
MOVLW
DD_RAM_ADDR
;
CALL
SEND_CMD
;
;
page
;
;Send a message the hard way
movlw
M
call
SEND_CHAR
movlw
i
call
SEND_CHAR
movlw
c
call
SEND_CHAR
movlw
r
call
SEND_CHAR
movlw
o
call
SEND_CHAR
movlw
c
call
SEND_CHAR
movlw
h
call
SEND_CHAR
movlw
i
call
SEND_CHAR
movlw
p
call
SEND_CHAR

MOVLW
endif
MOVWF
BSF
BCF
endif

AN587

DS00587B-page 11

285B

300C
2072
3001
2072
3006
2072
0008

005C
005C
005D
005E
005F
0060
0061
0062

2099
39FF
1903
285B
2063
0830
3E01
2852

0053
0054
0055
0056
0057
0058
0059
005A
005B
005B
005B

00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
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

DS00587B-page 12
MOVLW
CALL
MOVLW
CALL
MOVLW
CALL
RETURN

goto

DISP_ON
SEND_CMD
CLR_DISP
SEND_CMD
ENTRY_INC
SEND_CMD

loop

Table
0FFh
STATUS,Z
out
SEND_CHAR
TEMP1,w
1
dispmsg

;
;
;
;
;
;

Display On, Cursor On


Send This command to the Display Module
Clear the Display
Send This command to the Display Module
Set Entry Mode Inc., No shift
Send This command to the Display Module

;Stay here forever

;Display character
;Point to next character

;Check if at end of message (zero


;returned at end)

page
;
;*******************************************************************
;* The LCD Module Subroutines
*
;*******************************************************************
;
if ( Four_bit )
; 4-bit Data transfers?
;
if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;*SendChar - Sends character to LCD
*
;*This routine splits the character into the upper and lower
*
;*nibbles and sends them to the LCD, upper nibble first.
*
;*******************************************************************
;
SEND_CHAR
MOVWF
CHAR
;Character to be sent is in W
CALL
BUSY_CHECK
;Wait for LCD to be ready
MOVF
CHAR, w
ANDLW
0xF0
;Get upper nibble
MOVWF
LCD_DATA
;Send data to LCD
BCF
LCD_CNTL, RW
;Set LCD to read
BSF
LCD_CNTL, RS
;Set LCD to data mode
BSF
LCD_CNTL, E
;toggle E for LCD

;
;
INIT_DISPLAY

out
loop

call
andlw
btfsc
goto
call
movf
addlw
goto

AN587

1997 Microchip Technology Inc.

0063
0063
0064
0065
0066
0067
0068
0069
006A
006B
006C
006D
006E
006F
0070
0071

00B6
2081
0E36
390F
0086
1085
1505
1405
1005
0836
390F
0086
1405
1005
0008

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

LCD_CNTL, E
CHAR, w
0xF0
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E
;Get lower nibble
;Send data to LCD
;toggle E for LCD

else
; 4-bit transfers on the low nibble of the PORT
;
;*******************************************************************
;* SEND_CHAR - Sends character to LCD
*
;* This routine splits the character into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;* The data is transmitted on the PORT<3:0> pins
*
;*******************************************************************
;
SEND_CHAR
MOVWF
CHAR
; Character to be sent is in W
CALL
BUSY_CHECK
; Wait for LCD to be ready
SWAPF
CHAR, W
ANDLW
0x0F
; Get upper nibble
MOVWF
LCD_DATA
; Send data to LCD
BCF
LCD_CNTL, RW
; Set LCD to read
BSF
LCD_CNTL, RS
; Set LCD to data mode
BSF
LCD_CNTL, E
; toggle E for LCD
BCF
LCD_CNTL, E
MOVF
CHAR, W
ANDLW
0x0F
; Get lower nibble
MOVWF
LCD_DATA
; Send data to LCD
BSF
LCD_CNTL, E
; toggle E for LCD
BCF
LCD_CNTL, E
RETURN
;
endif
else
;
;*****************************************************************
;* SEND_CHAR - Sends character contained in register W to LCD
*
;* This routine sends the entire character to the PORT
*
;* The data is transmitted on the PORT<7:0> pins
*
;*****************************************************************
;
SEND_CHAR
MOVWF
CHAR
; Character to be sent is in W
CALL
BUSY_CHECK
; Wait for LCD to be ready
MOVF
CHAR, w

BCF
SWAPF
ANDLW
MOVWF
BSF
BCF
RETURN

AN587

1997 Microchip Technology Inc.

DS00587B-page 13

00314
00315
00316
00317
00318
00319
00320
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

DS00587B-page 14
endif

LCD_DATA
LCD_CNTL,
LCD_CNTL,
LCD_CNTL,
LCD_CNTL,
RW
RS
E
E

;
;
;
;

Send data to LCD


Set LCD in read mode
Set LCD in data mode
toggle E for LCD

SEND_CMD

else

MOVWF
CALL
MOVF
ANDLW
MOVWF
BCF
BCF
BSF
BCF
SWAPF
ANDLW
MOVWF
BSF
BCF
RETURN

Get upper nibble


Send data to LCD
Set LCD to read
Set LCD to command mode
toggle E for LCD

; Get lower nibble


; Send data to LCD
; toggle E for LCD

;
;
;
;
;

; Character to be sent is in W
; Wait for LCD to be ready

; 4-bit transfers on the low nibble of the PORT

CHAR
BUSY_CHECK
CHAR,w
0xF0
LCD_DATA
LCD_CNTL,RW
LCD_CNTL,RS
LCD_CNTL,E
LCD_CNTL,E
CHAR,w
0xF0
LCD_DATA
LCD_CNTL,E
LCD_CNTL,E

page
;
;*******************************************************************
;* SendCmd - Sends command to LCD
*
;* This routine splits the command into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;* The data is transmitted on the PORT<3:0> pins
*
;*******************************************************************
;
if ( Four_bit )
; 4-bit Data transfers?
;
if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;* SEND_CMD - Sends command to LCD
*
;* This routine splits the command into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;*******************************************************************

MOVWF
BCF
BSF
BSF
BCF
RETURN

AN587

1997 Microchip Technology Inc.

0072
0072
0073
0074
0075
0076
0077
0078
0079
007A
007B
007C
007D
007E
007F
0080

00B6
2081
0E36
390F
0086
1085
1105
1405
1005
0836
390F
0086
1405
1005
0008

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
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407

1997 Microchip Technology Inc.


else

endif

MOVWF
CALL
SWAPF
ANDLW
MOVWF
BCF
BCF
BSF
BCF
MOVF
ANDLW
MOVWF
BSF
BCF
RETURN

CHAR
BUSY_CHECK
CHAR, W
0x0F
LCD_DATA
LCD_CNTL, RW
LCD_CNTL, RS
LCD_CNTL, E
LCD_CNTL, E
CHAR, W
0x0F
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E
Get upper nibble
Send data to LCD
Set LCD to read
Set LCD to command mode
toggle E for LCD

; Get lower nibble


; Send data to LCD
; toggle E for LCD

;
;
;
;
;

; Character to be sent is in W
; Wait for LCD to be ready

if ( Four_bit )

page

endif

MOVWF
CALL
MOVF
MOVWF
BCF
BCF
BSF
BCF
RETURN

CHAR
BUSY_CHECK
CHAR, w
LCD_DATA
LCD_CNTL, RW
LCD_CNTL, RS
LCD_CNTL, E
LCD_CNTL, E

Send data to LCD


Set LCD in read mode
Set LCD in command mode
toggle E for LCD

; 4-bit Data transfers?

;
;
;
;

; Command to be sent is in W
; Wait for LCD to be ready

if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;* This routine checks the busy flag, returns when not busy
*

SEND_CMD

;
;**************************************************************
;* SEND_CND - Sends command contained in register W to LCD
*
;* This routine sends the entire character to the PORT
*
;* The data is transmitted on the PORT<7:0> pins
*
;**************************************************************

SEND_CMD

AN587

DS00587B-page 15

0081
0081
0082
0083
0084
0085
0086
0087
0088

1683
30FF
0086
1283
1105
1485
1405
1005

00408
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

;* Affects:
*
;*
TEMP - Returned with busy/address
*
;*******************************************************************
;
BUSY_CHECK
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0xFF
; Set Port_D for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Select Register Bank0
BCF
LCD_CNTL, RS
; Set LCD for Command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low
MOVF
LCD_DATA, W
; Read upper nibble busy flag, DDRam address
ANDLW
0xF0
; Mask out lower nibble
MOVWF
TEMP
BSF
LCD_CNTL, E
; Toggle E to get lower nibble
BCF
LCD_CNTL, E
SWAPF
LCD_DATA, w
; Read lower nibble busy flag, DDRam address
ANDLW
0x0F
; Mask out upper nibble
IORWF
TEMP
; Combine nibbles
BTFSC
TEMP, 7
; Check busy flag, high = busy
GOTO
BUSY_CHECK
; If busy, check again
BCF
LCD_CNTL, RW
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0x0F
MOVWF
LCD_DATA_TRIS
; Set Port_D for output
BCF
STATUS, RP0
; Select Register Bank0
RETURN
;
else
; 4-bit transfers on the low nibble of the PORT
;
;*******************************************************************
;* This routine checks the busy flag, returns when not busy
*
;* Affects:
*
;*
TEMP - Returned with busy/address
*
;*******************************************************************
;
BUSY_CHECK
BSF
STATUS, RP0
; Bank 1
MOVLW
0xFF
; Set PortB for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Bank 0
BCF
LCD_CNTL, RS
; Set LCD for Command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low

AN587

DS00587B-page 16

1997 Microchip Technology Inc.

0089
008A
008B
008C
008D
008E
008F
0090
0091
0092
0093
0094
0095
0096
0097
0098

0E06
39F0
00B5
1405
1005
0806
390F
04B5
1BB5
2881
1085
1683
30F0
0086
1283
0008

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
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501

1997 Microchip Technology Inc.


else

endif

LCD_DATA, W
0xF0
TEMP
LCD_CNTL, E
LCD_CNTL, E
LCD_DATA, W
0x0F
TEMP, F
TEMP, 7
BUSY_CHECK
LCD_CNTL, RW
STATUS, RP0
0xF0
LCD_DATA_TRIS
STATUS, RP0
Read lower nibble busy flag, DDRam address
Mask out upper nibble
Combine nibbles
Check busy flag, high = busy
If busy, check again

; Bank 1
;
; RB7 - 4 = inputs, RB3 - 0 = output
; Bank 0

;
;
;
;
;

; Read upper nibble busy flag, DDRam address


; Mask out lower nibble
;
; Toggle E to get lower nibble

;
;**************************************************************
;* This routine checks the busy flag, returns when not busy
*
;* Affects:
*
;*
TEMP - Returned with busy/address
*
;**************************************************************
;
BUSY_CHECK
BSF
STATUS,RP0
; Select Register Bank1
MOVLW
0xFF
; Set port_D for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Select Register Bank0
BCF
LCD_CNTL, RS
; Set LCD for command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low
MOVF
LCD_DATA, w
; Read busy flag, DDram address
MOVWF
TEMP
BTFSC
TEMP, 7
; Check busy flag, high=busy
GOTO
BUSY_CHECK
BCF
LCD_CNTL, RW
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0x00
MOVWF
LCD_DATA_TRIS
; Set port_D for output
BCF
STATUS, RP0
; Select Register Bank0
RETURN
;
endif

SWAPF
ANDLW
MOVWF
BSF
BCF
MOVF
ANDLW
IORWF
BTFSC
GOTO
BCF
BSF
MOVLW
MOVWF
BCF
RETURN

AN587

DS00587B-page 17

DS00587B-page 18

Program Memory Words Used:


Program Memory Words Free:

172
1876

All other memory blocks unused.

0000 : X---XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX


0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX- ----------------

00502
page
00503 ;
0099
00504 Table
0099 0782
00505
addwf
PCL, F
;Jump to char pointed to in W reg
009A 344D
00506
retlw
M
009B 3469
00507
retlw
i
009C 3463
00508
retlw
c
009D 3472
00509
retlw
r
009E 346F
00510
retlw
o
009F 3463
00511
retlw
c
00A0 3468
00512
retlw
h
00A1 3469
00513
retlw
i
00A2 3470
00514
retlw
p
00A3 3420
00515
retlw

00A4 3454
00516
retlw
T
00A5 3465
00517
retlw
e
00A6 3463
00518
retlw
c
00A7 3468
00519
retlw
h
00A8 346E
00520
retlw
n
00A9 346F
00521
retlw
o
00AA 346C
00522
retlw
l
00AB 346F
00523
retlw
o
00AC 3467
00524
retlw
g
00AD 3479
00525
retlw
y
00AE
00526 Table_End
00AE 3400
00527
retlw
0
00528 ;
00529
if ( (Table & 0x0FF) >= (Table_End & 0x0FF) )
00530
MESSG
Warning - User Definded: Table Table crosses page boundry in computed jump
00531
endif
00532 ;
00533
00534
00535
00536
end
MEMORY USAGE MAP (X = Used, - = Unused)

AN587

1997 Microchip Technology Inc.

Errors
:
Warnings :
Messages :

0
0 reported,
0 reported,
0 suppressed
12 suppressed

AN587

1997 Microchip Technology Inc.

DS00587B-page 19

DS00587B-page 20

00000000
00000001

00000000
00000001

0000009F

LOC OBJECT CODE


VALUE

LM032L.ASM

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00001
00002
00238
00016
00017
00018
00019
00020
00021
00022
00069
00023
00024
00025
00026
00027
00028
00029
00030
00031

PAGE

Program = LM032L.ASM
Revision Date:
5-10-94
1-22-97

include <lm032l.h>
list

EQU
EQU

EQU
0
1

9F

;
Four_bit
EQU
FALSE
Data_HI
EQU
TRUE
;
;
if ( Four_bit && !Data_HI )
;
LCD_DATA
EQU
PORTB
LCD_DATA_TRIS
EQU
TRISB

FALSE
TRUE

ADCON1

; Selects 4- or 8-bit data transfers


; If 4-bit transfers, Hi or Low nibble of PORT

Microchip Technology, Inc.

Compatibility with MPASMWIN 1.40

This program interfaces to a Hitachi (LM032L) 2 line by 20 character display


module. The program assembles for either 4-bit or 8-bit data interface, depending
on the value of the 4bit flag. LCD_DATA is the port which supplies the data to
the LM032L, while LCD_CNTL is the port that has the control lines ( E, RS, RW ).
In 4-bit mode the data is transfer on the high nibble of the port ( PORT<7:4> ).

9:50:32

include <p16c64.inc>
LIST
; P16C64.INC Standard Header File, Version 1.01
LIST

;
;
;
;
;
;
;
;
;
;
;
;

4-7-1997

LIST P=16C64
ERRORLEVEL -302

LINE SOURCE TEXT

MPASM 01.40.01 Intermediate

APPENDIX C: 4-BIT DATA INTERFACE, HIGH NIBBLE LISTING

Please check the Microchip BBS for the latest version of the source code. Microchips Worldwide Web Address: www.microchip.com; Bulletin Board Support:
MCHIPBBS using CompuServe (CompuServe membership not required).

AN587

1997 Microchip Technology Inc.

1997 Microchip Technology Inc.

0008

0004
0004
0004
0005
0006
0007

1283
1407
1007
2804

0000
0000 2808

00000030

00000003
00000002
00000001

00000005

00000008
00000088

00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
else
;
LCD_DATA
EQU
PORTD
LCD_DATA_TRIS
EQU
TRISD
;
endif
;
LCD_CNTL
EQU
PORTA
;
;
;
; LCD Display Commands and Control Signal names.
;
if ( Four_bit && !Data_HI )
;
E
EQU
0
; LCD Enable control line
RW
EQU
1
; LCD Read/Write control line
RS
EQU
2
; LCD Register Select control line
;
else
;
E
EQU
3
; LCD Enable control line
RW
EQU
2
; LCD Read/Write control line
RS
EQU
1
; LCD Register Select control line
;
endif
;
;
TEMP1
EQU
0x030
;
org
RESET_V
; RESET vector location
RESET
GOTO
START
;
;
; This is the Periperal Interrupt routine. Should NOT get here
;
page
org
ISR_V
; Interrupt vector location
PER_INT_V
ERROR1
BCF
STATUS, RP0
; Bank 0
BSF
PORTC, 0
BCF
PORTC, 0
GOTO
ERROR1
;
;
;
START
; POWER_ON Reset (Beginning of program)

AN587

DS00587B-page 21

DS00587B-page 22

1283
0185
0186
0187
0188
0189
1010

1683
0185
30F0
0086
0187
1407
0188
0189
140C
1781
1283

000F
0010
0011
0012
0013
0014
0015

0016
0017
0018
0019
001A
001B
001C
001D
001E
001F
0020

0022

0021 0185

0183
018B
018C
1683
3000
0081
018C

0008
0009
000A
000B
000C
000D
000E

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
; Bank 1
; The LCD module does not like to work w/ weak pull-ups
;
; Disable all peripheral interrupts

; Do initialization (Bank 0)

BSF
CLRF
MOVLW
MOVWF
CLRF
BSF
CLRF
CLRF
BSF
BSF
BCF

BCF
CLRF
CLRF
CLRF
CLRF
CLRF
BCF

MOVLW
MOVWF

STATUS, RP0
TRISA
0xF0
TRISB
TRISC
TRISC, T1OSO
TRISD
TRISE
PIE1, TMR1IE
OPTION_REG,NOT_RBPU
STATUS, RP0

STATUS, RP0
PORTA
PORTB
PORTC
PORTD
PORTE
T1CON, TMR1ON

0xFF
ADCON1

DISPLAY_INIT
if ( Four_bit && !Data_HI )
MOVLW
0x02
endif
;
if ( Four_bit && Data_HI )
MOVLW
0x020

RB7 - 4 inputs, RB3 - 0 outputs


RC Port are outputs
RC0 needs to be input for the oscillator to function
RD Port are outputs
RE Port are outputs
Enable TMR1 Interrupt
Disable PORTB pull-ups
Select Bank 0

Select Bank 1
RA5 - 0 outputs

; Command for 4-bit interface high nibble

; Command for 4-bit interface low nibble

; ALL PORT output should output Low.

;
;
;
;
;
;
;
;
;
;
;

; Timer 1 is NOT incrementing

; Bank 0
; ALL PORT output should output Low.

;
; Port A is Digital.

If using device with A/D, these two instructions are required.

STATUS
INTCON
PIR1
STATUS, RP0
0x00
OPTION_REG
PIE1

page
;
; Initilize the LCD Display Module
;
CLRF
LCD_CNTL

;***
;***
;***
;
;
;
;

CLRF
CLRF
CLRF
BSF
MOVLW
MOVWF
CLRF

AN587

1997 Microchip Technology Inc.

1997 Microchip Technology Inc.

2829

3006
00B3
01B4
0BB4
2829
0BB3

002E 0088
002F 1585
0030 1185

002D 3038

002D

0026
0027
0028
0029
002A
002B
002C
002C

0023 0088
0024 1585
0025 1185

0022 3038

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
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
MOVWF
BSF
BCF

LCD_DATA
LCD_CNTL, E
LCD_CNTL, E

if ( !Four_bit )
MOVLW
0x038
endif

endif

;
;
;

; Command for 8-bit interface

;
; This routine takes the calculated times that the delay loop needs to
; be executed, based on the LCD_INIT_DELAY EQUate that includes the
; frequency of operation. These use registers before they are needed to
; store the time.
;
LCD_DELAY
MOVLW
LCD_INIT_DELAY
;
MOVWF
MSD
; Use MSD and LSD Registers to Initilize LCD
CLRF
LSD
;
LOOP2
DECFSZ LSD, F
; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO
LOOP2
;
DECFSZ MSD, F
;
END_LCD_DELAY
GOTO
LOOP2
;
;
; Command sequence for 2 lines of 5x7 characters
;
CMD_SEQ
;
if ( Four_bit )
if ( !Data_HI )
MOVLW
0X02
; 4-bit low nibble xfer
else
MOVLW
0X020
; 4-bit high nibble xfer
endif
;
else
; 8-bit mode
MOVLW
0X038
endif
;
MOVWF
LCD_DATA
; This code for both 4-bit and 8-bit modes
BSF
LCD_CNTL, E
;
BCF
LCD_CNTL, E
;
;
if ( Four_bit )
; This code for only 4-bit mode (2nd xfer)
if ( !Data_HI )
MOVLW
0x08
; 4-bit low nibble xfer
else

AN587

DS00587B-page 23

DS00587B-page 24

304D
205F
3069
205F
3063
205F
3072
205F
306F
205F
3063
205F
3068
205F
3069
205F
3070
205F

0039
003A
003B
003C
003D
003E
003F
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
004A

004D 3000
004E
004E 00B0

004B 30C0
004C 2068

300C
2068
3001
2068
3006
2068
3080
2068

0031
0032
0033
0034
0035
0036
0037
0038

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

; 4-bit high nibble xfer


;
;
;

0x080
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E

dispmsg
movwf

movlw

movlw
call

TEMP1

B11000000
SEND_CMD

;TEMP1 holds start of message address

;Demonstration of the use of a table to output a message


;Table address of start of message

;Address DDRam first character, second line

;
; Busy Flag should be valid after this point
;
MOVLW
DISP_ON
;
CALL
SEND_CMD
;
MOVLW
CLR_DISP
;
CALL
SEND_CMD
;
MOVLW
ENTRY_INC
;
CALL
SEND_CMD
;
MOVLW
DD_RAM_ADDR
;
CALL
SEND_CMD
;
;
page
;
;Send a message the hard way
movlw
M
call
SEND_CHAR
movlw
i
call
SEND_CHAR
movlw
c
call
SEND_CHAR
movlw
r
call
SEND_CHAR
movlw
o
call
SEND_CHAR
movlw
c
call
SEND_CHAR
movlw
h
call
SEND_CHAR
movlw
i
call
SEND_CHAR
movlw
p
call
SEND_CHAR

MOVLW
endif
MOVWF
BSF
BCF
endif

AN587

1997 Microchip Technology Inc.

2857

300C
2068
3001
2068
3006
2068
0008

0058
0058
0059
005A
005B
005C
005D
005E

2083
39FF
1903
2857
205F
0830
3E01
284E

004F
0050
0051
0052
0053
0054
0055
0056
0057
0057
0057

00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
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

1997 Microchip Technology Inc.


MOVLW
CALL
MOVLW
CALL
MOVLW
CALL
RETURN

goto

DISP_ON
SEND_CMD
CLR_DISP
SEND_CMD
ENTRY_INC
SEND_CMD

loop

Table
0FFh
STATUS,Z
out
SEND_CHAR
TEMP1,w
1
dispmsg

;
;
;
;
;
;

Display On, Cursor On


Send This command to the Display Module
Clear the Display
Send This command to the Display Module
Set Entry Mode Inc., No shift
Send This command to the Display Module

;Stay here forever

;Display character
;Point to next character

;Check if at end of message (zero


;returned at end)

page
;
;*******************************************************************
;* The LCD Module Subroutines
*
;*******************************************************************
;
if ( Four_bit )
; 4-bit Data transfers?
;
if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;*SendChar - Sends character to LCD
*
;*This routine splits the character into the upper and lower
*
;*nibbles and sends them to the LCD, upper nibble first.
*
;*******************************************************************
;
SEND_CHAR
MOVWF
CHAR
;Character to be sent is in W
CALL
BUSY_CHECK
;Wait for LCD to be ready
MOVF
CHAR, w
ANDLW
0xF0
;Get upper nibble
MOVWF
LCD_DATA
;Send data to LCD
BCF
LCD_CNTL, RW
;Set LCD to read
BSF
LCD_CNTL, RS
;Set LCD to data mode
BSF
LCD_CNTL, E
;toggle E for LCD

;
;
INIT_DISPLAY

out
loop

call
andlw
btfsc
goto
call
movf
addlw
goto

AN587

DS00587B-page 25

005F
005F 00B6
0060 2071
0061 0836

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

DS00587B-page 26
LCD_CNTL, E
CHAR, w
0xF0
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E
; Get lower nibble
; Send data to LCD
; toggle E for LCD

else
; 4-bit transfers on the low nibble of the PORT
;
;*******************************************************************
;* SEND_CHAR - Sends character to LCD
*
;* This routine splits the character into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;* The data is transmitted on the PORT<3:0> pins
*
;*******************************************************************
;
SEND_CHAR
MOVWF
CHAR
; Character to be sent is in W
CALL
BUSY_CHECK
; Wait for LCD to be ready
SWAPF
CHAR, W
ANDLW
0x0F
; Get upper nibble
MOVWF
LCD_DATA
; Send data to LCD
BCF
LCD_CNTL, RW
; Set LCD to read
BSF
LCD_CNTL, RS
; Set LCD to data mode
BSF
LCD_CNTL, E
; toggle E for LCD
BCF
LCD_CNTL, E
MOVF
CHAR, W
ANDLW
0x0F
; Get lower nibble
MOVWF
LCD_DATA
; Send data to LCD
BSF
LCD_CNTL, E
; toggle E for LCD
BCF
LCD_CNTL, E
RETURN
;
endif
else
;
;*****************************************************************
;* SEND_CHAR - Sends character contained in register W to LCD
*
;* This routine sends the entire character to the PORT
*
;* The data is transmitted on the PORT<7:0> pins
*
;*****************************************************************
;
SEND_CHAR
MOVWF
CHAR
; Character to be sent is in W
CALL
BUSY_CHECK
; Wait for LCD to be ready
MOVF
CHAR, w

BCF
SWAPF
ANDLW
MOVWF
BSF
BCF
RETURN

AN587

1997 Microchip Technology Inc.

0062
0063
0064
0065
0066
0067

0088
1105
1485
1585
1185
0008

00314
00315
00316
00317
00318
00319
00320
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
endif

LCD_DATA
LCD_CNTL,
LCD_CNTL,
LCD_CNTL,
LCD_CNTL,
RW
RS
E
E

;
;
;
;

Send data to LCD


Set LCD in read mode
Set LCD in data mode
toggle E for LCD

1997 Microchip Technology Inc.


;

SEND_CMD

else

MOVWF
CALL
MOVF
ANDLW
MOVWF
BCF
BCF
BSF
BCF
SWAPF
ANDLW
MOVWF
BSF
BCF
RETURN

CHAR
BUSY_CHECK
CHAR,w
0xF0
LCD_DATA
LCD_CNTL,RW
LCD_CNTL,RS
LCD_CNTL,E
LCD_CNTL,E
CHAR,w
0xF0
LCD_DATA
LCD_CNTL,E
LCD_CNTL,E

Get upper nibble


Send data to LCD
Set LCD to read
Set LCD to command mode
toggle E for LCD

; 4-bit transfers on the low nibble of the PORT

; Get lower nibble


; Send data to LCD
; toggle E for LCD

;
;
;
;
;

; Character to be sent is in W
; Wait for LCD to be ready

page
;
;*******************************************************************
;* SendCmd - Sends command to LCD
*
;* This routine splits the command into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;* The data is transmitted on the PORT<3:0> pins
*
;*******************************************************************
;
if ( Four_bit )
; 4-bit Data transfers?
;
if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;* SEND_CMD - Sends command to LCD
*
;* This routine splits the command into the upper and lower
*
;* nibbles and sends them to the LCD, upper nibble first.
*
;*******************************************************************

MOVWF
BCF
BSF
BSF
BCF
RETURN

AN587

DS00587B-page 27

0068
0068
0069
006A
006B
006C
006D
006E
006F
0070

00B6
2071
0836
0088
1105
1085
1585
1185
0008

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
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407

DS00587B-page 28
else

endif

MOVWF
CALL
SWAPF
ANDLW
MOVWF
BCF
BCF
BSF
BCF
MOVF
ANDLW
MOVWF
BSF
BCF
RETURN

CHAR
BUSY_CHECK
CHAR, W
0x0F
LCD_DATA
LCD_CNTL, RW
LCD_CNTL, RS
LCD_CNTL, E
LCD_CNTL, E
CHAR, W
0x0F
LCD_DATA
LCD_CNTL, E
LCD_CNTL, E
Get upper nibble
Send data to LCD
Set LCD to read
Set LCD to command mode
toggle E for LCD

; Get lower nibble


; Send data to LCD
; toggle E for LCD

;
;
;
;
;

; Character to be sent is in W
; Wait for LCD to be ready

if ( Four_bit )

page

endif

MOVWF
CALL
MOVF
MOVWF
BCF
BCF
BSF
BCF
RETURN

CHAR
BUSY_CHECK
CHAR, w
LCD_DATA
LCD_CNTL, RW
LCD_CNTL, RS
LCD_CNTL, E
LCD_CNTL, E

Send data to LCD


Set LCD in read mode
Set LCD in command mode
toggle E for LCD

; 4-bit Data transfers?

;
;
;
;

; Command to be sent is in W
; Wait for LCD to be ready

if ( Data_HI )
; 4-bit transfers on the high nibble of the PORT
;
;*******************************************************************
;* This routine checks the busy flag, returns when not busy
*

SEND_CMD

;
;**************************************************************
;* SEND_CND - Sends command contained in register W to LCD
*
;* This routine sends the entire character to the PORT
*
;* The data is transmitted on the PORT<7:0> pins
*
;**************************************************************

SEND_CMD

AN587

1997 Microchip Technology Inc.

00408
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

;* Affects:
*
;*
TEMP - Returned with busy/address
*
;*******************************************************************
;
BUSY_CHECK
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0xFF
; Set Port_D for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Select Register Bank0
BCF
LCD_CNTL, RS
; Set LCD for Command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low
MOVF
LCD_DATA, W
; Read upper nibble busy flag, DDRam address
ANDLW
0xF0
; Mask out lower nibble
MOVWF
TEMP
BSF
LCD_CNTL, E
; Toggle E to get lower nibble
BCF
LCD_CNTL, E
SWAPF
LCD_DATA, w
; Read lower nibble busy flag, DDRam address
ANDLW
0x0F
; Mask out upper nibble
IORWF
TEMP, F
; Combine nibbles
BTFSC
TEMP, 7
; Check busy flag, high = busy
GOTO
BUSY_CHECK
; If busy, check again
BCF
LCD_CNTL, RW
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0x0F
MOVWF
LCD_DATA_TRIS
; Set Port_D for output
BCF
STATUS, RP0
; Select Register Bank0
RETURN
;
else
; 4-bit transfers on the low nibble of the PORT
;
;*******************************************************************
;* This routine checks the busy flag, returns when not busy
*
;* Affects:
*
;*
TEMP - Returned with busy/address
*
;*******************************************************************
;
BUSY_CHECK
BSF
STATUS, RP0
; Bank 1
MOVLW
0xFF
; Set PortB for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Bank 0
BCF
LCD_CNTL, RS
; Set LCD for Command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low

AN587

1997 Microchip Technology Inc.

DS00587B-page 29

0071
0071
0072
0073
0074
0075
0076
0077
0078
0079
007A
007B
007C
007D
007E
007F
0080
0081
0082

1683
30FF
0088
1283
1085
1505
1585
1185
0808
00B5
1BB5
2871
1105
1683
3000
0088
1283
0008

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
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501

DS00587B-page 30
else

endif

LCD_DATA, W
0xF0
TEMP
LCD_CNTL, E
LCD_CNTL, E
LCD_DATA, W
0x0F
TEMP, F
TEMP, 7
BUSY_CHECK
LCD_CNTL, RW
STATUS, RP0
0xF0
LCD_DATA_TRIS
STATUS, RP0
Read lower nibble busy flag, DDRam address
Mask out upper nibble
Combine nibbles
Check busy flag, high = busy
If busy, check again

; Bank 1
;
; RB7 - 4 = inputs, RB3 - 0 = output
; Bank 0

;
;
;
;
;

; Read upper nibble busy flag, DDRam address


; Mask out lower nibble
;
; Toggle E to get lower nibble

;
;**************************************************************
;* This routine checks the busy flag, returns when not busy
*
;* Affects:
*
;*
TEMP - Returned with busy/address
*
;**************************************************************
;
BUSY_CHECK
BSF
STATUS,RP0
; Select Register Bank1
MOVLW
0xFF
; Set port_D for input
MOVWF
LCD_DATA_TRIS
BCF
STATUS, RP0
; Select Register Bank0
BCF
LCD_CNTL, RS
; Set LCD for command mode
BSF
LCD_CNTL, RW
; Setup to read busy flag
BSF
LCD_CNTL, E
; Set E high
BCF
LCD_CNTL, E
; Set E low
MOVF
LCD_DATA, w
; Read busy flag, DDram address
MOVWF
TEMP
BTFSC
TEMP, 7
; Check busy flag, high=busy
GOTO
BUSY_CHECK
BCF
LCD_CNTL, RW
BSF
STATUS, RP0
; Select Register Bank1
MOVLW
0x00
MOVWF
LCD_DATA_TRIS
; Set port_D for output
BCF
STATUS, RP0
; Select Register Bank0
RETURN
;
endif

SWAPF
ANDLW
MOVWF
BSF
BCF
MOVF
ANDLW
IORWF
BTFSC
GOTO
BCF
BSF
MOVLW
MOVWF
BCF
RETURN

AN587

1997 Microchip Technology Inc.

0083
0083
0084
0085
0086
0087
0088
0089
008A
008B
008C
008D
008E
008F
0090
0091
0092
0093
0094
0095
0096
0097
0098
0098

1997 Microchip Technology Inc.

3400

0782
344D
3469
3463
3472
346F
3463
3468
3469
3470
3420
3454
3465
3463
3468
346E
346F
346C
346F
3467
3479

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
00534
00535
00536
;

retlw

addwf
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
0

PCL, F
M
i
c
r
o
c
h
i
p

T
e
c
h
n
o
l
o
g
y

; Jump to char pointed to in W reg

end

if ( (Table & 0x0FF) >= (Table_End & 0x0FF) )


MESSG
Warning - User Definded: Table Table crosses page boundry in computed jump
endif

Table_End

page
;
Table

AN587

DS00587B-page 31

- = Unused)

DS00587B-page 32

Errors
:
Warnings :
Messages :

0
0 reported,
0 reported,

Program Memory Words Used:


Program Memory Words Free:

0 suppressed
12 suppressed

150
1898

All other memory blocks unused.

0000 : X---XXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX


0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0080 : XXXXXXXXXXXXXXXX XXXXXXXXX------- ---------------- ----------------

MEMORY USAGE MAP (X = Used,

AN587

1997 Microchip Technology Inc.

WORLDWIDE SALES AND SERVICE


AMERICAS

ASIA/PACIFIC

Korea

Corporate Office

Australia

2355 West Chandler Blvd.


Chandler, AZ 85224-6199
Tel: 480-792-7200
Fax: 480-792-7277
Technical Support: 480-792-7627
Web Address: http://www.microchip.com

Suite 22, 41 Rawson Street


Epping 2121, NSW
Australia
Tel: 61-2-9868-6733
Fax: 61-2-9868-6755

168-1, Youngbo Bldg. 3 Floor


Samsung-Dong, Kangnam-Ku
Seoul, Korea 135-882
Tel: 82-2-554-7200 Fax: 82-2-558-5932 or
82-2-558-5934

Atlanta

Unit 706B
Wan Tai Bei Hai Bldg.
No. 6 Chaoyangmen Bei Str.
Beijing, 100027, China
Tel: 86-10-85282100
Fax: 86-10-85282104

3780 Mansell Road, Suite 130


Alpharetta, GA 30022
Tel: 770-640-0034
Fax: 770-640-0307

Boston
2 Lan Drive, Suite 120
Westford, MA 01886
Tel: 978-692-3848
Fax: 978-692-3821

Chicago
333 Pierce Road, Suite 180
Itasca, IL 60143
Tel: 630-285-0071
Fax: 630-285-0075

Dallas
4570 Westgrove Drive, Suite 160
Addison, TX 75001
Tel: 972-818-7423
Fax: 972-818-2924

Detroit
Tri-Atria Office Building
32255 Northwestern Highway, Suite 190
Farmington Hills, MI 48334
Tel: 248-538-2250
Fax: 248-538-2260

Kokomo
2767 S. Albright Road
Kokomo, IN 46902
Tel: 765-864-8360
Fax: 765-864-8387

Los Angeles

China - Beijing

China - Chengdu
Rm. 2401-2402, 24th Floor,
Ming Xing Financial Tower
No. 88 TIDU Street
Chengdu 610016, China
Tel: 86-28-86766200
Fax: 86-28-86766599

China - Fuzhou
Unit 28F, World Trade Plaza
No. 71 Wusi Road
Fuzhou 350001, China
Tel: 86-591-7503506
Fax: 86-591-7503521

China - Hong Kong SAR


Unit 901-6, Tower 2, Metroplaza
223 Hing Fong Road
Kwai Fong, N.T., Hong Kong
Tel: 852-2401-1200
Fax: 852-2401-3431

China - Shanghai
Room 701, Bldg. B
Far East International Plaza
No. 317 Xian Xia Road
Shanghai, 200051
Tel: 86-21-6275-5700
Fax: 86-21-6275-5060

China - Shenzhen

18201 Von Karman, Suite 1090


Irvine, CA 92612
Tel: 949-263-1888
Fax: 949-263-1338

Rm. 1812, 18/F, Building A, United Plaza


No. 5022 Binhe Road, Futian District
Shenzhen 518033, China
Tel: 86-755-82901380
Fax: 86-755-8295-1393

Phoenix

China - Shunde

2355 West Chandler Blvd.


Chandler, AZ 85224-6199
Tel: 480-792-7966
Fax: 480-792-4338

Room 401, Hongjian Building


No. 2 Fengxiangnan Road, Ronggui Town
Shunde City, Guangdong 528303, China
Tel: 86-765-8395507 Fax: 86-765-8395571

San Jose

China - Qingdao

1300 Terra Bella Avenue


Mountain View, CA 94043
Tel: 650-215-1444

Rm. B505A, Fullhope Plaza,


No. 12 Hong Kong Central Rd.
Qingdao 266071, China
Tel: 86-532-5027355 Fax: 86-532-5027205

Toronto
6285 Northam Drive, Suite 108
Mississauga, Ontario L4V 1X5, Canada
Tel: 905-673-0699
Fax: 905-673-6509

India
Divyasree Chambers
1 Floor, Wing A (A3/A4)
No. 11, OShaugnessey Road
Bangalore, 560 025, India
Tel: 91-80-2290061 Fax: 91-80-2290062

Japan
Benex S-1 6F
3-18-20, Shinyokohama
Kohoku-Ku, Yokohama-shi
Kanagawa, 222-0033, Japan
Tel: 81-45-471- 6166 Fax: 81-45-471-6122

DS00587B-page 33

Singapore
200 Middle Road
#07-02 Prime Centre
Singapore, 188980
Tel: 65-6334-8870 Fax: 65-6334-8850

Taiwan
Kaohsiung Branch
30F - 1 No. 8
Min Chuan 2nd Road
Kaohsiung 806, Taiwan
Tel: 886-7-536-4818
Fax: 886-7-536-4803

Taiwan
Taiwan Branch
11F-3, No. 207
Tung Hua North Road
Taipei, 105, Taiwan
Tel: 886-2-2717-7175 Fax: 886-2-2545-0139

EUROPE
Austria
Durisolstrasse 2
A-4600 Wels
Austria
Tel: 43-7242-2244-399
Fax: 43-7242-2244-393

Denmark
Regus Business Centre
Lautrup hoj 1-3
Ballerup DK-2750 Denmark
Tel: 45-4420-9895 Fax: 45-4420-9910

France
Parc dActivite du Moulin de Massy
43 Rue du Saule Trapu
Batiment A - ler Etage
91300 Massy, France
Tel: 33-1-69-53-63-20
Fax: 33-1-69-30-90-79

Germany
Steinheilstrasse 10
D-85737 Ismaning, Germany
Tel: 49-89-627-144-0
Fax: 49-89-627-144-44

Italy
Via Quasimodo, 12
20025 Legnano (MI)
Milan, Italy
Tel: 39-0331-742611
Fax: 39-0331-466781

Netherlands
P. A. De Biesbosch 14
NL-5152 SC Drunen, Netherlands
Tel: 31-416-690399
Fax: 31-416-690340

United Kingdom
505 Eskdale Road
Winnersh Triangle
Wokingham
Berkshire, England RG41 5TU
Tel: 44-118-921-5869
Fax: 44-118-921-5820
11/24/03

1997 Microchip Technology Inc.

You might also like