8051 Assembly Language LCD Display using AT89C2051 problem

Status
Not open for further replies.

corpuralx

Junior Member level 3
Joined
Oct 12, 2013
Messages
26
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
253
Good Day,

I would like to ask for help in troubleshooting my exercise experiment. I was trying to show a message in my 8x2 LCD display LM016L. The message in 1st line should be " R2K Technology " and in 2nd line is " MCU - Trainers ". The 2nd line won't show but the first line showed however with incorrect/random characters. The proteus also shows hundreds of errors saying "Attempted to write after reading a single nibble". I searched the web advising to add delays, i did but still the same. I noticed on the part of code calling "QUICK:", when i change R5, #100 to #1, the LCD shows R2K Tecf pE=Ew something like that, better than the previous one but still no 2nd line message. What part of code do you think would be the problem guys? In what line of code is the fault and the supposed correct right line of code? Thanks in advance.

Clock Frequency,
Crystal Oscillator: 11MHz
PIC: 11MHz
LCD LM016L: 250kHz

Here's the schematic:



Here's the code:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PROJECT NAME: MYEXPRT10A                                 ;
;FILENAME: EXPRT10A.A51                                   ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		
		P1			EQU	090H	;P1.0
		P1_1			EQU	091H	;P1.1
		P3			EQU	0B0H	;P3.0
		TL1			EQU   08BH
		TR1			EQU	08EH
		TF1			EQU   08FH
		TMOD			EQU	089H
		TH1			EQU	08DH
		SP			EQU	081H
		RS1			EQU	093H	;P1.3
		EN			EQU	0B2H	;P3.2	
		RW			EQU	0B7H	;P3.7
		BUSY_FLAG  		EQU	097H	;P1.7
		CLR_DISP		EQU	01H
		RET_HOME		EQU	02H
		DISP_OFF		EQU	08H
		DISP_ON		EQU	0CH
		CURSOR_ON		EQU	0EH
		BLINK_ON		EQU	0FH
		CODE_2X7		EQU	28H
		LINE1_START	EQU	080H
		LINE2_START	EQU	0C0H
					ORG	00H
					JMP	START
 ;;;;;;;;;;;;;;;; START INITIALIZATION;;;;;;;;;;;;;;;;;;;;;;;
START:
		CLR	P1
		CLR	P1_1
		CLR	093H        ;P1.3
		CALL	DELAY_15MS  ;DELAY ATLEAST 15MS
		CLR	EN          ;LCD CONTROLS TO LOW
		CLR	RS1
		CLR	RW
		MOV	A,#03H      ;1SEND CODE TO LCD
		CALL	SEND_2_LCD
		CALL	DELAY_5MS
		MOV	A,#03H	;2SECOND CODE TO LCD
		CALL	SEND_2_LCD
		CALL	DELAY_160US
		MOV	A,#03H	;3SECOND CODE TO LCD
		CALL	SEND_2_LCD
		CALL	DELAY_160US
		MOV	A,#02H		;SEND 4 BIT ENDTRY MODE
		CALL	SEND_2_LCD
		CALL	DELAY_160US
		MOV	A,#CODE_2X7	;SEND 16X2 CH 2 LINES
		CALL	SEND_COMMAND
		MOV	A,#DISP_ON	;TURN ON DISPLAY
		CALL	SEND_COMMAND
		MOV	A,#CLR_DISP	;CLEAR COMMAND
		CALL	SEND_COMMAND

;;;;;;;;;;;;;;;;;;;;INIITIALIZATION;;;;;;;;;;;;;;;;;;;;;;;;;;
DISPLAY_FIRST_LINE:
		MOV	SP,#07
		CALL	QUICK
		MOV	A,#LINE1_START	;FIRST LINE
		CALL	SEND_COMMAND
		MOV	DPTR,#MESSAGE1	;LINE1 MESSAGE
		MOV	R7,#16
DISPLAY_FIRST_LINE_LOOP:
		;CALL	QUICK
		CLR	A
		MOVC	A,@A+DPTR
		CALL	SEND_DATA
		INC	DPTR
		DJNZ	R7,DISPLAY_FIRST_LINE_LOOP
DISPLAY_SECOND_LINE:
		CALL	QUICK
		MOV	A,#LINE2_START	;2ND LINE
		CALL	SEND_COMMAND
		MOV	DPTR,#MESSAGE2	;LINE2 MESSAGE
		MOV	R7,#16
