please dont rip this site

PIC 4 bit 16x2 Hitachi LCD driver


Universal HD44780 LCD display driver library - P. Pemberton


NEW!

This is my first decent bit of code for the PICmicro. It's a display control library that was distributed to a few members of the PICList for testing. I have used the serial control library (lcd_ser.inc) extensively - LCDs make great debugging tools. Examine the examples carefully - almost all you need to know is contained in them.

A small bug in the 4-bit driver code was fixed on 26 May 2003. This bug meant that some display panels (such as the Optrex DMC16106C) would miss characters sent to the display.


banks.inc

          LIST
; PIC16-series PAGE-switching macros
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.
;
; Provides:
;       BANK0           Switch to RAM BANK 0
;       BANK1           Switch to RAM BANK 1
;       BANK2           Switch to RAM BANK 2
;       BANK3           Switch to RAM BANK 3
          NOLIST

#ifndef   __BANKS_INCLUDED
 #define  __BANKS_INCLUDED

BANK0     MACRO                         ; Macro to select data RAM BANK 0
          BCF       STATUS,RP0
          BCF       STATUS,RP1
          ENDM

BANK1     MACRO                         ; Macro to select data RAM BANK 1
          BSF       STATUS,RP0
          BCF       STATUS,RP1
          ENDM

BANK2     MACRO                         ; Macro to select data RAM BANK 2
          BCF       STATUS,RP0
          BSF       STATUS,RP1
          ENDM

BANK3     MACRO                         ; Macro to select data RAM BANK 3
          BSF       STATUS,RP0
          BSF       STATUS,RP1
          ENDM
#endif
          LIST


lcd_cmn.inc

; Universal PIC LCD Interface Module
; HD44780 main handler/common functions (LCD_CMN.INC)
; NOTE: DO NOT #INCLUDE THIS FILE - #INCLUDE ONE OF THE BACKENDS INSTEAD!
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.


	CBLOCK
		__LCD_DOCBUFF		; Display Control settings
	ENDC

; Initialize LCD
LCD_INIT:
	MOVLW	B'00000100'		; Init DOCBUFF
	MOVWF	__LCD_DOCBUFF
	CALL	__LCD_INIT		; Init the LCD
	RETURN				; Return

; Display Clear
LCD_CLRSCR:
	MOVLW	B'00000001'		; Clear the LCD display
	CALL	LCD_SENDINS
	RETURN

; Display On/Off - If W=0 then display off else display on
LCD_ONOFF:
	BSF	__LCD_DOCBUFF,	2	; Assume W != 0
	IORLW	0			; Update flags
	BTFSC	STATUS,		Z	; Zero?
	BCF	__LCD_DOCBUFF,	2	; W=0; turn off the display
	MOVF	__LCD_DOCBUFF,	W	; Move control byte into W
	IORLW	.8			; Set command bit
	CALL	LCD_SENDINS		; Send the instruction
	RETURN

; Cursor On/Off - If W=0 then cursor off else cursor on
LCD_CURSOR:
	BSF	__LCD_DOCBUFF,	1	; Assume W != 0
	IORLW	0			; Update flags
	BTFSC	STATUS,		Z	; Zero?
	BCF	__LCD_DOCBUFF,	1	; W=0; turn off the cursor
	MOVF	__LCD_DOCBUFF,	W	; Move control byte into W
	IORLW	.8			; Set command bit
	CALL	LCD_SENDINS		; Send the instruction
	RETURN

; Blinking Cursor On/Off - If W=0 then blinking cursor on else off
LCD_CURSBLINK:
	BSF	__LCD_DOCBUFF,	0	; Assume W != 0
	IORLW	0			; Update flags
	BTFSC	STATUS,		Z	; Zero?
	BCF	__LCD_DOCBUFF,	0	; W=0; turn off the block cursor
	MOVF	__LCD_DOCBUFF,	W	; Move control byte into W
	IORLW	.8			; Set command bit
	CALL	LCD_SENDINS		; Send the instruction
	RETURN

; Move cursor - W=offset
LCD_MOVECURS:
	IORLW	B'10000000'		; Set command bit
	CALL	LCD_SENDINS		; Send the instruction
	RETURN

; Move cursor to Line 1
LCD_LINE1:
	MOVLW	0x00			; Move cursor to 0x00
	CALL	LCD_MOVECURS
	RETURN

; Move cursor to Line 2
LCD_LINE2:
	MOVLW	0x40			; Move cursor to 0x40
	CALL	LCD_MOVECURS
	RETURN


lcd_4bit.inc

; Universal PIC LCD Interface Module
; HD44780 4-bit mode transport layer/backend (LCD_4BIT.INC)
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.
;
; Pindefs required:
; 	LCD_D7	The PIC pin connected to the LCD's D7 pin (ex: PORTB,3)
;	LCD_D6	The PIC pin connected to the LCD's D6 pin (ex: PORTB,2)
;	LCD_D5	The PIC pin connected to the LCD's D5 pin (ex: PORTB,1)
;	LCD_D4	The PIC pin connected to the LCD's D4 pin (ex: PORTB,0)
;	LCD_E	The PIC pin connected to the LCD's E pin (ex: PORTB,5)
;	LCD_RS	The PIC pin connected to the LCD's RS pin (ex: PORTB,4)

        CBLOCK
                __LCD_TEMP0
                __LCD_TEMP1
        ENDC

; Send a byte to the LCD, assumes RS already set
__LCD_SEND:
	MOVWF	__LCD_TEMP0		; Store byte in Temp 0
	BCF	LCD_D7			; Clear data bits
	BCF	LCD_D6
	BCF	LCD_D5
	BCF	LCD_D4
	BTFSC	__LCD_TEMP0,	7	; Load high nibble
	BSF	LCD_D7
	BTFSC	__LCD_TEMP0,	6
	BSF	LCD_D6
	BTFSC	__LCD_TEMP0,	5
	BSF	LCD_D5
	BTFSC	__LCD_TEMP0,	4
	BSF	LCD_D4
	BSF	LCD_E			; Strobe E
	GOTO	$+1
	BCF	LCD_E

	BCF	LCD_D7			; Clear data bits
	BCF	LCD_D6
	BCF	LCD_D5
	BCF	LCD_D4
	BTFSC	__LCD_TEMP0,	3	; Load low nibble
	BSF	LCD_D7
	BTFSC	__LCD_TEMP0,	2
	BSF	LCD_D6
	BTFSC	__LCD_TEMP0,	1
	BSF	LCD_D5
	BTFSC	__LCD_TEMP0,	0
	BSF	LCD_D4
	BSF	LCD_E			; Strobe E
	GOTO	$+1
	BCF	LCD_E
	RETURN

; Send an instruction byte to the LCD
LCD_SENDINS:
	BCF	LCD_RS			; RS low=instruction
	CALL	__LCD_SEND		; Send the instruction byte
	CALL	__LCD_SHORTDELAY	; Short delay for instruction
	RETURN

; Send a character to the LCD
LCD_PUTCH:
	BSF	LCD_RS			; RS high=character
	CALL	__LCD_SEND		; Send the character
	CALL	__LCD_SHORTDELAY	; Short delay for data
	RETURN

; Initialize the LCD
__LCD_INIT:
	CALL	__LCD_LONGDELAY		; Long init delay
	MOVLW	B'00110011'		; 2x 8bit resets
	CALL	LCD_SENDINS
	MOVLW	B'00110011'		; 2x 8bit resets
	CALL	LCD_SENDINS
	MOVLW	B'00110010'		; 8bit reset then 4bit reset
	CALL	LCD_SENDINS
	MOVLW	B'00101100'		; Function Set - 4bit, 2 lines
	CALL	LCD_SENDINS
	MOVLW	B'00000110'		; Mode Set - incr. w/crsr shift
	CALL	LCD_SENDINS
	MOVLW	B'00001100'		; Display on, cursor & blink off
	CALL	LCD_SENDINS
	MOVLW	B'00000001'		; Display Clear
	CALL	LCD_SENDINS
	MOVLW	B'00000010'		; Cursor Home
	CALL	LCD_SENDINS
	CALL	__LCD_LONGDELAY		; Long post-init delay
	RETURN

