Character LCD initialization

Thread Starter

Pencil

Joined Dec 8, 2009
272
I have been trying to implement a software initialization
on a character LCD using a PIC 16f690.

When I run the code as is the display will not display anything.
If I jump over the initialization sequence I have written and go
straight to writing instructions it seems to work fine. (automatic
initialization works fine with the power supply/test circuit at present).

A couple of notes about the display.
OPTREX DMC20261NY-LY
Hitachi 44780 chip
Although unit is previously unused, it may be an older model.

Any ideas? I have changed the delays longer and shorter in
an attempt to see if it was a timing issue.

Datasheet attached.


Rich (BB code):
;Internal Oscillator 4MHz (1Mhz instruction)

;PIN CONNECTIONS:
;______________
;PIC            LCD
;______________
;RB4            RS
;RB5            R/W
;RB6            ENABLE
;RC0-RC7     DB0-DB7

;****BEGIN INITIALIZE LCD****
;DWELL 100ms (Wait for 15ms minimum after Vcc=4.5V)
        MOVLW    0xDF  ;223
        MOVWF    DWELLA
        MOVLW    0x82  ;130
        MOVWF    DWELLB
        DECFSZ    DWELLA,F
        GOTO    $-1
        DECFSZ    DWELLB,F
        GOTO    $-3
        NOP
        NOP
;FUNCTION SET COMMAND (8-BIT INTERFACE)*1*
        MOVLW  0x30        ;0011 0000
        MOVWF  PORTC     ;0011 0000 RC5(DB5)=1 RC4(DB4)=1 
        MOVLW  0x00        ;0000 0000    
        MOVWF  PORTB     ;0000 0000 RB4(RS)=0 RB5(R/W)=0 RB6(E)=0
        NOP                     ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
;FUNCTION SET COMMAND (8-BIT INTERFACE)*2*
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;FUNCTION SET COMMAND (8-BIT INTERFACE)*3*
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;FUNCTION SET COMMAND (8-BIT INTERFACE, LINES 2, FONT 5X7)
        MOVLW  0x38        ;0011 1000
        MOVWF  PORTC     ;0011 1000 RC5=1 RC4=1 RC3=1 RC2=0
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;DISPLAY OFF
        MOVLW  0x08        ;0000 1000
        MOVWF  PORTC     ;0000 1000 RC3=1 (DISPLAY OFF) 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
;****END INITIALIZE LCD****
;***************************
;NO INITIALIZATION JUMP TO HERE
;***************************
 ;CLEAR DISPLAY
        MOVLW  0x01        ;0000 0001
        MOVWF  PORTC     ;0000 0001 RC0=1 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;SET ENTRY MODE (INCREMENT, NO DISPLAY SHIFT)
        MOVLW  0x06        ;0000 0110
        MOVWF  PORTC     ;0000 0110 RC2=1 RC1=1 RC0=0 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;DISPLAY ON OFF CONTROL (DISPLAY=ON, CURSOR=ON, BLINK=ON)
        MOVLW  0x0E        ;0000 1110
        MOVWF  PORTC     ;0000 1110 RC3=1 RC1=2 RC1=1 RC0=0 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
 ;CLEAR DISPLAY AND CURSOR HOME
        MOVLW  0x01        ;0000 0001
        MOVWF  PORTC     ;0000 0001 RC0=1 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms     
;****END INITIALIZE LCD****
;TEST WRITE CHARACTER
;CHARACTER 1
;INSTRUCTION SET DD RAM ADDRESS
        MOVLW  0x8A        ;1000 1010 ADDRESS 0Ah
        MOVWF  PORTC     ;1000 1010 ADDRESS 0Ah
        MOVLW  0x00        ;0000 0000    
        MOVWF  PORTB     ;0000 0000 RB4(RS)=0 RB5(R/W)=0 RB6(E)=0
        NOP                     ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)  
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
;WRITE DATA
        MOVLW  0x41        ;0100 0001
        MOVWF  PORTC     ;0100 0001 CHARACTER=A 
        MOVLW  0x10        ;0001 0000    
        MOVWF  PORTB     ;0001 0000 RB4(RS)=1 RB5(R/W)=0 RB6(E)=0
        NOP                     ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms
HERE
        NOP
        GOTO   HERE

DWELL5ms
;DWELL 5ms
        MOVLW    0x7E  ;126
        MOVWF    DWELLA
        MOVLW    0x07  ;7
        MOVWF    DWELLB
        DECFSZ    DWELLA,F
        GOTO    $-1
        DECFSZ    DWELLB,F
        GOTO    $-3
        NOP
        NOP
        RETURN
 

Attachments

Last edited:

Thread Starter

Pencil

Joined Dec 8, 2009
272
Thanks for responding takao21203.

I have been searching feverishly to solve this problem.
I stumbled accross your site previously and found it to
be quite informative.

I am sure I must be making a basic mistake, either in the
coding or in the interpretation of the flow chart.
 

takao21203

Joined Apr 28, 2012
3,702
Well I can read assembler I used it for years.

There are some things missing in your source, such as configuration,
and information about clock frequency.

It is not clear what is the main code, where is the entry point etc.

And sometimes you comment 1mS, sometimes 1uS for the NOP.

What version of MPLAB do you use or something else? MPASM only?

It would also be helpful if you (in commented lines) write the I/O assigment, which LCD pins are connected to which PIC I/O pins.
It's written in line comments but I mean all together in one block at the top.

After power up it's required to wait 40mS or something like this!
And correct LCD reset is not guaranteed only if you power it directly via PIC I/O. If the reset was not correct, the flowchart from the website I linked must be followed.
 

takao21203

Joined Apr 28, 2012
3,702
Rich (BB code):
;DWELL 100ms (Wait for 15ms minimum after Vcc=4.5V)
        MOVLW    0xDF  ;223
        MOVWF    DWELLA
        MOVLW    0x82  ;130
        MOVWF    DWELLB
        DECFSZ    DWELLA,F
        GOTO    $-1
        DECFSZ    DWELLB,F
        GOTO    $-3
        NOP
        NOP
also is slightly incorrect, the inner loop pointer must be reloaded!

Rich (BB code):
 movlw c_loop_outer_count
 movwf DWELLA
l_loop_outer:
 movlw c_loop_inner_count
 movwf DWELLB

l_loop_inner:
 decfsz DWELLB,f
 goto l_loop_inner
 decfsz DWELLA,f
 goto l_loop_outer
 

Thread Starter

Pencil

Joined Dec 8, 2009
272
There are some things missing in your source, such as configuration,
and information about clock frequency.

And sometimes you comment 1mS, sometimes 1uS for the NOP.

It would also be helpful if you (in commented lines) write the I/O assigment, which LCD pins are connected to which PIC I/O pins.
It's written in line comments but I mean all together in one block at the top.
Added and fixed comments. See original code.

What version of MPLAB do you use or something else? MPASM only?
MPLAB v8.60
After power up it's required to wait 40mS or something like this!
And correct LCD reset is not guaranteed only if you power it directly via PIC I/O. If the reset was not correct, the flowchart from the website I linked must be followed.
That is the 100ms delay at the beginning.

As stated before, the automatic reset will work if I skip down to the
comment ";NO INITIALIZATION JUMP TO HERE" after the 100ms delay.

If I skip to comment mentioned above after the 100ms delay routine
the LCD will display the character "A" as I have programmed for a test.

If I run the entire program, without skipping the problematic code, LCD will display nothing.

To skip the part of the program that is problematic I insert a "CALL"
instruction after the 100ms delay and a label in the place of ";NO INITIALIZATION JUMP TO HERE".

also is slightly incorrect, the inner loop pointer must be reloaded!
The simulation shows the delay to be 100.005ms.
 
Last edited:

takao21203

Joined Apr 28, 2012
3,702
Yes I was thinking that you insert a goto.

All I can say is that the Hitachi LCD controllers are not intelligent, they have exact requirement at which point of time they can accept certain commands.

I founds these flowcharts helpful, and following them 1:1 resulted in working code.

Assembler really has the disadvantage that you have to change many lines.

To be 100% sure the LCD should only become powered up after values on PORTB have been established (for instance E=0). But I don't do that myself, and no problems from that.

If I read through your code, you don't follow this sequence 100%, at first yes, but then at some point, different.
http://elm-chan.org/docs/lcd/hd44780_e.html

Here is some old assembler code, where I use character LCD:

Rich (BB code):
l_lcd_init: ; initialize LCD display
 btfss v_status,c_status_lcd_cmd_st
 goto l_lcd_init_next ; get next command from table
 
 movf v_lcd_cmd_ints,w
 cpfsgt v_serial_ints ; refresh interrupts elapsed?
 return
 
 bcf v_status,c_status_lcd_cmd_st ; yes
 movlw d'4' ; next list element
 addwf v_lcd_offset,f
 return
  
l_lcd_init_next:
 bsf v_status,c_status_lcd_cmd_st ; enable refresh interrupt counter
 clrf v_serial_ints
 movlw high(l_lcd_init_data) ; load data table address
 movwf TBLPTRH,ACCESS
 movlw low(l_lcd_init_data)
 movwf TBLPTRL,ACCESS
 movf v_lcd_offset,w ; add offset
 addwf TBLPTRL,f,ACCESS
 btfsc STATUS,C,ACCESS
 incf TBLPTRH,f,ACCESS
 
 tblrd *+ ; read LCD data
 movff TABLAT,v_m_ioxp0
 
 movlw 0xff ; end of table?
 cpfseq TABLAT,ACCESS
 goto l_lcd_init_skip0
 bcf v_status,c_status_lcd_more ; no more list elements
 return
 
l_lcd_init_skip0: ; get refresh interrupt counts
 tblrd *+ ; how many refresh interrupts are needed for delay?
 movff TABLAT,v_lcd_cmd_ints

 tblrd *+ ; command or ASCII data?
 movff TABLAT,v_lcd_cmd ; this variable is used in refresh routine
 bcf v_m_ioxp1,d'0' ; at first, delay is needed, no command
 btfsc v_lcd_cmd,d'1' ; this is a special case which also is included
 bsf v_m_ioxp1,d'0' ; normally set command/data bit here

 return
  
l_lcd_init_data:
 dw 0x3000
 dw 0x0000 ; wait for 30 milliseconds (at least)
 dw 0x0138
 dw 0x0001 ; 5x7 font size, 2 lines 
 dw 0x010f
 dw 0x0001 ; display on, no cursor, no blink
 dw 0x0301
 dw 0x0001 ; clear the display
 dw 0x0106
 dw 0x0001 ; shift off, increment
 
 dw 0x0100+'P'
 dw 0x0003 ; ASCII data (test)
 dw 0x0100+'I'
 dw 0x0003
 dw 0x0100+'C'
 dw 0x0003
 dw 0x0100+' '
 dw 0x0003
 dw 0x0100+'1'
 dw 0x0003
 dw 0x0100+'3'
 dw 0x0003
 dw 0x0100+'k'
 dw 0x0003
 dw 0x0100+'5'
 dw 0x0003
 dw 0x0100+'0'
 dw 0x0003
 
 dw 0xffff
 dw 0x0000 ; end of lcd initialization sequence
it's incomplete but maybe you can follow the general idea to read the code from a table, so it's easier to change.

Particulary in your code, you seem to switch off the display, then immediately switch on again, then you set increment, then you set blink, and then you clear the display!

on the website:

3x enable with 0x30
then function set,
then display off,
then clear display,
then entry mode set,
then display on.

http://web.alfredstate.edu/weimandn/lcd/lcd_initialization/lcd_initialization_index.html

My suggestion is to write some assembler code to read "LCD commands" from a table, so you only have to modify this table, not the program code anymore!
 

Thread Starter

Pencil

Joined Dec 8, 2009
272
Particulary in your code, you seem to switch off the display, then immediately switch on again, then you set increment, then you set blink, and then you clear the display!

on the website:

3x enable with 0x30
then function set,
then display off,
then clear display,
then entry mode set,
then display on.

http://web.alfredstate.edu/weimandn/lcd/lcd_initialization/lcd_initialization_index.html

My suggestion is to write some assembler code to read "LCD commands" from a table, so you only have to modify this table, not the program code anymore!
The code after comment ";DISPLAY ON" is actually writing the instruction
for "Clear Display" (0x01). I wrote the comment because on the sheet
that I have, (the original paper that came with the display) that line
on the flow chart had that comment. This was a source of confusion
for me also until I figured it was a typo on the sheet. I corrected the
comment in the original post.

My (intended) sequence is as follows:
Delay 100ms
Function set (0x30)
Delay 5ms
Function set (0x30)
Delay 5ms
Function set (0x30)
Delay 5ms
Function set (0x38)
Delay 5ms
Display off (0x08)
Delay 5ms
Clear display (0x01)
Delay 5ms
Entry mode (0x06)
Delay 5ms
Cursor on, blink off (0x0E)
Delay 5ms
Clear display (0x01)
Delay 5ms
Start writing to display

