Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

4 bit lcd interfacing with pic 16f877a

Status
Not open for further replies.

pratzz

Member level 5
Joined
Jun 15, 2012
Messages
83
Helped
6
Reputation
12
Reaction score
6
Trophy points
1,288
Activity points
1,781
Code:
list p=PIC16F877a
#include <p16F877a.inc>
errorlevel -302
__config _HS_OSC & _LVP_OFF
en  equ 4
rw equ 5
rs equ 6
;-------------------------------------------
; GENERAL PURPOSE REGISTERS
;-------------------------------------------
		CBLOCK 20h
temp1
temp2
temp
temp3
temp4
num
count
		ENDC


		ORG 0
		clrf STATUS
		movlw 00
		movwf PCLATH
		goto start
;------------------------------------------
		org 04
		retfie
table1
movlw HIGH $
movwf PCLATH
movf temp3,w
addwf PCL,f
dt "     EXCEL      ",0
table2
movlw HIGH $
movwf PCLATH
movf temp4,w
addwf PCL,f
dt "UNIVERSALTRAINER",0
delay
         movwf temp2
         movlw (0ff-0feh)
         movwf temp1
		 clrwdt
         incfsz temp1,1
         goto $-2
		 decfsz temp2,1
		 goto $-6
         retlw 0


lcd_init
        movlw 0fh
        movwf PORTB
        bsf PORTB,en
        BSF PORTB,rs
        movlw .15
        call delay
        movlw 03h
        movwf PORTB
        bsf PORTB,en
        nop
        bcf PORTB,en
         movlw .15
        call delay
         movlw 03h
        movwf PORTB
        bsf PORTB,en
        nop
        bcf PORTB,en
         movlw .15
        call delay
        movlw 02h
        movwf PORTB
        bsf PORTB,en
        nop
        bcf PORTB,en
         movlw .15
        call delay

        movlw 28H              ;4-bit, 2 line, 5x7 dots
        call lcd_cmd           ;Call LCD command
        movlw 15h
        call delay
        movlw 0CH              ;Display ON cursor OFF
        call lcd_cmd           ;Call LCD command
        movlw 15h
        call delay
          movlw 06H              ;Set entry mode (Auto increment)
        call lcd_cmd           ;Call LCD command
  movlw 15h
        call delay
movlw 80H              ;Bring cursor to line 1
        call lcd_cmd           ;Call LCD command
        retlw 00h

;-------------------------------------------------------------------
lcd_cmd
    movwf temp
    swapf temp,W
    andlw 0fh
    movwf PORTB
    bcf PORTB,rs
    bcf PORTB,rw
    bsf PORTB,en
    ;movlw .15
    ;call delay
    bcf PORTB,en
    movf temp,W
    andlw 0fh
    movwf PORTB
    bcf PORTB,rs
    bcf PORTB,rw
    bsf PORTB,en
    movlw .15
    call delay
    bcf PORTB,en
    retlw 00h
lcd_data
    movwf temp
    swapf temp,W
    andlw 0fh
    iorlw 40h
    movwf PORTB
    bsf PORTB,rs
    bcf PORTB,rw
    bsf PORTB,en
   ; movlw .15
   ; call delay
    bcf PORTB,en
    movf temp,W
    andlw 0fh
    movwf PORTB
    bsf PORTB,rs
    bcf PORTB,rw
    bsf PORTB,en
    movlw .15
    call delay
    bcf PORTB,en
    retlw 00h
initialise

        clrf temp3
        clrf temp4
        clrf num
		bcf STATUS,RP1
		bsf STATUS,RP0
        clrf TRISB
		movlw b'00000111'
		movwf ADCON1
        bcf  STATUS,RP0
		retlw 00
;--------------------------------------------------------------
start
      call initialise
      call lcd_init

       y    call table1
            iorlw 00h
            btfsc STATUS,Z
            goto z
            call lcd_data
            incf temp3,1
            ;decfsz count,1
            goto y
            
            
         ;movlw d'16'
         ;movwf count
       z    movlw 0c0h
            call lcd_cmd
       z1     call table2
            iorlw 00h
            btfsc STATUS,Z
            goto x
            call lcd_data
            incf temp4,1
            ;decfsz count,1
            goto z1
x           goto x
            end

while the display is running fine on simulation,hardware implementation show absurd characters.
 

The issue could be improper initialization.

LCDs require a period of time upon powerup to reach a known ready state, the specific amount of time varies depending on the actual device and both environmental and operating factors. I do not see the presence of such a delay in your code.

I would suggest a delay of 150ms upon powerup before beginning the LCD initialization sequence. A longer than needed delay will not interfere with the LCD initialization and can always be reduced to a safe minimum once the initialization sequence has been shown to be viable.

Also I would strongly recommend using the Busy Flag rather than delays when sending normal commands and data to the LCD, if the device supports the feature. However, use of delays are necessary during the initialization sequence.

What has been done with the four unused pins of the LCD?

There maybe other issues, however the startup delay for a LCD can be crucial.

BigDog
 

The issue could be improper initialization.

LCDs require a period of time upon powerup to reach a known ready state, the specific amount of time varies depending on the actual device and both environmental and operating factors. I do not see the presence of such a delay in your code.

I would suggest a delay of 150ms upon powerup before beginning the LCD initialization sequence. A longer than needed delay will not interfere with the LCD initialization and can always be reduced to a safe minimum once the initialization sequence has been shown to be viable.

Also I would strongly recommend using the Busy Flag rather than delays when sending normal commands and data to the LCD, if the device supports the feature. However, use of delays are necessary during the initialization sequence.

What has been done with the four unused pins of the LCD?

There maybe other issues, however the startup delay for a LCD can be crucial.

BigDog

four pins are left not connected
 

While some LCD datasheets suggest these pins can be left floating and others recommend they be pulled low, I always err on the side of caution and pull them low through the use of a pull down resistor tied to ground.

BigDog
 

the kit in which i am implementing it is not possible for me to pull them down
 

[QUOTEwhile the display is running fine on simulation,hardware implementation show absurd characters.[/QUOTE]

i have encountered the same problem while my early days programming in college .
usually this error come due to delay subroutine .
the first thing to understand here is that circuit simulator never give real time O/P .
adjust your delays according to the actual hardware you are using and you will be fine .
i do all my programming with c compiler so i am not much help with the assembly coding .
if you are interested in c codes for the same then i can write the same for you .
 

the kit in which i am implementing it is not possible for me to pull them down

Hi,

First have a look at the Error report in MPlabx.

You have a label called ' z ' this is already assigned to the STATUS register bit Z.

You are using the High nibble of the port to send out the control lines Rw.Rs and E.
Think you will find in 4 bit mode you need to have the high nibble Rb4-7 for the data and the control lines on RB0-3.

Have a look at this tutorial for good into.
http://www.epemag.wimborne.co.uk/resources.htm


Its very easy to get your lcd wired up incorrectly as well, double check your lines and also do a resistance check between the pins to ensure nothing is shorting.

Attached is an lcd routine for the 18F chips, which will hopefully give you some guidance.


Edit,

AS BDG says the unsed pins should not be left floating is true and good practice, however on the lcds I have used I have never found it any problem if they are left floating, pulled high or pulled low.
 

Attachments

  • 18F_lcd.rar
    4.9 KB · Views: 114

the kit in which i am implementing it is not possible for me to pull them down
 

I only asked the question in passing, while it has proven to be an issue in past cases, the lack of a sufficient startup delay is almost certainly a source of problems. The required minimum statup delay is usually in the 20ms to 50ms range.

The following is Microchip's LCD routines for the PICDEM 2 Plus development board utilizing a PIC16F877 and a 4-bit LCD interface. I have also attached the entire project for your convenience and inspiration.

Code:
;************************************************************************
;*	Microchip Technology Inc. 2002					*
;*	Assembler version: 2.0000					*
;*	Filename: 							*
;*		lcd16.asm			 			*
;************************************************************************

	list 		p=16F877
	#include	P16F877.inc

#define	LCD_D4		PORTD, 0	; LCD data bits
#define	LCD_D5		PORTD, 1
#define	LCD_D6		PORTD, 2
#define	LCD_D7		PORTD, 3

#define	LCD_D4_DIR	TRISD, 0	; LCD data bits
#define	LCD_D5_DIR	TRISD, 1
#define	LCD_D6_DIR	TRISD, 2
#define	LCD_D7_DIR	TRISD, 3

;#define	LCD_E		PORTA, 1	; LCD E clock
;#define	LCD_RW		PORTA, 2	; LCD read/write line
;#define	LCD_RS		PORTA, 3	; LCD register select line
;
;#define	LCD_E_DIR	TRISA, 1	
;#define	LCD_RW_DIR	TRISA, 2	
;#define	LCD_RS_DIR	TRISA, 3	
;
#define	LCD_E		PORTD, 6	; LCD E clock
#define	LCD_RW		PORTD, 5	; LCD read/write line
#define	LCD_RS		PORTD, 4	; LCD register select line

#define	LCD_E_DIR	TRISD, 6	
#define	LCD_RW_DIR	TRISD, 5	
#define	LCD_RS_DIR	TRISD, 4	

#define	LCD_INS		0	
#define	LCD_DATA	1



D_LCD_DATA	UDATA 0x20
COUNTER		res	1
delay		res	1
temp_wr		res	1
temp_rd		res	1

	GLOBAL	temp_wr

PROG1	CODE


;***************************************************************************
	
LCDLine_1
	banksel	temp_wr
	movlw	0x80
	movwf	temp_wr
	call	i_write
	return
	GLOBAL	LCDLine_1

LCDLine_2
	banksel	temp_wr
	movlw	0xC0
	movwf	temp_wr
	call	i_write
	return
	GLOBAL	LCDLine_2
	
d_write					;write data
	call	LCDBusy
	bsf	STATUS, C	
	call	LCDWrite
	banksel	TXREG			;move data into TXREG 
	movwf	TXREG
	banksel	TXSTA
	btfss	TXSTA,TRMT		;wait for data TX
	goto	$-1
	banksel	PORTA	
	return
	GLOBAL	d_write
	
i_write					;write instruction
	call	LCDBusy
	bcf	STATUS, C
	call	LCDWrite
	return
 	GLOBAL	i_write

rlcd	macro	MYREGISTER
 IF MYREGISTER == 1
	bsf	STATUS, C
	call	LCDRead
 ELSE
	bcf	STATUS, C
	call	LCDRead
 ENDIF
	endm
;****************************************************************************




; *******************************************************************
LCDInit
	banksel TRISD
	bcf		TRISD,7
	banksel	PORTD
	bsf		PORTD,7
	call	Delay30ms
	clrf	PORTA
	
	banksel	TRISA			;configure control lines
	bcf	LCD_E_DIR
	bcf	LCD_RW_DIR
	bcf	LCD_RS_DIR
	
	movlw	b'00001110'
	banksel	ADCON1
	movwf	ADCON1	

	movlw	0xff			; Wait ~15ms @ 20 MHz
	banksel	COUNTER
	movwf	COUNTER
	movlw	0xFF
	banksel	delay
	movwf	delay
	call	DelayXCycles
	decfsz	COUNTER, F
	goto	$-3
;0x02------------------	
;	movlw	b'00110000'		;#1 Send control sequence 
	movlw	b'00100000'		;#1 Send control sequence 
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble

	movlw	0xff			;Wait ~4ms @ 20 MHz
	movwf	COUNTER
	movlw	0xFF
	movwf	delay
	call	DelayXCycles
	decfsz	COUNTER, F
	goto	$-3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;28---2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	movlw	b'00110000'		;#2 Send control sequence
	movlw	b'00100000'		;#2 Send control sequence
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble

	movlw	0xFF			;Wait ~100us @ 20 MHz
	movwf	delay
	call	DelayXCycles
;28--08						
;	movlw	b'0011000'		;#3 Send control sequence
	movlw	b'10000000'
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble

		;test delay
	movlw	0xFF			;Wait ~100us @ 20 MHz
	movwf	delay
	call	DelayXCycles

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0C--0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;	movlw	b'00100000'		;#4 set 4-bit
	movlw	b'00000000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble
;0x0C
	movlw	b'11000000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble



	call	Delay1ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0x01
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	movlw	b'00100000'		;#4 set 4-bit
	movlw	b'00000000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble
;0x01
	movlw	b'00010000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0x02
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	movlw	b'00000000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble
;0x02
	movlw	b'00100000'		;#4 set 4-bit
	movwf	temp_wr
	bcf	STATUS,C
	call	LCDWriteNibble
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;	rcall	LCDBusy			;Busy?
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms
	call	LongDelay ;2ms

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


;	call	LCDBusy			;Busy?
;				
;	movlw	b'00101000'		;#5   Function set
;	movwf	temp_wr
;	call	i_write
;
;	movlw	b'00001101'		;#6  Display = ON
;	movwf	temp_wr
;	call	i_write
;			
;	movlw	b'00000001'		;#7   Display Clear
;	movwf	temp_wr
;	call	i_write
;
;	movlw	b'00000110'		;#8   Entry Mode
;	movwf	temp_wr
;	call	i_write	
;
;	movlw	b'10000000'		;DDRAM addresss 0000
;	movwf	temp_wr
;	call	i_write

;	movlw	b'00000010'		;return home
;	movwf	temp_wr
;	call	i_write

	movlw	0x4E
	movwf	temp_wr
	call	LCDBusy
	bsf	STATUS, C	
	call	LCDWrite


	call	Delay1ms
	return

	GLOBAL	LCDInit	
; *******************************************************************








;****************************************************************************
;     _    ______________________________
; RS  _>--<______________________________
;     _____
; RW       \_____________________________
;                  __________________
; E   ____________/                  \___
;     _____________                ______
; DB  _____________>--------------<______
;
LCDWriteNibble
	btfss	STATUS, C		; Set the register select
	bcf	LCD_RS
	btfsc	STATUS, C	
	bsf	LCD_RS

	bcf	LCD_RW			; Set write mode

	banksel	TRISD
	bcf	LCD_D4_DIR		; Set data bits to outputs
	bcf	LCD_D5_DIR
	bcf	LCD_D6_DIR
	bcf	LCD_D7_DIR

	NOP				; Small delay
	NOP

	banksel	PORTA
	bsf	LCD_E			; Setup to clock data
	
	btfss	temp_wr, 7			; Set high nibble
	bcf	LCD_D7	
	btfsc	temp_wr, 7
	bsf	LCD_D7
	btfss	temp_wr, 6
	bcf	LCD_D6	
	btfsc	temp_wr, 6
	bsf	LCD_D6
	btfss	temp_wr, 5
	bcf	LCD_D5	
	btfsc	temp_wr, 5
	bsf	LCD_D5
	btfss	temp_wr, 4
	bcf	LCD_D4
	btfsc	temp_wr, 4
	bsf	LCD_D4	

	NOP
	NOP

	bcf	LCD_E			; Send the data

	return
; *******************************************************************





; *******************************************************************
LCDWrite
;	call	LCDBusy
	call	LCDWriteNibble
	BANKSEL	temp_wr
	swapf	temp_wr, f
	call	LCDWriteNibble
	banksel	temp_wr
	swapf	temp_wr,f

	return

	GLOBAL	LCDWrite
; *******************************************************************





; *******************************************************************
;     _____    _____________________________________________________
; RS  _____>--<_____________________________________________________
;               ____________________________________________________
; RW  _________/
;                  ____________________      ____________________
; E   ____________/                    \____/                    \__
;     _________________                __________                ___
; DB  _________________>--------------<__________>--------------<___
;
LCDRead
	banksel	TRISD
	bsf	LCD_D4_DIR		; Set data bits to inputs
	bsf	LCD_D5_DIR
	bsf	LCD_D6_DIR
	bsf	LCD_D7_DIR		

	BANKSEL	PORTA
	btfss	STATUS, C		; Set the register select
	bcf	LCD_RS
	btfsc	STATUS, C	
	bsf	LCD_RS

	bsf	LCD_RW			;Read = 1

	NOP
	NOP			

	bsf	LCD_E			; Setup to clock data

	NOP
	NOP
	NOP
	NOP

	btfss	LCD_D7			; Get high nibble
	bcf	temp_rd, 7
	btfsc	LCD_D7
	bsf	temp_rd, 7
	btfss	LCD_D6			
	bcf	temp_rd, 6
	btfsc	LCD_D6
	bsf	temp_rd, 6
	btfss	LCD_D5			
	bcf	temp_rd, 5
	btfsc	LCD_D5
	bsf	temp_rd, 5
	btfss	LCD_D4			
	bcf	temp_rd, 4
	btfsc	LCD_D4
	bsf	temp_rd, 4

	bcf	LCD_E			; Finished reading the data

	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP

	bsf	LCD_E			; Setup to clock data

	NOP
	NOP

	btfss	LCD_D7			; Get low nibble
	bcf	temp_rd, 3
	btfsc	LCD_D7
	bsf	temp_rd, 3
	btfss	LCD_D6			
	bcf	temp_rd, 2
	btfsc	LCD_D6
	bsf	temp_rd, 2
	btfss	LCD_D5			
	bcf	temp_rd, 1
	btfsc	LCD_D5
	bsf	temp_rd, 1
	btfss	LCD_D4			
	bcf	temp_rd, 0
	btfsc	LCD_D4
	bsf	temp_rd, 0

	bcf	LCD_E			; Finished reading the data

FinRd
	return
; *******************************************************************






; *******************************************************************
LCDBusy
	call	LongDelayLast
;	call	LongDelay
	return
				; Check BF
	rlcd	LCD_INS
	btfsc	temp_rd, 7
	goto	LCDBusy
	return

	GLOBAL	LCDBusy
; *******************************************************************






; *******************************************************************
DelayXCycles
	decfsz	delay, F
	goto	DelayXCycles
	return
; *******************************************************************
	
Delay1ms			;Approxiamtely at 4Mhz
	banksel	delay
	clrf	delay
Delay_1
	nop
	decfsz	delay
	goto	Delay_1
	return




Delay30ms	;more than 30 at 4 Mhz	
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms

	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms

	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	return
LongDelay:
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	return

LongDelayLast
	call	Delay1ms
	call	Delay1ms
	call	Delay1ms
	return

	END

BigDog
 

Attachments

  • 16FASM.zip
    100.8 KB · Views: 106

that two z's are different as case sensitivity is on and now i will look on the matter latter .definately delay is the program but work that i have to complete is urgent so i guess i will have to use 8 bit interfacing

- - - Updated - - -

Hi,

First have a look at the Error report in MPlabx.

You have a label called ' z ' this is already assigned to the STATUS register bit Z.

You are using the High nibble of the port to send out the control lines Rw.Rs and E.
Think you will find in 4 bit mode you need to have the high nibble Rb4-7 for the data and the control lines on RB0-3.

Have a look at this tutorial for good into.
http://www.epemag.wimborne.co.uk/resources.htm


Its very easy to get your lcd wired up incorrectly as well, double check your lines and also do a resistance check between the pins to ensure nothing is shorting.

Attached is an lcd routine for the 18F chips, which will hopefully give you some guidance.


Edit,

AS BDG says the unsed pins should not be left floating is true and good practice, however on the lcds I have used I have never found it any problem if they are left floating, pulled high or pulled low.
that two z's are different as case sensitivity is on and now i will look on the matter latter .definately delay is the program but work that i have to complete is urgent so i guess i will have to use 8 bit interfacing

- - - Updated - - -

[QUOTEwhile the display is running fine on simulation,hardware implementation show absurd characters.

i have encountered the same problem while my early days programming in college .
usually this error come due to delay subroutine .
the first thing to understand here is that circuit simulator never give real time O/P .
adjust your delays according to the actual hardware you are using and you will be fine .
i do all my programming with c compiler so i am not much help with the assembly coding .
if you are interested in c codes for the same then i can write the same for you .[/QUOTE]
thank you but i need assembly only
 

Hi,

To try coding your own lcd routine from scratch is complicated, particularly when you are just getting going.

Its also a very handy thing to have ready made so you can see the results of your other programming efforts.

In the attached file is a simpler version of those 18F files I sent earlier.

These examples, in 4 bit mode, have run in sim and on my 877A hardware at 4 mhz without any problem.
You can use any of the methods shown, but I find the last example easier for changing results.

The point about that Z z labels.

Before you start any coding the system preloads itself with the P877A.inc file.

This contains datails of all the System Register names and all the Bits within the Regsiters.
Typically the STATUS register has bits Z and C .

You then start using labels like 'z' it can become problematic depending on the case sensistivity.
Much better to become familiar with these system registers / bits and avoid any possible conflict.
 

Attachments

  • 877ALCD.rar
    65.1 KB · Views: 99

Please let me know that how to convert 8-bit data and command into its equivalent 4-bit data and command for LCD
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top