; Long delay for init
__LCD_LONGDELAY:
	CLRF	__LCD_TEMP0
__LCD_LONGDEL:
	CLRF	__LCD_TEMP1
__LCD_SHORTDEL:
	DECFSZ	__LCD_TEMP1,	F
	GOTO	__LCD_SHORTDEL
	DECFSZ	__LCD_TEMP0,	F
	GOTO	__LCD_LONGDEL
	RETURN

; Short delay between commands
__LCD_SHORTDELAY:
	MOVLW	0x14
	MOVWF	__LCD_TEMP1
__LCD_SHORTLOOP:
	DECFSZ	__LCD_TEMP1,	F
	GOTO	__LCD_SHORTLOOP
	RETURN

; Include the Common LCD Functions
	INCLUDE	"lcd_cmn.inc"


lcd_ser.inc

; Universal PIC LCD Interface Module
; HD44780 serial mode transport layer/backend (LCD_SER.INC)
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.
;
; Pindefs required:
;	LCD_DATA	The PIC pin connected to the A and B pins on the 
;				74LS164 (ex: PORTB,5)
;	LCD_CLOCK	The PIC pin connected to the LS164's CLOCK pin
;				(ex: PORTB,4)

        INCLUDE "banks.inc"

; File register Usage
	CBLOCK
		__LCD_DLAY		; Delay variable
		__LCD_NOTEMP		; Temporary variable for nibble output
		__LCD_TEMP		; Temporary variable
		__LCD_CNTR		; Counter
	ENDC

__LCD_INIT:
        CALL    __LCD_DLAY5             ;  Wait 20 msecs before Reset
        CALL    __LCD_DLAY5
        CALL    __LCD_DLAY5
        CALL    __LCD_DLAY5

        BCF     STATUS,         C       ; RS=0 (instruction)
        MOVLW   0x30                    ; RESET
        CALL    __LCD_NIBBLE            ; Send the nibble
        CALL    __LCD_DLAY5             ; Wait 5mS before resending

        BSF     LCD_DATA		; Send again.
        BCF     LCD_DATA
        CALL    __LCD_DLAY160           ; Wait 160uS before resending

        BSF     LCD_DATA
        BCF     LCD_DATA
        CALL    __LCD_DLAY160           ; Wait 160uS before sending

        BCF     STATUS,         C       ; RS=0 (instruction)
        MOVLW   0x20                    ; Set 4-bit (nibble) mode
        CALL    __LCD_NIBBLE            ; Send the nibble
        CALL    __LCD_DLAY160           ; Wait 160uS before sending

        MOVLW   0x28                    ; Two line mode, 4-bit
        CALL	LCD_SENDINS
        CALL	__LCD_DLAY160

        MOVLW   0x08                    ; Turn off the display
        CALL    LCD_SENDINS

        MOVLW   0x01                    ; Clear the DDRAM
        CALL    LCD_SENDINS
        CALL    __LCD_DLAY5             ; Can take up to 5uS

        MOVLW   0x06                    ; Set cursor direction
        CALL    LCD_SENDINS

        MOVLW   0x0C                    ; Display on
        CALL    LCD_SENDINS
        CALL    __LCD_DLAY160

	RETURN

LCD_PUTCH:                              ; Send a character to the LCD
        MOVWF   __LCD_DLAY              ; Temporary store.

        BSF     STATUS,         C       ; RS=1 (data)
        CALL    __LCD_NIBBLE            ; Send the high nibble

        SWAPF   __LCD_DLAY,     W       ; Low nibble -> W
        BSF     STATUS,         C       ; RS=1 (data)
        CALL    __LCD_NIBBLE            ; Send the low nibble
        RETURN

LCD_SENDINS:                            ; Send an instruction to the LCD
        MOVWF   __LCD_DLAY              ; Temporary store

        BCF     STATUS,         C       ; RS=0 (instruction)
        CALL    __LCD_NIBBLE            ; Send the high nibble

        SWAPF   __LCD_DLAY,     W       ; Low nibble -> W
        BCF     STATUS,         C       ; RS=0 (instruction)
        CALL    __LCD_NIBBLE            ; Send the low nibble
        RETURN

