Wednesday, March 29, 2006

PIC: EXAMPLE 15

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.
Example 15 - Using LCD display

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