0
\$\begingroup\$

I'm working on this project using an 8051 micro controller (AT89S51) and it involves interfacting with an LCD. The schematic of the project I'm working on is shown below:

enter image description here

And I've written a very simple code for the LCD to display content. The code is as follows:

ORG 0000H
SJMP INIT_MAIN          ;For interrupts

INIT_MAIN:
      ;Initializing the LCD Display with the initial commands:
      MOV A, #38H       ;Setting up the LCD to operate in 8 bit mode
      ACALL CMD
      MOV A, #0FH       ;Turning the display on
      ACALL CMD
      MOV A, #01H       ;Clearing the curser 
      ACALL CMD
      MOV A, #06H       ;Putting the curser incriment mode to be left to right
      ACALL CMD
      MOV A, #3CH       ;Activating the second line of the LCD
      ACALL CMD
      MOV A, #80H       ;Putting the curser to be at position 1 (the first place)
      ACALL CMD

     ;Writing serially on the LCD
      MOV DPTR, #WELCOME1   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0C0H      ;Jump to second line position one
      ACALL CMD

      MOV DPTR, #WELCOME2   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #094H      ;Jump to third line position one
      ACALL CMD

      MOV DPTR, #WELCOME3   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #13H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0D4H      ;Jump to fourth line position one
      ACALL CMD

      MOV DPTR, #WELCOME4   ;Pointing the data pointer at the data array WELCOME1
      MOV 41H, #10H     ;Specifying the message's length
      LCALL LCD_SERIAL      ;Giving the command to the uC to print it on the LCD

      MOV A, #0FFH      ;Pointing the curser away from the screen
      ACALL CMD

MAIN:
      SJMP MAIN
;-------------------------------------DELAY SUBROUTINES-------------------------------------
DELAY_1ms:          ;delay for 1ms subroutine
      MOV 39H,#0FAH         ;Load 0FA into the register 39H
      MOV 40H,#0FAH     ;Load 0FA into the register 40H
      LABEL1: DJNZ 39H,LABEL1   ;Decrease 39H by one and jump if not zero
      LABEL2: DJNZ 40H,LABEL2   ;Decrease 40H by one and jump if not zero
      RET

;-------------------------------------LCD SUBROUTINES---------------------------------------
CMD:                    ;Commands used in intializations
      MOV P1, A         ;Move the values of A to Pin 1. These will be the commands we want to transfer
      CLR P3.5          ;This makes the RS equal to 0. When RS is zero, 
      CLR P3.6          ;This makes the RW equal to 0. When RW is zero,
      SETB P3.7         ;This control the latch. Setting it and resetting it, latches the data
      CLR P3.7          ;This control the latch. Setting it and resetting it, latches the data
      ACALL DELAY_1ms   ;A delay is required because on practical LCDs, it takes some time to change
      RET

LCD_SERIAL:             ;Used to display strings onto the LCD
      MOV R0, #00H
REPEAT:
      MOV A,R0
      MOVC A,@A+DPTR        ;obtain LCD lookup table
      ACALL LCD_DISPLAY     ;Display the character on the screen
      INC R0                ;Increment R0
      DJNZ 41H, REPEAT
      RET

LCD_DISPLAY:            ;Used to display info onto the LCD
      MOV P1, A         ;Move the values of A to pin 1. The data will now be on Port 1
      SETB P3.5         ;This makes RS equal to 1. When RS is one, 
      CLR P3.6          ;This makes the RW equal to 0. When RW is one,
      SETB P3.7         ;This control the latch. Setting it and resetting it, latches the data
      CLR P3.7          ;This control the latch. Setting it and resetting it, latches the data
      ACALL DELAY_1ms       ;A delay is required because on practical LCDs, it takes some time to change
      RET

;--------------------------------------LOOK UP TABLES---------------------------------------
WELCOME1:
DB 'WELCOME TO THE BANK'

WELCOME2:
DB 'PREVIOUS NUMBER 000'

WELCOME3:
DB 'YOUR NUMBER IS: ---'

WELCOME4:
DB 'HAVE A GOOD DAY!'


END

The above code is not the full code that I've written, but only the portions relevant to the LCD display.

This code works fine in the proteous simulation (as can be seen from the picture). However, it doesn't work at all when I construct it on a real circuit. Sometimes the LCD backlight would just turn on and nothing would be shown (not even black squares) even if I adjust the potentiometer. Sometimes, the black squares would show, but upon resetting the 8051 they'd disappear.

In case it matters, the programmer I'm using is the MikroE 8051 programmer,

I've done the following yesterday while constructing the circuit:

  1. Made sure that all of my jumpers were indeed conducting by checking them on an LED first.
  2. Tried this code with multiple LCD displays, none of them worked
  3. Tried this code on another 8051 chip, it still didn't work
  4. Got a sample code online of someone interfacing a 8051 with an LCD and my LCDs still didn't work

I would greatly appreciate it if someone could give me an insight on why this could be the case

\$\endgroup\$
2
\$\begingroup\$

The LCD controller might be in 4-bit mode, and even worse in the middle between the first nibble and the second. So your first command might not be understood. Send it 3 times to resolve any situation.

Additionally the real world LCDs have timing constraints. IIRC some of these need some more time than 1ms after initialize commands. Please read the data sheet of the specific part you use. The LCD might need some time to be ready to accept commands after power-up, too.

At last check that your delay is really 1ms.

\$\endgroup\$
1
\$\begingroup\$

Check your LCD datasheet again.

In all the LCD datasheets I have ground is on pin 1 , power is on pin 2 and contrast on pin 3.

\$\endgroup\$
  • \$\begingroup\$ Agree. All code notwithstanding, your Vss, Vdd, Vee seem incorrect. Proteus probably does not emulate these properly, if at all. \$\endgroup\$ – Soldersmoke Sep 8 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.