Friday, December 30, 2016

Assembly code of LCD display using 16F877A

; Assembly code of LCD display using 16F877A
; you may need to adjust the delay time to make it works.

;***** Declaration and configuration of the microcontroller *****
        PROCESSOR 16f877A
        #include "p16f877A.inc"
        __CONFIG _HS_OSC &_CP_OFF & _WDT_OFF & _LVP_OFF


;*********************** 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
  counter
  counter1
  counter2
       counter3
  counter4
  counter5
  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  
       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, "LCD Project" ; Write text from the begin
                                           ; ning of the first line
       lcdtext     2, "Good Luck"  ; Write text from the beginning of
                                   ; the second line
       ;pausems     .2000           ; 2 sec. delay
       call Delay
  lcdcmd      0x01            ; Instruction to clear LCD
       lcdtext 1, "Temperature" ; 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
       call Delay
  goto        Loop

Delay
       movlw       .40         ; approx cal of delay = 40x255x255x3 x instruction cycle time.
       movwf       counter    
loop    
       movlw       .255        
       movwf       counter2    
loop2
       movlw       .255        
       movwf       counter1    
loop1
       decfsz      counter1    
       goto        loop1        
     
       decfsz      counter2    
       goto        loop2        
     
       decfsz      counter    
       goto        loop        
     
       return                        

;**********************************************************************
       end                      
;**********************************************************************


;**********  digbyte.inc********************
;Macro "digbyte":
digbyte MACRO arg0
       LOCAL       Exit0
       LOCAL       Exit1
       LOCAL       Exit2
     
       clrf        Dig0
       clrf        Dig1
       clrf        Dig2        
       clrf        Dig3
     
       movf        arg0, w
       movwf       Digtemp
       movlw       .100
Exit2
       incf        Dig2, f
       subwf       Digtemp, f
       btfsc       STATUS, C
       goto        Exit2
       decf        Dig2, f
       addwf       Digtemp, f
Exit1
       movlw       .10          
       incf        Dig1, f
       subwf       Digtemp, f
       btfsc       STATUS, C
       goto        Exit1
       decf        Dig1, f
       addwf       Digtemp, f
Exit0
       movf        Digtemp, w
       movwf       Dig0
       ENDM


;***************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
       call   Delay40ms
 
; 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
       call   Delay40ms
       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 16="" compiling="" conditional="" nbsp="" p="" program="" repeat="" 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

Delay40ms
       movlw .40
       movwf    counter5
       decfsz   counter5
       call     Delay1ms
       return

Delay1ms    
       movlw       .20           ; approximate delay calculation = 20x250x3 insctruction cyle time.
       movwf       counter4    
loop4
       movlw       .250        
       movwf       counter3    
loop3
       decfsz      counter3    
       goto        loop3        
     
       decfsz      counter4    
       goto        loop4        
     
       return



1 comment: