Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Interfacing LCD with 8951

Status
Not open for further replies.

panadol

New Member
Hi, im new to 8951. I am interfacing a LCD to a 8951, however it doesnt seems to work...can anyone help me check my program?
im using 11.059Mhz crystal and 30pF cap.

Code:
Here Data pins D0-D7 are connected to port1.0-port1.7 of 8951 microcontroller. 

Enable pin, RS are connected to P3.3 and P3.4 of 8951 respectively. 
R/W is connected to p3.5

      ORG 0H

      mOV     TmOD,#20H   ;Timer 1 in mode 2 
      mOV     TH1,#-3     ;9600 baud rate 
      SETB    TR1         ;Start timer 1 
      mOV     SCON,#50H   ;8-bit, 1 stop bit, REN enabled


      MOV A,#38H                           ; initialization LCD 2lines, 5x7 matrix.
      ACALL COMMAND                	   ; call command subroutine.
      MOV A,#0EH                           ; display on, cursor on
      ACALL COMMAND                
      MOV A,#01H                           ; Clear LCD
      ACALL COMMAND 
      MOV A,#06H                           ; shift cursor right
      ACALL COMMAND
      MOV A,#80H                           ; cursor at beginning of 1st line
      ACALL COMMAND
      MOV A,#'E'                             ; display letter E 
      ACALL DATA
      MOV A,#'D'                             ; display letter D
      ACALL DATA
      MOV A,#' '                             ; display space
      ACALL DATA
      MOV A,#'T'                             ; display letter T
      ACALL DATA
      MOV A,#'E'                             ; display letter E
      ACALL DATA
      MOV A,#'S'                             ; display letter S
      ACALL DATA
      MOV A,#'T'                             ; display letter T
     
 
HERE:  JMP HERE
 
COMMAND:   CALL READY  ; check whether LCD is ready
                       MOV P1,A        ; Send command to LCD
                       CLR P3.4          ; RS=0 for command
                       CLR P3.5          ; R/W=0 for write
                       SETB P3.3        ; E=1 for high pulse
                       CLR P3.3          ; E=0 for H-to-L pulse
                       RET

DATA:            CALL READY  ; check whether LCD is ready
                       MOV P1,A        ; Write data to LCD
                       SETB P3.4        ; RS=1 for data
                       CLR P3.5          ; R/W=0 for write
                       SETB P3.3        ; E=1 for high pulse
                       CLR P3.3          ; E=0 for H-to-L pulse
                       RET

READY:          SETB P1.7        ; make P1.7 input port
                       CLR P3.4          ; RS=0
                       SETB P3.5        ; R/W=1 for read
UP:                 SETB P3.3        ; E=1 for high pulse
                       CLR P3.3          ; E=0 for H-to-L pulse
                       JB P1.7, UP      ; stay until LCD is busy
                       RET

thank you vry much!!!
 
Last edited:
Did you read the datasheet of the LCD display?
I gess not :(

I assume it's a Hitachi HD44780 driver.

Check fig 23 on page 45, you will see the power up sequence of the controller.
You can't check the busy flag at the beginning of the initialisation sequence! You have to wait a certain amount of time.
 

Attachments

  • HD44780.pdf
    322.1 KB · Views: 410
ooh i see i see....
means i have to wait at least 15ms+4.1+100us after power up before checking the busy flag correct?
if just just put a delay right after i power up the microcontroller +lcd for 1 second, it should be sufficient for delay right?
basically just have to wait until its power initialization to ends before the flag is available for checking.right?
im not vry good in 8951,i duno how long it takes to run 1 instruction...
thanks
 
Last edited:
EricG

Hi panadol,
The problem is that you not allowing sufficient time
during initialising the LCD controller.
The controller is not high speed, depending upon your
xtal clock, you may need to pad out your read,write,ready subs with nops.

Send the 0x33 init cmd 3 times with a delay in between each
0x33 call.
The READY bit 7 cannot be read before the first 3, #38 periods.
[ my comments are in lower case]

If you need more info send me a PM
EricG

' 0x38 cmd is for 8 bit, 4 line lcd

MOV A,#38H ' 0x33 ; initialization LCD 2lines, 5x7 matrix
ACALL COMMAND ;init strobe
'wait 5 milliSec
'repeat
MOV A,#38H ' 0x33
ACALL COMMAND ;init strobe
'wait 5 milliSec
'repeat
MOV A,#38H ' 0x33
ACALL COMMAND; function set
'call READY

MOV A,#0EH ; display on, cursor on
ACALL COMMAND
MOV A,#01H ; Clear LCD
ACALL COMMAND
MOV A,#06H ; shift cursor right
ACALL COMMAND
MOV A,#80H ; cursor at beginning of 1st line
ACALL COMMAND

MOV A,#'E' ; display letter E
ACALL DATA
MOV A,#'D' ; display letter D
ACALL DATA
MOV A,#' ' ; display space
ACALL DATA
MOV A,#'T' ; display letter T
ACALL DATA
MOV A,#'E' ; display letter E
ACALL DATA
MOV A,#'S' ; display letter S
ACALL DATA
MOV A,#'T' ; display letter T


HERE: JMP HERE

COMMAND: CALL READY ; check whether LCD is ready
MOV P1,A ; Send command to LCD
CLR P3.4 ; RS=0 for command
CLR P3.5 ; R/W=0 for write
SETB P3.3 ; E=1 for high pulse
CLR P3.3 ; E=0 for H-to-L pulse=write
RET

DATA: CALL READY ; check whether LCD is ready
MOV P1,A ; Write data to LCD
SETB P3.4 ; RS=1 for data
CLR P3.5 ; R/W=0 for write
SETB P3.3 ; E=1 for high pulse
CLR P3.3 ; E=0 for H-to-L pulse=write
RET

READY:
wait 1 mSec
SETB P1.7 ; make P1.7 input port
CLR P3.4 ; RS=0
SETB P3.5 ; R/W=1 for read

UP: SETB P3.3 ; E=1 for high pulse
CLR P3.3 ; E=0 for H-to-L pulse

JB P1.7, UP ; stay until LCD is busy
p1.7 needs to an output now.

RET
 
Hmmm...thanks for the reply,so i have to send the same command 3 times before i jump into checking the busy flag.can i just delay a long period after power up?anyway, i dunno how to calculate to make the controller delay for 5ms....

besides why do i have to wait for 1ms at the ready part?
"p1.7 needs to an output now." this is for?do u mean i have to make it an output now....I tot it will be output automatically once i write something to it.

How long is a NOP?its 1 cycle,im using 11.052Mhz crystal...how to calculate its delay?thanks

thank you vrymuch.
 
Last edited:
Hi panadol,
As you have an xtal at 11+mHz, say 12mHz, if the internal cycle time for an instruction
is the xtal/4, your Tcyc time will be 250 nSec. If you have a Hitachi lcd datasheet, check
the minimum timing requirements for the lcd controller. eg; the E-nable Tcyc is 1uSec and the
E-nable pulse width is 450nSec. This is why I suggested NOP's to lengthen some of the signals
to the lcd. eg; set Enb high, nop,nop, set Enb low, this will give close to a 1uSec enable
pulse, assuming a 250nSec Tcyc.

To code a delay loop, a common way is to have two nested byte count down loops.
[its not the only way]

eg:
load a reg1 with say, .100' 100 deci
load a reg2 with say, .250
save the regs,
call the routine,

loop1:
count down reg2 to zero, using a zero detect for reg2.
'[loop2 delay is the 'approx' sum of all the Tcyc's in loop2, times the number of times round loop2]
'say the sum of loop2 Tcyc is 2000nSec * 250loops = 500 microSec/loop

count down reg1 by 1
if reg1 not zero then reload reg2, goto loop1
'[loop1 delay is the 'approx' loop2 delay, times the number of times round loop1
'say the number of times round loop1 is 100, so 500uSec * 100 = 50000uSec == 50milliSec.

return

NOTE:
as described, these are not the precise time delays, but are close enough to give you
an idea on how delays can be achieved using loops.
Determine your Tcyc for different instructions, calculate the sums and products within
the loops to give you a delay time for that routine. Remember you can repeat call the routine
to give you an approx double delay time. etc. Later on you could consider writing a delay macro.

eg: call waitms 5' the value being in millisec
call waitms 10 ' etc


I program the microchip PIC controllers, which have different characteristics from
the 8951. A PIC port pin needs to set for Input or Output as required by the program, before
it is accessed. Thats why I queried the bit state. Ive downloaded a copy of the 8951 sheet
for ref, in case I can help further.

Regards
EricG
 
Wow, very detailed one..THANKS!

If im not wrong...each machine cycle will be 1us.(xtal = 12Mhz, each machine cycle = 1us)...hence since NOP is one cycle, it will be 1us.

if each cycle will be 1us, if i wana clocked out the command,
i can simply just:
setb en
clr en
right?
anyway, for safety sake, i will put a delay in between.
Thanks for explaining the delays in detailed!

I have changed my program to somehting like that
Code:
;*******************************************************************************
;		D0-D7 connect to P1.0-P1.7
;		En connect p3.3
;		RS connect p3.4
;		RW connect p3.5
;*******************************************************************************

      
;*******************************************************************************
;		INITIALIZE THE MICROCONTROLLER
;*******************************************************************************
      ORG 0H      
      MOV     TmOD,#20H   		      ;Timer 1 in mode 2 
      MOV     TH1,#-3     		      ;9600 baud rate 
      SETB    TR1         		      ;Start timer 1 
      ACALL   DELAY                          ;Delay to wait at lest 15mili second for LCD before any initialization.
      
;*******************************************************************************
;		INITIALIZE THE LCD
;*******************************************************************************
      MOV A,#30H			      ; Set 8 bit interface
      ACALL COMMAND
      ACALL   DELAY                          
      MOV A,#0DH			      ; DISPALY & CURSOR: SET TO DISPLAY ON; CURSOR UNDERLINE OFF; CURSOR BLINK ON
      ACALL COMMAND
      ACALL   DELAY
      MOV A,#38H                              ; initialization LCD 2lines, 5x7 matrix.
      ACALL COMMAND                	      ; call command subroutine.
      ACALL   DELAY
      MOV A,#01H                              ; Clear LCD
      ACALL COMMAND 
      MOV A,#07H                              ; Shift display left
      ACALL COMMAND
      ACALL   DELAY
      MOV A,#80H                              ; cursor at beginning of 1st line
      ACALL COMMAND
      ACALL   DELAY

;*******************************************************************************
;		DATA TO BE SEND
;*******************************************************************************     

      MOV A,#'E'                              ; display letter E 
      ACALL DATA
      MOV A,#'D'                              ; display letter D
      ACALL DATA
      MOV A,#' '                              ; display space
      ACALL DATA
      MOV A,#'T'                              ; display letter T
      ACALL DATA
      MOV A,#'E'                              ; display letter E
      ACALL DATA
      MOV A,#'S'                              ; display letter S
      ACALL DATA
      MOV A,#'T'                              ; display letter T

;*******************************************************************************
;		PROGRAM WILL NON-STOP LOOPING HERE
;*******************************************************************************     
 
HERE:  JMP HERE
 
;*******************************************************************************
;		COMMAND SUBROUTINE TO INITIALIZE LCD
;*******************************************************************************

COMMAND:   	
	ACALL   DELAY
	CALL READY              ; check whether LCD is ready
                       CLR P3.4         ; RS=0 for command code register
                       CLR P3.5         ; R/W=0 for write		       
		       MOV P1,A        	; Send command to LCD
		       SETB P3.3        ; E=1 for high pulse
			ACALL   DELAY 
                       CLR P3.3         ; E=0 for H-to-L pulse to end the command
                       RET