DISPLAY_SECOND_LINE_LOOP:
		;CALL	QUICK
		CLR	A
		MOVC	A,@A+DPTR
		CALL	SEND_DATA
		INC	DPTR
		DJNZ	R7,DISPLAY_SECOND_LINE_LOOP
		CALL	HALF_SEC_DELAY	;DISPLAY HALF A SECOND
BLANK_MESSAGE:
		MOV	A,#CLR_DISP		;CLEAR LCD DISPLAY
		CALL	SEND_COMMAND
		CALL	HALF_SEC_DELAY
		SJMP	DISPLAY_FIRST_LINE
;;;;;;;;;;;;;;;LCD RELATED ROUTINES;;;;;;;;;;;;;;;;;;;;;;;;;;
SEND_2_LCD:		
		SWAP	A
SEND_CODE:			
		SETB	EN
		ANL	P1,#0FH
		ORL	P1,A
		CALL	QUICK
		CLR	EN
		RET
SEND_COMMAND:
		CALL	READY			;BUSY FLAG
		CLR	RS1
		CLR	RW
		JMP	SEND_ROUTINE
SEND_DATA:
		CALL	READY
		SETB	RS1
		CLR	RW
SEND_ROUTINE:
		ORL	P3,#00111000B
		MOV	R6,A
		ANL	A,#0F0H
		CALL	SEND_CODE
		MOV	A,R6
		SWAP	A
		ANL	A,#0F0H
		CALL	SEND_CODE
		RET
READY:
		SETB	BUSY_FLAG
		CLR	RS1
		SETB	RW
KEEP_POLLING:
		CLR	EN
		CALL	QUICK
		SETB	EN
		JB	BUSY_FLAG,KEEP_POLLING
		RET
;;;;;;;;;;;;;;;;;DELAYS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DELAY_15MS:
		MOV	TH1,#0CAH
		MOV	TL1,00H
		ORL	TMOD,#01H
		CLR	TF1
		SETB	TR1
		JNB	TF1,$
		CLR	TF1
		CLR	TR1
		RET
DELAY_5MS:		
		MOV	TH1,#0EEH
		MOV	TL1,#00H
		ORL	TMOD,#01H
		CLR	TF1
		SETB	TR1
		JNB	TF1,$
		CLR	TF1
		CLR	TR1
		RET
DELAY_160US:
		MOV	TH1,0FFH
		MOV	TL1,60H
		ORL	TMOD,#01H
		CLR	TF1
		SETB	TR1
		JNB	TF1,$
		CLR	TF1
		SETB	TR1
		RET
HALF_SEC_DELAY:
		MOV	TH1,#0DCH
		MOV	TL1,00H
		ORL	TMOD,#01H
		CLR	TF1
		SETB	TR1
		MOV	R7,#180
DELAY_CONT:
		JNB	TF1,$
		CLR	TF1
		MOV	TH1,#0DCH
		DJNZ	R7,DELAY_CONT
		CLR	TR1
		RET
QUICK:
		MOV	R5,#100
		DJNZ	R5,$
		RET
;;;;;;;;;;;;;;;;;LOOK UP TABLES;;;;;;;;;;;;;;;;;;;;
MESSAGE1:	DB	' R2K Technology '
MESSAGE2:	DB	' MCU - Trainers '
END
 

This is working, you will have to change your pinout to match this code, OR
change the code.

ALSO: in your schematic, you do not have a resistor connected to pin 3 on the LCD. You should install a 10K pot
so you can adjust the contrast. Without this you may never see the test and you may think the code does not work!

Code:
;4 bit code tested & working
;
;LCD is connected to MCU in following way:
;D4 - P3.0
;D5 - P3.1
;D6 - P3.2
;D7 - P3.3
;EN - P3.7
;RS - P3.5
;RW connected to GND (only write operations)
;
$MOD51
;
lcd_port 	equ 	P3         ;LCD connected to Port3
EN 		equ 	P3.7       ;Enable connected to P3.7
RS 		equ 	P3.5       ;Register select to P3.5
;	
;-----------------------------------------------------
dcount	equ	08h		;
bytecount	equ	09h		;
temp		equ	0Ah		;
;
	ORG	0			;
Reset:
	sjmp	Start			;

Start:
	MOV	SP,#06FH		;
	MOV	A,#0FFH		;
	MOV	P0,A			;  
	MOV	P1,A			;
	MOV	P2,A			;
	MOV	P3,A			;
	
	call	lcd_reset
	call	lcd_init		;	
