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.

Unexpected characters on LCD

Status
Not open for further replies.

mig29fulcrum

Junior Member level 1
Joined
Sep 29, 2011
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,391
Hi...
I've written following code to drive an LCD in 4-bit mode using busy flag.When i simulate my hex on Proteus,i should see "xxxxxxx"but i have " xwxwxw(A'x'=0x78 and A'w'=0x77).I also tested my code for "4444444" but i got " 434343"(A'4'=0x34 and A'3'=0x33).As you see higher nibble latches twice alternately and then cursor shifts right and latching lower nibble does not affects on the LCD.On the other hand when i increase clock frequency i get "4 4 4"or "x x x"(one shift to left alternately).
I also got "[HD44780]Attempted to write after reading a single nibble" warning.
I'll appreciate if you help me with this problem.
tnx...

Code:
		LIST P=PIC18F4550
	#INCLUDE P18F4550.INC
	CONFIG FOSC=INTOSC_EC
	CONFIG WDT=OFF
LCD		 EQU LATD
RS       EQU RD0
RW		 EQU RD1
EN       EQU RD2
BUFFER   EQU 0XAA
;-------------main program------------
	ORG 0H
	MOVLW 0X42
	MOVWF OSCCON
	RCALL LCD_INIT
	RCALL MYDATA
	BRA	  $
;------------LCD initialization-------
LCD_INIT
	CLRF  TRISD
	BCF   LCD,EN
	BCF   LCD,RS
	BCF   LCD,RW
	RCALL LONG_DELAY				;Power-up delay
	MOVLW 0X28						;4-bit/5*7
	RCALL COMMAND_ISSUE				;command send
	RCALL BUSY						;check for busy flag
	MOVLW 0X0F						;LCD on/cursor blinking
	RCALL COMMAND_ISSUE				;send command 
	RCALL BUSY						;check for busy flag
	MOVLW 0X06						;increment cursor	
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X84						;1st line/loc=4		
	RCALL COMMAND_ISSUE
	RCALL BUSY						;check for busy flag
	RETURN
;-----------command issue--------------
COMMAND_ISSUE
	MOVWF BUFFER					;store command into a file reg
	ANDLW 0XF0						;mask lower nibble of command
	MOVWF LCD						;move higher nibble into LATB
	BCF   LCD,RS					;select command reg
	BCF   LCD,RW					;select write mode
	BSF   LCD,EN					
	NOP
	BCF   LCD,EN					;H-to-L for latch 
	MOVF  BUFFER,W
	ANDLW 0X0F						;mask lower nibble of command
	SWAPF WREG						
	MOVWF LCD						;move lower nibble into LATB
	BSF   LCD,EN
	NOP
	BCF   LCD,EN					;H-to-L enable pulse
	RETURN
;------------idata-----------
MYDATA
	MOVLW A'z'						;move A'x' into working register
	RCALL DATA_ISSUE				;send data
	RCALL BUSY						;check for busy flag
	MOVLW A'x'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'x'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'x'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'x'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'x'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'x'
	RCALL DATA_ISSUE
	RETURN
;------------data issue-----------
DATA_ISSUE
	MOVWF BUFFER					;store data into a file reg
	ANDLW 0XF0						;mask lower nibble
	MOVWF LCD						;move higher nibble into LATB 
	BSF   LCD,RS					;select data reg
	BCF   LCD,RW					;select write mode
	BSF   LCD,EN						
	NOP
	BCF   LCD,EN	;H-to-L enable pulse(in this line first character send as A' ')
	MOVF  BUFFER,W
	ANDLW 0X0F						;mask higher nibble
	SWAPF WREG
	MOVWF LCD
	BSF   LCD,RS
	BCF   LCD,RW
	BSF   LCD,EN
	NOP
	BCF   LCD,EN					;H-to-L enable pulse
	RETURN
;-------------busy flag checking----------
BUSY
	BCF   LCD,RS					;select command reg
	BSF   LCD,RW					;select read mode
	MOVLW 0XF0						;make higher nibble of PORTB input
	MOVWF TRISD
CHECK								;busy flag checking
	BSF   LCD,EN
	NOP
	BCF   LCD,EN					;enable LCD
	BTFSC PORTD,7					;test for RB,7(busy flag)skip if clean
	BRA   CHECK
	CLRF  TRISD						;make PORTB output
	RETURN
;------------------(50msec)---------
LONG_DELAY
	MOVLW 0X3D
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------------(1msec)------------
JIFFY
	MOVLW 0XFC
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------general delay--------
GENERAL_DELAY
	MOVLW B'01000111'
	MOVWF T0CON
	BCF   INTCON,TMR0IF
	BSF   T0CON,TMR0ON
COUNT
	BTFSS INTCON,TMR0IF
	BRA   COUNT
	BCF   T0CON,TMR0ON
	RETURN
	END
I've corrected my code as you mentioned (change PORT to LAT and attached my LCD to PORTD)but result is the same.:sad:
I also got "[HD44780]Attempted to write after reading a single nibble" warning again.:sad:
I'm completely confused.
 
Last edited:

Check out the 18F4550 datasheet section on PORTC.

PORTC bits 4 and 5 can only be used for USB or as digital inputs. They cannot be used as ouputs.

You will need to avoid using C4 and C5 when connecting your LCD.

Hope this helps
 

Thank u for your answer.
I also tested PORTD lower nibble and got same result.
Is mt code OK?
 

You should always use LAT for output and PORT for input.

The way your code is written, you will suffer from Read-Modify-Write problems.

Post your corrected code, using LATD and I will check it out for you when I get time.

First, change all PORT references to LAT, except when reading the busy flag, when you must use PORT.

It would be a good idea to comment your code thoroughly too. Debugging will be much easier with commented code.
 
Here is my attempt at fixing your program, using PORTC for control signals and UPPER nibble of PORTD for 4 bit data:

Code:
; 16x2 LCD test program for PIC18F4550

	LIST P=PIC18F4550
	#INCLUDE P18F4550.INC
	
	;18F4550 Configuration Registers
	config	PLLDIV=5			;5 for 20MHz crystal
	config	CPUDIV = OSC1_PLL2	;[OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
	config	USBDIV = 2      	;USB clock source comes from the 96 MHz PLL divided by 2
;	config	FOSC = HSPLL_HS     ;HS oscillator, PLL enabled, HS used by USB
	config	FOSC = INTOSC_EC    ;test
;	config	FOSC = HS           ;test
	config	FCMEN = OFF         ;Fail-Safe Clock Monitor disabled
	config	WDT = OFF			;HW Disabled - SW Controlled
	config	MCLRE = ON			;MCLR pin enabled; RE3 input pin disabled
	config	PBADEN = OFF		;PORTB<4:0> pins are configured as digital I/O on Reset
	config	PWRT = ON		    ;power up timer on
	config	BOR = OFF		    ;brown-out reset off
	config	WDTPS = 1		    ;watchdog timer postscaler
	config	LVP = OFF		    ;low voltage programming disabled
	config	DEBUG = OFF		    ;background debugger off
    config  CCP2MX = OFF        ; CCP2 on RB3
    config  XINST = OFF         ; no extended instruction
    config  LPT1OSC = OFF       ; Timer1 configured for higher power operation
	config	CP0 = OFF		    ;code protection block 0
	config	CP1 = OFF
	config	CP2 = OFF
	config	CP3 = OFF
	config	CPB = OFF		    ;code protection boot block
	config	CPD = OFF		    ;code protection data EEPROM
	config	WRT0 = OFF		    ;write protection block 0
	config	WRT1 = OFF
	config	WRT2 = OFF
	config	WRT3 = OFF
	config	WRTB = OFF		;write protection boot block
	config	WRTC = OFF		;write protection configuration register
	config	WRTD = OFF		;write protection data EEPROM
	config	EBTR0 = OFF		;table read protection block 0
	config	EBTR1 = OFF
	config	EBTR2 = OFF
	config	EBTR3 = OFF
	config	EBTRB = OFF		;table read protection boot block

    cblock	0xAA			
        BUFFER
	endc
	
#define LCD_RS   LATC,0     ; low for command, high for data
#define LCD_RW   LATC,1     ; low for write
#define LCD_EN   LATC,2     ; pulse high to latch data in
#define LCD      LATD       ; 4 data bits on HIGH nibble
#define LCD_TRIS TRISD
#define LCD_BUSY PORTD,7    ; busy bit for HIGH nibble

;-------------main program------------
	ORG 0H
    nop                 ; for ICD2 debugger
	MOVLW 0X62
	MOVWF OSCCON
	RCALL LCD_INIT
	RCALL MYDATA
	BRA	  $
	
;------------LCD initialization-------
LCD_INIT
	CLRF  TRISC         ; all output
    CLRF  TRISD         ; all output
	BCF   LCD_EN
	BCF   LCD_RS
	BCF   LCD_RW
	RCALL LONG_DELAY
	MOVLW 0X28
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X0F
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X06
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X84
	RCALL COMMAND_ISSUE
	RCALL BUSY
	RETURN
;-----------command issue--------------
COMMAND_ISSUE
	MOVWF BUFFER
	ANDLW 0XF0
	MOVWF LCD
	BCF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
	BCF   LCD_EN
	MOVF  BUFFER,W
	ANDLW 0X0F
	SWAPF WREG
	MOVWF LCD
	BCF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
	BCF   LCD_EN
	RETURN
;------------idata-----------
MYDATA
	MOVLW A'H'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'e'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'l'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'l'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'o'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A' '
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'A'
	RCALL DATA_ISSUE
	RCALL BUSY	
	RETURN
;------------data issue-----------
DATA_ISSUE
	MOVWF BUFFER
	ANDLW 0XF0
	MOVWF LCD
	BSF   LCD_RS        ; high for data
	BCF   LCD_RW        ; low for write
	BSF   LCD_EN
    NOP
	NOP
	BCF   LCD_EN                      ;In this line data latches twice alternately
	MOVF  BUFFER,W
	ANDLW 0X0F
	SWAPF WREG
	MOVWF LCD
	BSF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
	BCF   LCD_EN
	RETURN
;-------------busy flag checking----------
BUSY
	BCF   LCD_RS
	BSF   LCD_RW
	MOVLW 0XF0
	MOVWF LCD_TRIS      ; change to high nibble inputs
CHECK
	BSF   LCD_EN
	NOP                 ; en pulse time
    NOP                 ; en pulse time
	BCF   LCD_EN
	NOP                 ; settle time
	BTFSC LCD_BUSY      ; check busy bit
	BRA   CHECK
	CLRF  LCD_TRIS      ; back to all outputs
	RETURN
;------------------(50msec)---------
LONG_DELAY
	MOVLW 0X3D
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------------(1msec)------------
JIFFY
	MOVLW 0XFC
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------general delay--------
GENERAL_DELAY
	MOVLW B'01000111'
	MOVWF T0CON
	BCF   INTCON,TMR0IF
	BSF   T0CON,TMR0ON
COUNT
	BTFSS INTCON,TMR0IF
	BRA   COUNT
	BCF   T0CON,TMR0ON
	RETURN
	END

And here the same program, but for LCD data on low nibble of PORTD:

Code:
; 16x2 LCD test program for PIC18F4550

	LIST P=PIC18F4550
	#INCLUDE P18F4550.INC
	
	;18F4550 Configuration Registers
	config	PLLDIV=5			;5 for 20MHz crystal
	config	CPUDIV = OSC1_PLL2	;[OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
	config	USBDIV = 2      	;USB clock source comes from the 96 MHz PLL divided by 2
;	config	FOSC = HSPLL_HS     ;HS oscillator, PLL enabled, HS used by USB
	config	FOSC = INTOSC_EC    ;test
;	config	FOSC = HS           ;test
	config	FCMEN = OFF         ;Fail-Safe Clock Monitor disabled
	config	WDT = OFF			;HW Disabled - SW Controlled
	config	MCLRE = ON			;MCLR pin enabled; RE3 input pin disabled
	config	PBADEN = OFF		;PORTB<4:0> pins are configured as digital I/O on Reset
	config	PWRT = ON		    ;power up timer on
	config	BOR = OFF		    ;brown-out reset off
	config	WDTPS = 1		    ;watchdog timer postscaler
	config	LVP = OFF		    ;low voltage programming disabled
	config	DEBUG = OFF		    ;background debugger off
    config  CCP2MX = OFF        ; CCP2 on RB3
    config  XINST = OFF         ; no extended instruction
    config  LPT1OSC = OFF       ; Timer1 configured for higher power operation
	config	CP0 = OFF		    ;code protection block 0
	config	CP1 = OFF
	config	CP2 = OFF
	config	CP3 = OFF
	config	CPB = OFF		    ;code protection boot block
	config	CPD = OFF		    ;code protection data EEPROM
	config	WRT0 = OFF		    ;write protection block 0
	config	WRT1 = OFF
	config	WRT2 = OFF
	config	WRT3 = OFF
	config	WRTB = OFF		;write protection boot block
	config	WRTC = OFF		;write protection configuration register
	config	WRTD = OFF		;write protection data EEPROM
	config	EBTR0 = OFF		;table read protection block 0
	config	EBTR1 = OFF
	config	EBTR2 = OFF
	config	EBTR3 = OFF
	config	EBTRB = OFF		;table read protection boot block

    cblock	0xAA			
        BUFFER
	endc
	
#define LCD_RS   LATC,0     ; low for command, high for data
#define LCD_RW   LATC,1     ; low for write
#define LCD_EN   LATC,2     ; pulse high to latch data in
#define LCD      LATD       ; 4 data bits on LOW nibble
#define LCD_TRIS TRISD
#define LCD_BUSY PORTD,3    ; busy bit for LOW nibble

;-------------main program------------
	ORG 0H
    nop                 ; for ICD2 debugger
	MOVLW 0X62
	MOVWF OSCCON
	RCALL LCD_INIT
	RCALL MYDATA
	BRA	  $
	
;------------LCD initialization-------
LCD_INIT
	CLRF  TRISC         ; all output
    CLRF  TRISD         ; all output
	BCF   LCD_EN
	BCF   LCD_RS
	BCF   LCD_RW
	RCALL LONG_DELAY
	MOVLW 0X28
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X0F
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X06
	RCALL COMMAND_ISSUE
	RCALL BUSY
	MOVLW 0X84
	RCALL COMMAND_ISSUE
	RCALL BUSY
	RETURN
;-----------command issue--------------
COMMAND_ISSUE
	MOVWF BUFFER
	ANDLW 0XF0
	SWAPF WREG
	MOVWF LCD
	BCF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
    NOP
	BCF   LCD_EN
	MOVF  BUFFER,W
	ANDLW 0X0F
	MOVWF LCD
	BCF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
    NOP
	BCF   LCD_EN
	RETURN
;------------idata-----------
MYDATA
	MOVLW A'H'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'e'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'l'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'l'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'o'
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A' '
	RCALL DATA_ISSUE
	RCALL BUSY
	MOVLW A'L'
	RCALL DATA_ISSUE
	RCALL BUSY	
	RETURN
;------------data issue-----------
DATA_ISSUE
	MOVWF BUFFER
	ANDLW 0XF0
	SWAPF WREG
	MOVWF LCD
	BSF   LCD_RS        ; high for data
	BCF   LCD_RW        ; low for write
	BSF   LCD_EN
    NOP
	NOP
	BCF   LCD_EN                      ;In this line data latches twice alternately
	MOVF  BUFFER,W
	ANDLW 0X0F
	MOVWF LCD
	BSF   LCD_RS
	BCF   LCD_RW
	BSF   LCD_EN
	NOP
    NOP
	BCF   LCD_EN
	RETURN
;-------------busy flag checking----------
BUSY
	BCF   LCD_RS
	BSF   LCD_RW
	MOVLW 0X0F
	MOVWF LCD_TRIS      ; change to low nibble inputs
CHECK
	BSF   LCD_EN
	NOP                 ; en pulse time
    NOP                 ; en pulse time
	BCF   LCD_EN
	NOP                 ; settle time
	BTFSC LCD_BUSY      ; check busy bit
	BRA   CHECK
	CLRF  LCD_TRIS      ; back to all outputs
	RETURN
;------------------(50msec)---------
LONG_DELAY
	MOVLW 0X3D
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------------(1msec)------------
JIFFY
	MOVLW 0XFC
	MOVWF TMR0L
	RCALL GENERAL_DELAY
	RETURN
;------------general delay--------
GENERAL_DELAY
	MOVLW B'01000111'
	MOVWF T0CON
	BCF   INTCON,TMR0IF
	BSF   T0CON,TMR0ON
COUNT
	BTFSS INTCON,TMR0IF
	BRA   COUNT
	BCF   T0CON,TMR0ON
	RETURN
	END
By the way, 18F4550 is not a good PIC to learn on, due to the large number of complex Config options and the pins lost to USB. 18F4520 or 18F4620 are far better to learn on.
 
Last edited:

I really appreciate your kindness.
Your code has following result.
untitled.JPG
 

Works fine on real hardware.

Never used Proteus and never wanted to. It seems to be a poor emulator, judging by the number of problem posts that I see.
 
I'll never trust Proteus from now.
Thank u for your kindness and sorry for wasting your time my friend.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top