;===================================================================================
;                FOUR BIT INTERFACING LCD DRIVER FOR 8051 or DERIVATED
;                    >>>
;-----------------------------------------------------------------------------------
; This utility is used for cotrolled LCD-Display with 4BIT interfacing
; The Port I/O  is bit port of microcontroller. The configurations is :
; PORT:    Bit  7   6   5   4   3   2   1   0
; FOR :         U   U   U   U   D7  D6  D5  D4
;
; Note:
; - U is used for RS_LCD, RW_LCD and E_LCD pin or another bit output port.
; - 4 bit lcd data bus (for 4 bit interfacing is D7..D4) must be connected to
;   bit 0..3 of I/O port (bidirectional, because this interfacing can write/read)
;
; RS_LCD, RW_LCD, E_LCD can connected to Bit 4 to 7.
; Please use pseudo opcode BIT to refer the bit that you like
; The PORT_LCD label is the LCD bit Port address of microcontroller
;
; This driver can intefaced to C language Keil-C51 uVision2 with "extern" prototype
; or Assembly.
;------------------------------------------+----------------------------------------
; EXTERN PROTOTYPE                         | FUNCTION
;------------------------------------------+----------------------------------------
; void init_lcd(void);                     | Initialaze LCD,LCD ON,NOBLINK,NOCURSOR
; void clr_lcd(void);                      | Clear LCD and Home Cursor
; void locate_lcd(char row, char col);     | Locate cursor (begin 0)
; void csrhome_lcd(void);                  | Locate cursor to (0,0), char no clear
; void on_lcd(void)                        | Lcd ON no blink, no cursor
; void off_lcd(void);                      | Lcd off, character no display, no clear
; void wrchar_lcd(char character);         | Display character to current cursor
; void wrstr_lcd(char *buff_char);         | Display string depend generic pointer
;                                          | *buff_char, in idata, data, xdata,
;                                          | cdata, and pdata. Automatic pointer.
; void csrmode_lcd(char cur, char blink);  | Set cursor mode
;===================================================================================
; THIS PROGRAM IS TESTED WITH C51 Keil uVision2 Version 6.20
; THE RESULT WORK FINE,  NO ANY TROUBLE
; THE ALL ROUTINE USED REGISTER BANK 0 FOR PARAMETERS PASSING, IF ANOTHER BANK USED
; WILL NOT WORK FINE.
;===================================================================================
               NAME Utility_LCD_4Bit_Port


Utility_LCD_4Bit_Port_SEG   SEGMENT CODE

;==========================================================================
; The following is Control pin configurations.
; If the pin are changed, please the pin configurations are changed by you
;--------------------------------------------------------------------------
RS_LCD         BIT      P2.4
RW_LCD         BIT      P2.5
E_LCD          BIT      P2.6
sfr PORT_LCD    = P2;
;==========================================================================

    PUBLIC   init_lcd
    PUBLIC   _wrstr_lcd
    PUBLIC   clr_lcd
    PUBLIC   csrhome_lcd
    PUBLIC   _locate_lcd
    PUBLIC   on_lcd
    PUBLIC   off_lcd
    PUBLIC   _wrchar_lcd
    PUBLIC   _wrctl_lcd
    PUBLIC   _csrmode_lcd

                RSEG    Utility_LCD_4Bit_Port_SEG
                USING   0

;==========================================================================
; WRCTL_LCD_4BYTE : write 4bit data for control lcd
;--------------------------------------------------------------------------
; INPUT    : R7 = data 4 bit : 0000DDDD
; OUTPUT   : NONE
; REG USES : A, R7
; NO-PUBLIC to C51
;==========================================================================
wrctl_lcd_4byte:  CLR     C              ; write operation prepare
                  CLR     RS_LCD         ; select control address
                  SJMP    enable_lcd

;==========================================================================
; ENABLE_LCD : write/read 4bit data to/from lcd (data or control)
;              and enable operation
;--------------------------------------------------------------------------
; INPUT    : R7 = 4 bit data: 0000DDDD
;            CY = 0:write, 1:read operation select
; OUTPUT   : R7:data result if read operation is selected
; REG USED : A,R7
; NO-PUBLIC to C51
;==========================================================================
enable_lcd:       MOV     RW_LCD,C       ; set r/w lcd
                  MOV     A,PORT_LCD     ; read old data port
                  ORL     A,#0FH         ; prepare D0..D3=1111 for read
                                         ; and prepare D4..D7 not changed
                  JC      enable_lcd1    ; jump if read operation
                  ANL     A,#0F0H        ; masking bit, D4..D7 not change
                                         ; D0..D3 = 0000
                  ORL     A,R7           ; ORing for 4 bit data
                  MOV     PORT_LCD,A     ; output to 4bit data lcd port
                  SJMP    enable_lcd2
enable_lcd1:      MOV     PORT_LCD,A     ; write data lcd
enable_lcd2:      SETB    E_LCD          ; pulse for E lcd, now high logic
                  NOP                    ; for timing high logic
                  NOP                    ; total nop depend to crystal
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  MOV     A,PORT_LCD     ; no proble this operation for data lcd reading
                  NOP
                  NOP
                  NOP
                  NOP
                  CLR     E_LCD          ; e_lcd to low logic
                  JNC     enable_lcd3    ; if write operation no 4bit data masking
                  ANL     A,#0FH         ; 4bit data masking
                  MOV     R7,A           ; return value for C51 language
enable_lcd3:      RET

;==========================================================================
; BUSY_LCD : read busy lcd flag bit 7 from control lcd
;--------------------------------------------------------------------------
; INPUT    : none
; OUTPUT   : CY for busy lcd flag
; REG USED : A,B,R7
; NO-PUBLIC to C51
;==========================================================================
busy_lcd:         SETB    C              ; read prepare
                  CLR     RS_LCD         ; select control address
                  CALL    enable_lcd     ; generated enable pulse
                  MOV     B,R7           ; save 4bit return value D4..D7
                  CALL    enable_lcd     ; generated enable pulse
                  MOV     A,B            ; get value D4..D7
                  JB      ACC.3,busy_lcd ; check busy lcd bit 7
                  RET                    ; for 4 bit interfacing is bit 3

;==========================================================================
; _RDCHAR_LCD : read char lcd from current cursor
;--------------------------------------------------------------------------
; INPUT    : none
; OUTPUT   : R7 = data ASCII char from current cursor lcd
; REG USED : A,B,R6,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern char rdchar_lcd(void)
;==========================================================================
_rdchar_lcd:      SETB    C              ; read prepare
                  SETB    RS_LCD         ; select data address
                  CALL    enable_lcd     ; generated enable pulse
                  SWAP    A              ; shift left 4 position to MSNyble
                  MOV     B,A            ; save
                  CALL    enable_lcd     ; generated enable pulse
                  ORL     A,B            ; joint to LSNyble data
                  MOV     R6,A           ; save 8bit data
                  CALL    busy_lcd       ; check busy lcd for high speed access
                                         ; because without delay routine
                  MOV     R7,AR6         ; return value to C51 language
                  RET

;==========================================================================
; _WRCTL_LCD : write control lcd to perform clear_lcd, locate_lcd etc
;--------------------------------------------------------------------------
; INPUT    : R7 = 8bit data to be writing to lcd as data control
; OUTPUT   : none
; REG USED : A,B,R6,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void wrctl_lcd(char)
;==========================================================================
_wrctl_lcd:       CLR     C
                  CLR     RS_LCD
                  SJMP    _wrchar_lcd1

;==========================================================================
; _WRCHAR_LCD : write ascii char lcd to perform char display in current cur
;--------------------------------------------------------------------------
; INPUT    : R7 = 8bit data to be writing to lcd as data ascii char
; OUTPUT   : none
; REG USED : A,B,R6,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void wrchar_lcd(char)
;==========================================================================
_wrchar_lcd:      CLR     C
                  SETB    RS_LCD
_wrchar_lcd1:
                  MOV     R6,AR7
                  MOV     A,R7
                  SWAP    A
                  ANL     A,#0FH
                  MOV     R7,A
                  CALL    enable_lcd
                  MOV     A,R6
                  ANL     A,#0FH
                  MOV     R7,A
                  CALL    enable_lcd
                  CALL    busy_lcd
                  RET

;==========================================================================
; FOR USED FIRT POWER UP TO INITIALIZE LCD
; BECAUSE FOR THE FIRT POWER UP TIME, THE BUSY LCD FLAG CAN NOT READ
; IF YOU HAVE ANOTHER DELAY ROUTINE OUTSIDE THIS DRIVER,
; PLEASE WRITE: PUBLIC to the top line
;==========================================================================
delay_lcd:        MOV     R7,#0FFH
delay_lcd1:       MOV     R6,#0FFH
delay_lcd2:       DEC     R6
                  MOV     A,R6
                  ORL     A,#0
                  JNZ     delay_lcd2
                  DJNZ    R7,delay_lcd1
                  RET
;==========================================================================


;==========================================================================
; _WRSTR_LCD : write sequence ascci in memory until NULL char is reached
;              The memory is free on all 8051 memory mapping as:
;              idata, data, xdata, cdata and pdata
;
;              This routine check Reg R3 to specify memory type.
;              If 00H:idata/data 01H:xdata FFH:cdata FEH:pdata
;
; Automatic generic pointer configuration for C51 language interfacing
;--------------------------------------------------------------------------
; INPUT    : R3 = memory type, R2 = MSB address, R1 = LSB address
; OUTPUT   : none
; REG USED : A,B,R6,R7, R0 for pdata/idata/data, DPTR for cdata and xdata
;
; PUBLIC to C51
; C51 PROTYPE: extern void wrstr_lcd(char*)
;==========================================================================
_wrstr_lcd:       CJNE    R3,#0,_wrstr_lcd_xdata    ; for idata memory
                  MOV     R0,AR1
_wrstr_lcd_idata1:MOV     A,@R0
                  ORL     A,#0
                  JZ      _wrstr_lcd_exit
                  MOV     R7,A
                  CALL    _wrchar_lcd
                  INC     R0
                  SJMP    _wrstr_lcd_idata1
_wrstr_lcd_xdata: CJNE    R3,#1,_wrstr_lcd_cdata    ; for xdata memory
                  MOV     DPH,R2
                  MOV     DPL,R1
_wrstr_lcd_xdata1:MOVX    A,@DPTR
                  ORL     A,#0
                  JZ      _wrstr_lcd_exit
                  MOV     R7,A
                  CALL    _wrchar_lcd
                  INC     DPTR
                  SJMP    _wrstr_lcd_xdata1
_wrstr_lcd_cdata: CJNE    R3,#0FFH,_wrstr_lcd_pdata ; for cdata memory
                  MOV     DPH,R2
                  MOV     DPL,R1
_wrstr_lcd_cdata1:CLR     A
                  MOVC    A,@A+DPTR
                  ORL     A,#0
                  JZ      _wrstr_lcd_exit
                  MOV     R7,A
                  CALL    _wrchar_lcd
                  INC     DPTR
                  SJMP    _wrstr_lcd_cdata1
_wrstr_lcd_pdata: CJNE    R3,#0FEH,_wrstr_lcd_exit ; for external page memory
                  MOV     R0,AR1
_wrstr_lcd_pdata1:MOVX    A,@R0
                  ORL     A,#0
                  JZ      _wrstr_lcd_exit
                  MOV     R7,A
                  CALL    _wrchar_lcd
                  INC     R0
                  SJMP    _wrstr_lcd_pdata1
_wrstr_lcd_exit:  RET

;==========================================================================
; CLR_LCD : clear all character in lcd, move to home cursor
;--------------------------------------------------------------------------
; INPUT    : none
; OUTPUT   : none
; REG USED : A,B,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void clr_lcd(void)
;==========================================================================
clr_lcd:          MOV     R7,#1
                  CALL    _wrctl_lcd
                  RET

;==========================================================================
; CSRHOME_LCD : move cursor to home position
;--------------------------------------------------------------------------
; INPUT    : none
; OUTPUT   : none
; REG USED : A,B,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void csrhome_lcd(void)
;==========================================================================
csrhome_lcd:      MOV     R7,#2
                  CALL    _wrctl_lcd
                  RET

;==========================================================================
; _LOCATE_LCD : move cursor to row,col
;--------------------------------------------------------------------------
; INPUT    : R7 = row, R5 = col, 0 is the firt col/row
; OUTPUT   : none
; REG USED : A,B,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void locate_lcd(char row, char col)
;==========================================================================
_locate_lcd:      CJNE    R7,#0,_locate_lcd1     ; row 0
                  MOV     A,#80H
                  SJMP    _locate_lcd4
_locate_lcd1:     CJNE    R7,#1,_locate_lcd2     ; row 1
                  MOV     A,#0C0H
                  SJMP    _locate_lcd4
_locate_lcd2:     CJNE    R7,#2,_locate_lcd3     ; row 2
                  MOV     A,#94H
                  SJMP    _locate_lcd4
_locate_lcd3:     CJNE    R7,#3,_locate_lcd5     ; row 3
                  MOV     A,#0D4H
_locate_lcd4:     ADD     A,R5                   ; add to col
                  MOV     R7,A
                  CALL    _wrctl_lcd
_locate_lcd5:     RET

;==========================================================================
; OFF_LCD : off lcd display, all char not clear only no-display
;--------------------------------------------------------------------------
; INPUT    : none
; OUTPUT   : none
; REG USED : A,B,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void off_lcd(void)
;==========================================================================
off_lcd:          MOV     R7,#08H
                  SJMP    on_lcd1
on_lcd:           MOV     R7,#0CH
on_lcd1:          CALL    _wrctl_lcd
                  RET

;==========================================================================
; OFF_LCD : setting lcd cursor to blink or/not/and cursor
;--------------------------------------------------------------------------
; INPUT    : R7 = cursor 1:on 0:off
;            R5 = blink  1:on 0:off
; OUTPUT   : none
; REG USED : A,B,R7
;
; PUBLIC to C51
; C51 PROTYPE: extern void csrmode_lcd(char cursor, char blink)
;==========================================================================
_csrmode_lcd:     MOV     B,#0CH
                  MOV     A,R7
                  JZ      _csrmode_lcd1
                  INC     B
                  INC     B
_csrmode_lcd1:    MOV     A,R5
                  JZ      _csrmode_lcd2
                  INC     B
_csrmode_lcd2:    MOV     R7,B
                  CALL    _wrctl_lcd
                  RET

;==========================================================================
; Initialize LCD for the first time on power up
;==========================================================================
init_lcd:         MOV     R7,#03H
                  CALL    wrctl_lcd_4byte
                  CALL    delay_lcd
                  MOV     R7,#03H
                  CALL    wrctl_lcd_4byte
                  CALL    delay_lcd
                  MOV     R7,#03H
                  CALL    wrctl_lcd_4byte
                  MOV     R7,#02H
                  CALL    wrctl_lcd_4byte
                  MOV     R7,#028H
                  CALL    _wrctl_lcd
                  MOV     R7,#0CH
                  CALL    _wrctl_lcd
                  MOV     R7,#01H
                  CALL    _wrctl_lcd
                  MOV     R7,#06H
                  CALL    _wrctl_lcd
                  CALL    delay_lcd
                  RET
;==========================================================================
END 

Vytisknout stránku

Zpátky Zpátky
© DH servis 2002 -