Main:	
	mov	dptr,#message1 	;Point to message
	lcall	WrLCD			;Transmit message

	mov a,#0C0H             ;move cursor to 2nd line
	call lcd_cmd           ;

	mov	dptr,#message2	;Point to message 
	lcall	WrLCD			;Transmit message

stop:
	sjmp	stop
;----------------------------------------------------------
message1:
db	'Hello There!    '

message2:
db	'How Are You?    '
;--------------Writes Text to LCD display --------------------
WrLCD:				;
	mov	bytecount,#16
WrLCD1LP:
	CLR	A
	MOVC	A,@A+DPTR		;get data to send to LCD
	INC	DPTR
	call	lcd_dat
	djnz	bytecount,WrLCD1LP
	RET				;	
;------------------------------------------------------------------
lcd_reset:                  ;LCD reset sequence
	mov lcd_port, #0FFH
	mov dcount,#20           ;20mS delay
	acall delay

	mov lcd_port, #83H      ;Data = 30H, EN = 1, First Init
	mov lcd_port, #03H      ;Data = 30H, EN = 0
	mov dcount,#15           ;Delay 15mS
	acall delay

	mov lcd_port, #83H      ;Second Init, Data = 30H, EN = 1
 
	mov lcd_port, #03H      ;Data = 30H, EN = 0
	mov dcount,#5            ;Delay 5mS
	acall delay

	mov lcd_port, #83H      ;Third Init 
	mov lcd_port, #03H
	mov dcount,#5            ;Delay 5mS
	acall delay

	mov lcd_port, #82H      ;Select Data width (20H for 4bit)
 
	mov lcd_port, #02H      ;Data = 20H, EN = 0
	mov dcount,#5            ;Delay 5mS
	acall delay
	ret
;------------------------------------------------------------------
lcd_init:
	acall lcd_reset         ;Call LCD Reset sequence
	mov a,#28H              ;4-bit, 2 line, 5x7 dots
 
	acall lcd_cmd           ;Call LCD command
	mov a,#0CH              ;Display ON cursor OFF
	acall lcd_cmd           ;Call LCD command
	mov a,#06H              ;Set entry mode (Auto increment)
 
	acall lcd_cmd           ;Call LCD command
	mov a,#80H              ;Bring cursor to line 1
	acall lcd_cmd           ;Call LCD command
	ret
;------------------------------------------------------------------
lcd_cmd:                  ;LCD command Routine
	mov temp,a            ;Save a copy of command to temp
	swap a                ;Swap to use higher nibble
	anl a,#0FH            ;Mask the first four bits
	add a,#80H            ;Enable = 1, RS = 0
	mov lcd_port,a        ;Move it to lcd port
	anl a,#0FH            ;Enable = 0, RS = 0
	mov lcd_port,a        ;Move to lcd port
 
	mov a,temp            ;Reload the command from temp
	anl a,#0FH            ;Mask first four bits
	add a,#80H            ;Enable = 1
	mov lcd_port,a        ;Move to port
	anl a,#0FH            ;Enable = 0
	mov lcd_port,a        ;Move to lcd port
 
	mov dcount,#1          ;delay 1 ms
	acall delay
	ret
 ;------------------------------------------------------------------
lcd_dat:                  ;LCD data Routine
	mov temp,a            ;Keep copy of data in temp
	swap a                ;We need higher nibble
	anl a,#0FH            ;Mask first four bits
	add a,#0A0H           ;Enable = 1, RS = 1
	mov lcd_port,a        ;Move to lcd port
	nop
	clr en                ;Enable = 0
 
	mov a,temp            ;Reload the data from temp
	anl a,#0FH            ;we need lower nibble now
	add a,#0A0H           ;Enable = 1, RS = 1
	mov lcd_port,a        ;Move to lcd port
	nop
	clr en                ;Enable = 0
 
	mov dcount,#1          ;Delay 1mS
	acall delay
	ret
;------------------------------------------------------------------
;1mS delay @11.0592 MHz
Time1mS:
	MOV   R2,#2
      MOV   R1,#221
tim1mS:
	DJNZ  R1,$
      DJNZ  R2,tim1mS
      RET
;------------------------------------------------------------------
Delay:
	call	Time1mS
	djnz	dcount,Delay
	ret
;------------------------------------------------------------------
END
 
I guess your code itself working...May be only the contrast problem. Always the LCD interface should be as in the image
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…