EXAMPLE 15
Using LCD display
This example illustrates the use of the alphanumeric LCD display. The program itself is very simple because macros are used (usually the effort of creating Macros pays off in the end).Two messages written on two lines change on display. The second message is intended to display the current temperature. Since no sensor is installed, the measurement is not really carried out, the variable "temp" appears on the display instead of the measured temperature.
In reality, the current temperature or some other measured value would be displayed.

Source Code
;*********************** Header ***********************************
; DEFINING VARIABLES IN PROGRAM
CBLOCK 0x20 ; Block of variables starts at address 20h
HIcnt ; Belongs to macro "pausems"
LOcnt
LOOPcnt
LCDbuf ; Belongs to functions "LCDxxx"
LCDtemp
LCDportBuf ; LCD Port Buffer
Digtemp ; Belongs to macro "digbyte"
Dig0
Dig1
Dig2
Dig3
temp
ENDC ; End of block
LCDport EQU PORTB ; LCD is on PORTB (4 data lines on RB0-RB3)
RS EQU 4 ; RS line connected to RB4
EN EQU 5 ; EN line connected to RB5
;**********************************************************************
ORG 0x0000 ; Reset vector address
nop
goto main ; Go to beginning of the program (label "main")
;**********************************************************************
include "LCD.inc"
include "digbyte.inc"
include "pause.inc"
;**********************************************************************
main
banksel ANSEL ; Selects bank containing ANSEL
clrf ANSEL ; All pins are digital
clrf ANSELH
bcf STATUS,RP0 ; Bank0 active only
bcf STATUS,RP1
movlw .23
movwf temp ; Move arbitrary value to variable
; is to be displayed on LCD
lcdinit ; LCD initialization
Loop
lcdcmd 0x01 ; Instruction to clear LCD
lcdtext 1, "mikroelektronika" ; Write text from the begin
; ning of the first line
lcdtext 2, "Beograd" ; Write text from the beginning of
; the second line
pausems .2000 ; 2 sec. delay
lcdcmd 0x01 ; Instruction to clear LCD
lcdtext 1, "Temperatura1" ; Write text from the begin
; ning of the first line
lcdtext 2, "temp=" ; Write text from the beginning of
; the second line
lcdbyte temp ; Write variable (dec.)
lcdtext 0, " C" ; Write text after cursor
pausems .2000 ; 2 sec. delay
goto Loop
;**********************************************************************
end ; End of program
LCD.inc
;**********************************************************************
; Initialization must be done by using macro lcdinit before access
; ing LCD
;**********************************************************************
lcdinit MACRO
bcf STATUS, RP0 ; Bank0
bcf STATUS, RP1
clrf LCDportBuf
movf LCDportBuf, w
movwf LCDport
bsf STATUS, RP0 ; Bank1
bcf STATUS, RP1
clrf TRISB ; LCDport with output LCD
bcf STATUS, RP0 ; Bank0
bcf STATUS, RP1
; Function set (4-bit mode change)
movlw b'00100000'
movwf LCDbuf
swapf LCDbuf, w
movwf LCDportBuf
bcf LCDportBuf, RS
movf LCDportBuf, w
movwf LCDport
bsf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
bcf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
call Delay1ms ; 1 ms delay
; Function set (display mode set)
lcdcmd b'00101100'
call Delay1ms ; 1 ms delay
; Display ON/OFF Control
lcdcmd b'00001100'
call Delay1ms ; 1 ms delay
; Entry Mode Set
lcdcmd b'00000110'
call Delay1ms ; 1 ms delay
; Display Clear
lcdcmd b'00000001'
pausems .40 ; 40 ms delay
; Function set (4-bit mode change)
movlw b'00100000'
movwf LCDbuf
swapf LCDbuf, w
movwf LCDportBuf
bcf LCDportBuf, RS
movf LCDportBuf, w
movwf LCDport
bsf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
bcf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
call Delay1ms ; 1 ms delay
; Function set (display mode set)
lcdcmd b'00101100'
call Delay1ms ; 1 ms delay
; Display ON/OFF Control
lcdcmd b'00001100'
call Delay1ms ; 1 ms delay
; Entry Mode Set
lcdcmd b'00000110'
call Delay1ms ; 1 ms delay
; Display Clear
lcdcmd b'00000001'
pausems .40 ; 40 ms delay
ENDM
;**********************************************************************
; lcdcmd sends command to LCD (see the table on the previous page)
; lcdclr is the same as lcdcmd 0x01
;**********************************************************************
lcdcmd MACRO LCDcommand ; Send command to LCD
movlw LCDcommand
call LCDcomd
ENDM
LCDcomd
movwf LCDbuf
bcf LCDportBuf, RS
movf LCDportBuf, w
movwf LCDport
goto LCDwr
LCDdata
movwf LCDbuf
bsf LCDportBuf, RS
movf LCDportBuf, w
movwf LCDport
goto LCDwr
LCDwr
swapf LCDbuf, w
call SendW
movf LCDbuf, w
call SendW
return
SendW
andlw 0x0F
movwf LCDtemp
movlw 0xF0
andwf LCDportBuf, f
movf LCDtemp, w
iorwf LCDportBuf, f
movf LCDportBuf, w
movwf LCDport
call Delay1ms
bsf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
bcf LCDportBuf, EN
movf LCDportBuf, w
movwf LCDport
call Delay1ms
return
;**********************************************************************
; lcdtext writes text containing 16 characters which represents a
; macro argument. The first argument select selects the line in which
; text writing is to start. If select is 0, text writing starts from
; cursor current position.
;**********************************************************************
lcdtext MACRO select, text ; This macro writes text from cursor
; current position. Text is specified
; in argument consisting of 16 charac
; ters
local Message
local Start
local Exit
local i=0
goto Start
Message DT text ; Create lookup table from arguments
DT 0
Start
IF (select == 1)
lcdcmd b'10000000'
ELSE
IF (select == 2)
lcdcmd b'11000000'
ENDIF
ENDIF
WHILE (i<16) ; Repeat conditional program compiling 16 times
call Message+i ; Read lookup table and place value in W
addlw 0
bz Exit ; until 0 is read
call LCDdata ; Call routine displaying W on LCD
i=i+1
ENDW
Exit
ENDM
;**********************************************************************
; This macro writes value in size of 1 byte on LCD
; excluding leading zeros
;**********************************************************************
lcdbyte MACRO arg0
digbyte arg0 ; A hundred is in Dig2,
; A ten is in Dig1 and one in Dig0
movf Dig2, w
addlw 0x30
call LCDdata
movf Dig1, w ; If digit is 0 move cursor
addlw 0x30
call LCDdata
movf Dig0, w ; If digit is 0 move cursor
addlw 0x30
call LCDdata
ENDM
;**********************************************************************
; 1ms Delay
Delay1ms:
movlw .200
movwf LOOPcnt
Delay10us:
nop ;1us
nop ;1us
nop ;1us
nop ;1us
nop ;1us
nop ;1us
nop ;1us
decfsz LOOPcnt, f ;1us
goto Delay10us ;2us
return