__LCD_NIBBLE:                           ; Sends a nibble (4 bits) to the LCD
        MOVWF   __LCD_NOTEMP            ; Temporarily store the nibble
        RRF     __LCD_NOTEMP,   F       ; Save the RS bit
        BSF     STATUS,         C       ; Carry high
        RRF     __LCD_NOTEMP,   F       ; Save the gate bit

        MOVLW   .0                      ; Clear the shift register
        CALL    __LCD_SEND

        MOVF    __LCD_NOTEMP,   W       ; Send the nibble to the LCD
        CALL    __LCD_SEND

        BSF     LCD_DATA                ; Clock in the data
        BCF     LCD_DATA
        RETURN

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

; Send the byte in W to the 74HCT164
__LCD_SEND:
        MOVWF   __LCD_TEMP              ; Store byte
        MOVLW   .8                      ; Eight data bits
        MOVWF   __LCD_CNTR              ; Store in counter
__LCD_SENDLOOP:
        MOVLW   0
        RLF     __LCD_TEMP,	F	; Rotate left into carry
        BCF     LCD_DATA                ; Assume carry low
        BTFSC   STATUS, C               ; Carry high?
        BSF     LCD_DATA                ; Yes. Set port bit
;        GOTO    $+1                     ; Wait for the data line to settle
        BSF     LCD_CLOCK               ; Clock high
;        GOTO    $+1                     ; Make sure the HC164 sees the transition
        BCF     LCD_CLOCK		; Clock low
        DECFSZ  __LCD_CNTR,	F	; Decrement counter
        GOTO    __LCD_SENDLOOP          ; Not zero yet; keep going
        RETURN                          ; Counter=0; return.

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

__LCD_DLAY160:                          ; 160uS delay
        MOVLW   .256-(160/4)            ; Loop until carry set
        ADDLW   .1
        BTFSS   STATUS,         C
        GOTO    $-2
        RETURN

__LCD_DLAY5:                            ; 5mS delay
        MOVLW   .4                      ; Set up the Delay
        MOVWF   __LCD_DLAY
        MOVLW   .256 - 0x0E8            ; Inner loop
        ADDLW   1
         BTFSC  STATUS, Z
        DECFSZ  __LCD_DLAY, F           ; Outer loop
        GOTO    $-3
        RETURN

; Include the Common LCD Functions
	INCLUDE	"lcd_cmn.inc"


lcdtest_ser.inc

; Universal PIC LCD Interface Module
; 74LS164-to-LCD test program
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.
;
; Connections:
;	PIC	74LS164		LCD
;	RB7	1 and 2		via 10k resistor to "E"
;	RB6	8
;		5		D4
;		6		D5
;		10		D6
;		11		D7
;		12		RS
;		13			to 1N4148 cathode
;	Vcc	9 and 14	Vcc
;	Vss	7		Vss
;				E	to 1N4148 anode
;
;
; The contrast pin on the LCD should be connected as shown in the LCD module's
; datasheet.
;
; The above circuit is based on one included in an article written by
; Myke Predko for www.rentron.com

;; PIC setup and toplevel includes
	LIST	P=16F874
	INCLUDE	<p16f874.inc>
	INCLUDE	"banks.inc"

; Pindefs
#DEFINE	LCD_DATA	PORTB,	7
#DEFINE	LCD_CLOCK	PORTB,	6

; Variables
	CBLOCK	0x20
	ENDC

; Reset vector
	ORG	0
	GOTO	START
; Interrupt vector
	ORG	4
	GOTO	START

; Start of code
	ORG	5

START:
	CLRF	PORTB			; Clear PORTB
	PAGE1				; Bank 1
	BCF	LCD_DATA		; Data, clock=outputs
	BCF	LCD_CLOCK
	PAGE0				; Bank 0

	CALL	LCD_INIT		; Init the LCD

	CLRF	FSR			; Message loop
MSGLOOP:
	MOVF	FSR,		W
	INCF	FSR,		F
	CALL	MESSAGE
	IORLW	.0
	BTFSC	STATUS,		Z
	GOTO	MSGDONE
	CALL	LCD_PUTCH
	GOTO	MSGLOOP