I am beginning to think that if the display performs
the automatic initialization correctly it cannot be
commanded to "re-initialize". Am I correct?
 

takao21203

Joined Apr 28, 2012
3,702
This should not be the case.

Have you tried to power the LCD via PIC I/O?

And why you want to clear the display two times now?

The LCD glass can be powered directly, only the chip powered by PIC I/O.
 

Thread Starter

Pencil

Joined Dec 8, 2009
272
I finally figured it out.

Since it is a 2-line display the three (3) function
set commands at the beginning must be set for
a 2 line display, in addition to the fourth (4th) function
set command.

The corrected sequence is as follows:
Delay 100ms
Function set (0x38)
Delay 5ms
Function set (0x38)
Delay 5ms
Function set (0x38)
Delay 5ms
Function set (0x38)
Delay 5ms
Display off (0x08)
Delay 5ms
Clear display (0x01)
Delay 5ms
Entry mode (0x06)
Delay 5ms
Cursor on, blink on(0x0F)
Delay 5ms
Clear display (0x01)
Delay 5ms
Start writing to display

Corrected code snippet below:
Rich (BB code):
;PIC 16f690
;Internal Oscillator 4MHz (1Mhz instruction)
;DMC20261NY-LY 20x2 Character display

;PIN CONNECTIONS:
;__________________
;PIC            LCD
;__________________
;RB4            RS
;RB5            R/W
;RB6            ENABLE
;RC0-RC7       DB0-DB7

;****BEGIN INITIALIZE LCD****
;DWELL 100ms (Wait for 15ms minimum after Vcc=4.5V)
        MOVLW    0xDF  ;223
        MOVWF    DWELLA
        MOVLW    0x82  ;130
        MOVWF    DWELLB
        DECFSZ    DWELLA,F
        GOTO    $-1
        DECFSZ    DWELLB,F
        GOTO    $-3
        NOP
        NOP

;FUNCTION SET COMMAND (8-BIT INTERFACE)*1*
        MOVLW  0x38        ;0011 1000 *LOOK*
        MOVWF  PORTC     ;0011 1000 RC5(DB5)=1 RC4(DB4)=1 RC3(DB3)=1
        MOVLW  0x00        ;0000 0000    
        MOVWF  PORTB     ;0000 0000 RB4(RS)=0 RB5(R/W)=0 RB6(E)=0
        NOP                    ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                    ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

;FUNCTION SET COMMAND (8-BIT INTERFACE)*2*
        BSF    PORTB,6   ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                  ;WAIT 1us
        NOP                  ;WAIT 1us
        BCF    PORTB,6   ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;FUNCTION SET COMMAND (8-BIT INTERFACE)*3*
        BSF    PORTB,6   ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                  ;WAIT 1us
        NOP                  ;WAIT 1us
        BCF    PORTB,6   ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;FUNCTION SET COMMAND (8-BIT INTERFACE, LINES 2, FONT 5X7)
        MOVLW  0x38        ;0011 1000 0x38 *LOOK*
        MOVWF  PORTC     ;0011 1000 RC5=1 RC4=1 RC3=1 RC2=0
        BSF    PORTB,6     ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                    ;WAIT 1ms
        NOP                    ;WAIT 1ms
        BCF    PORTB,6     ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;DISPLAY OFF
        MOVLW  0x08        ;0000 1000
        MOVWF  PORTC     ;0000 1000 RC3=1 (DISPLAY OFF) 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;CLEAR DISPLAY
        MOVLW  0x01        ;0000 0001
        MOVWF  PORTC     ;0000 0001 RC0=1 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                    ;WAIT 1us
        NOP                    ;WAIT 1us
        BCF    PORTB,6     ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;SET ENTRY MODE (INCREMENT, NO DISPLAY SHIFT)
        MOVLW  0x06        ;0000 0110
        MOVWF  PORTC     ;0000 0110 RC2=1 RC1=1 RC0=0 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;DISPLAY ON OFF CONTROL (DISPLAY=ON, CURSOR=ON, BLINK=ON)
        MOVLW  0x0F        ;0000 1111
        MOVWF  PORTC     ;0000 1111 RC3=1 RC1=2 RC1=1 RC0=0 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

 ;CLEAR DISPLAY AND CURSOR HOME
        MOVLW  0x01        ;0000 0001
        MOVWF  PORTC     ;0000 0001 RC0=1 
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms     
;****END INITIALIZE LCD****

;TEST WRITE CHARACTER

;TEST CHARACTER R

;INSTRUCTION SET DD RAM ADDRESS
        MOVLW  0x8A      ;1000 1010 ADDRESS 0Ah
        MOVWF  PORTC     ;1000 1010 ADDRESS 0Ah
        MOVLW  0x00        ;0000 0000    
        MOVWF  PORTB     ;0000 0000 RB4(RS)=0 RB5(R/W)=0 RB6(E)=0
        NOP                    ;WAIT MINIMUM .14uS
        BSF    PORTB,6     ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)  
        NOP                    ;WAIT 1us
        NOP                    ;WAIT 1us
        BCF    PORTB,6     ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

;WRITE DATA
        MOVLW  0x52        ;0101 0010
        MOVWF  PORTC     ;0101 0001 CHARACTER=R 
        MOVLW  0x10        ;0001 0000    
        MOVWF  PORTB     ;0001 0000 RB4(RS)=1 RB5(R/W)=0 RB6(E)=0
        NOP                    ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                    ;WAIT 1us
        NOP                    ;WAIT 1us
        BCF    PORTB,6     ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

;TEST CHARACTER L

;INSTRUCTION SET DD RAM ADDRESS
        MOVLW  0xCA        ;1100 1010 ADDRESS 4Ah
        MOVWF  PORTC     ;1100 1010 ADDRESS 4Ah
        MOVLW  0x00        ;0000 0000    
        MOVWF  PORTB     ;0000 0000 RB4(RS)=0 RB5(R/W)=0 RB6(E)=0
        NOP                     ;WAIT MINIMUM .14uS
        BSF    PORTB,6      ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)  
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

;WRITE DATA
        MOVLW  0x4C        ;0100 1100
        MOVWF  PORTC     ;0100 1100 CHARACTER=L 
        MOVLW  0x10        ;0001 0000    
        MOVWF  PORTB      ;0001 0000 RB4(RS)=1 RB5(R/W)=0 RB6(E)=0
        NOP                      ;WAIT MINIMUM .14uS
        BSF    PORTB,6       ;x1xx xxxx RB6(E)=1 (ENABLE HIGH)
        NOP                     ;WAIT 1us
        NOP                     ;WAIT 1us
        BCF    PORTB,6      ;x0xx xxxx RB6(E)=0 (ENABLE LOW)
        CALL   DWELL5ms

DWELL5ms
       ;DWELL 5ms
        MOVLW    0x7E  ;126
        MOVWF    DWELLA
        MOVLW    0x07  ;7
        MOVWF    DWELLB
        DECFSZ    DWELLA,F
        GOTO    $-1
        DECFSZ    DWELLB,F
        GOTO    $-3
        NOP
        NOP
        RETURN
#%@&*! I lined up the comments nice and neat and look how they posted.

Thanks for all the help.:)
 
Last edited:

takao21203

Joined Apr 28, 2012
3,702
Interesting. According to the flowchart these bits are irrelevant for the reset. And that's also my experience.

So if you keep it like it is, and only modify the first three commands to 0x30, it won't work?

Interesting because if this is the case, indeed there might be a chip revision which always requires the correct bits for 2 lines.
 

Thread Starter

Pencil

Joined Dec 8, 2009
272
Interesting. According to the flowchart these bits are irrelevant for the reset. And that's also my experience.

Interesting because if this is the case, indeed there might be a chip revision which always requires the correct bits for 2 lines.
I know it is confusing. I cannot find a single reference to changing
any of the lower 4 bits, this includes the paper that was stuck in
with the display. (this display may be 10+ years old). I read the date
before I mounted it in my test fixture, but I cannot see it now.
It may have been 1993? Is this possible? The number on the chip
is HD44780A00 1B3.

My process of elimination included initializing as a 1-line and it worked.
Then I changed the first three commands from 0x30 to 0x38 and suddenly
it worked. Added the second test character and there it appeared.

As a note, if i tried to write a character to the second line when initialized
as a 1-line display the cursor disappeared. I never tried writing any
more instructions after the cursor disappeared so I don't know what
would happen.

So if you keep it like it is, and only modify the first three commands to 0x30, it won't work?
0x30 3 times and 0x38 1 time = does not work

0x30 4 times= works as 1-line

0x38 4 times= works as 2-line

Results are based on limited testing of writing a single character
in the middle of the line on each line.
 
Last edited:
Top