;*******************************************************************************
;		DATA SUBROUTINE FOR SENDING DATA TO LCD
;*******************************************************************************

DATA:   ACALL   DELAY         
	CALL READY             ; check whether LCD is ready
                       SETB P3.4        ; RS=1 for data       
		       CLR P3.5         ; R/W=0 for write
		       MOV P1,A        	; Write data to LCD
                       SETB P3.3        ; E=1 for high pulse
			ACALL   DELAY 
                       CLR P3.3         ; E=0 for H-to-L pulse
                       RET

;*******************************************************************************
;		READY SUBROUTINE TO CHECK LCD STATUS
;*******************************************************************************

READY:         	       
	ACALL   DELAY              
		       SETB P1.7        ; make P1.7 input port
                       CLR  P3.4        ; RS=0, select command code register
                       SETB P3.5        ; R/W=1 for read
	UP:            SETB P3.3        ; E=1 for high pulse
			ACALL   DELAY 
                       CLR  P3.3        ; E=0 for H-to-L pulse to end the command
                       JB   P1.7, UP    ; loop until LCD is busy
                       RET		; Return once p1.7 is 0
;*******************************************************************************
;		DELAY
;*******************************************************************************
DELAY:                MOV R2,#XXH      
D1:                   MOV R3,#XXH
D2:                   DJNZ R3,D2
                      DJNZ R2,D1 
                      RET
END

i havent calculate the total delay in the DELAY subroutine,i will do it later.I was thinking that should i put in some delay in the DATA subroutine as well.
will burn the chip tmr and test it tmr in the lab too.....
THANKS ERIC!!!!
 
I have added delays in the program. delay after every command to make sure that the LCD is ready and not busy. The delay i used was 142ms.....

however, there isnt any output from my lcd at all. I suspect the problem is from my 8951.

I wrote a fairly simple program like this:
org 0h
mov p1,#0f3h
end

i checked this using LED,but it did not work at all. i think the problem is the initialiation of 8951.

I am using 11.0592Mhz 33pF, EA pin is connected to 5V. i duno is there any problem with this circuit connection.
I do not know how to initialize a 8951 properly to make it work, i tried using timer mode 1 and 0 , it also did not work. No output from microcontroller at all...

anyone can suggest me the way to connect the circuit?and how to initialize the microcontroller?Do i need to initialize timer?...
thanks...
 
A µC require an endless loop :)
You do'nt have that with your "fairly simple program" :(

You better write something like
Code:
org 0
loop:
nop
nop
nop
mov p1,#000h
nop
nop
nop
mov p1,#001h
jmp Loop
END

And check pin 0 of port 0 with a scope or multimeter, not a LED
A scope will give you a nice square wave.
A multimeter will give you 1/2 Vcc.
A LED will give you nothing because it flashses way too fast.


About the timings for your LCD (and other things in future programs) I suggest that you configure timer 0 for an auto reload 10ms timer.
Every 10 ms the ISR for Timer 0 will be executed.
Define one byte of internal RAM "Delay"
When you need a delay in your main program set Delay to x times 10ms (max 255 equals max 2550ms) and write a small loop that check the value of Delay

Code:
mov Delay,#10   ;100ms delay
MyDelay:
mov a,Delay
jnz  MyDelay

_100msLater:

In the ISR of T0 check the value of Delay
When it's > 0 decrement it
When it's 0 do nothing with it


Search my other posts and you will find some code and schematics for 8051 based µC and LCD...
 
somehting weird here, my '1'(high) output from 8951 is only 1.8v, and low is 0.1v....why is the voltage so low?????
i connect Vcc to 5 volts...
 
A little bit more information please... ...

Because you do something wrong :( :)

What is your hardware look like?
How do you measure, scoop, multimeter?
What is the code in the µP?

If you don't share the details, we can't help you further...
 
Hi. panadol, I'm not very active here but I saw that you needed using lcd interface with MCS51 Core. I have lived a problem like this before and solved. So I think this tutor will be good for you if you visit.
**broken link removed**
**broken link removed**
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top