MSGDONE:
	MOVLW	.1			; Block Cursor on
	CALL	LCD_CURSBLINK
	CALL	LCD_LINE2
	MOVLW	"2"
	CALL	LCD_PUTCH
	MOVLW	"0"
	CALL	LCD_PUTCH
	MOVLW	"."
	CALL	LCD_PUTCH
	MOVLW	"0"
	CALL	LCD_PUTCH
	MOVLW	0x1A
	CALL	LCD_PUTCH
	GOTO	$

MESSAGE:
	ADDWF	PCL,		F
	DT	"Hello.",0

;; Final post-code includes
	INCLUDE	"lcd_ser.inc"

	END


lcdtest_4bit.inc

; Universal PIC LCD Interface Module
; 4-bit LCD test program
; By P. Pemberton, Jr.
; WWW: http://www.philpem.me.uk/
; Email: piclist@philpem.me.uk
; This software is distributed under the BSD License. You are free to do whatever
; you want with this code, but I would appreciate an email first. I would also
; appreciate copies of any modifications you make.
;
; Connections:
;	PIC	LCD
;	RB5	E
;	RB4	RS
;	RB3	D7
;	RB2	D6
;	RB1	D5
;	RB0	D4
;
; The contrast pin on the LCD should be connected as shown in the LCD module's
; datasheet.

;; PIC setup and toplevel includes
	LIST	P=16F874
	INCLUDE	<p16f874.inc>
	INCLUDE	"banks.inc"

; Pindefs
#DEFINE	LCD_D7	PORTB,	3
#DEFINE	LCD_D6	PORTB,	2
#DEFINE	LCD_D5	PORTB,	1
#DEFINE	LCD_D4	PORTB,	0
#DEFINE	LCD_E	PORTB,	5
#DEFINE	LCD_RS	PORTB,	4

; Variables
	CBLOCK	0x20
	ENDC

; Reset vector
	ORG	0
	GOTO	START
; Interrupt vector
	ORG	4
	GOTO	START

; Start of code
	ORG	5

START:
	CLRF	PORTB			; Clear PORTB
	PAGE1				; Bank 1
	BCF	LCD_D7			; Databits=outputs
	BCF	LCD_D6
	BCF	LCD_D5
	BCF	LCD_D4
	BCF	LCD_RS			; RS, E=outputs
	BCF	LCD_E
	PAGE0				; Bank 0

	CALL	LCD_INIT		; Init the LCD

	CLRF	FSR			; Message loop
MSGLOOP:
	MOVF	FSR,		W
	INCF	FSR,		F
	CALL	MESSAGE
	IORLW	.0
	BTFSC	STATUS,		Z
	GOTO	MSGDONE
	CALL	LCD_PUTCH
	GOTO	MSGLOOP

MSGDONE:
	MOVLW	.1			; Blinking Cursor on
	CALL	LCD_CURSBLINK
	CALL	LCD_LINE2
	MOVLW	"2"
	CALL	LCD_PUTCH
	MOVLW	"0"
	CALL	LCD_PUTCH
	MOVLW	"."
	CALL	LCD_PUTCH
	MOVLW	"0"
	CALL	LCD_PUTCH
	MOVLW	0x1A
	CALL	LCD_PUTCH
	GOTO	$

MESSAGE:
	ADDWF	PCL,		F
	DT	"Hello.",0

;; Final post-code includes
	INCLUDE	"lcd_4bit.inc"

	END

Comments:

See also:


file: /Techref/io/lcd/unilcd.htm, 16KB, , updated: 2009/10/1 09:34, local time: 2014/12/22 09:58, owner: PAP-NA-554,
TOP NEW HELP FIND: 
54.166.105.24:LOG IN

 ©2014 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE! / 

<A HREF="http://www.piclist.com/techref/io/lcd/unilcd.htm"> Universal HD44780 LCD display driver library</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

  LCD Front Panel Set: $8.99!
- 2x16 LCD HD44780 controller
- 4 push buttons - 3 LEDs - 2x12 header
 

Welcome to www.piclist.com!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .