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.

89c4051 4-bit controlled LCD sporadic screwup

Status
Not open for further replies.

Pax Writer

New Member
Hi folks

Here's a pretty ungrateful question, which I hope some of you can help me out with:
I have a 89C4051 processor controlling an LCD-display (common HD44780 type) in the 4-bit mode (see attached picture).
Now, things seem to work out fine most of the time, but occasionally, the display is initiated in a bad way, and I get only garbled text on it. If I then hit the reset-button, it usually works fine.
I suspect there may be two sources of faults:
1. The length and type of wiring, which is ribbon cable of around 40-50cm.
or
2. The code, which I wrote my own interpretation of from the guidelines in the HD44780 data sheet.
Here's the code (its a subroutine written in assembler using Keil):
NOTE: Code is in capitals, comments in italics.
-------------------------------------------------------------

LCDINIT:
;Display init in 4-bit mode
MOV A,#15d
CALL WAIT_M ;Wait routine providing apprx. 15mS of waiting time, so that VCC may reach stable level, if this subroutine is the first in program to be executed.
CALL IN4 ;IN4 is an unused transciever-circuit address, which I use as "parking area" when I need to be sure that no unintentional port activity is influencing other relevant circuits.
CLR RS ;Register Select clearing to allow instruction to lcd.
CLR RW ;Displayet is put in write mode.
MOV A,#15d ;15mS wait-routine is set up...
CALL WAIT_M ;...And then executed.
MOV P1,#110000b ;Port 1 is set up as instructed in data sheet.
CALL LCDTOGGLE_L ;Toggle using lang wait time of apprx. 4mS.
CALL LCDTOGGLE ;Followed by two short toggles of apprx. 100uS.
CALL LCDTOGGLE
MOV P1,#100000b ;P1 is set up to instruct lcd to go in 4-bit mode.
CALL LCDTOGGLE ;lcd toggled to write instruction to lcd.
;Function set - 4-bit, 2-line, 5x8-font below:
MOV P1,#100000b ;Toggle of HI and LO nibble...
CALL LCDTOGGLE
MOV P1,#10000000b
CALL LCDTOGGLE
;Display set up below:
MOV P1,#00b
CALL LCDTOGGLE
MOV P1,#11000000b
CALL LCDTOGGLE
CALL LCDCLEAR
RET
----------------------------------------------------------------

For the sake of clarity I might add that WAIT_M is a subroutine for allowing waiting for a number of milliseconds as indicated by the value in the accumulator prior to calling the routine. The same goes for WAIT_U below.
I have also included LCDTOGGLE, LCDTOGGLE_L and LCDCLEAR subroutines below:

--------------------------------------------------------------------
LCDTOGGLE:
CALL LCD ;LCD enable
MOV ACC,#100d
CALL WAIT_U
CALL IN4 ;IN4 is used as "No Select"-address in this application
RET
--------------------------------------------------------------------

--------------------------------------------------------------------
LCDTOGGLE_L:
CALL LCD ;LCD enable
MOV ACC,#4d
CALL WAIT_M
CALL IN4

RET
--------------------------------------------------------------------

--------------------------------------------------------------------
LCDCLEAR: ;Deletes all display text and returns cursor home.
CLR RS ;As instructed in datasheet.
CLR RW ;As instructed in datasheet.
MOV P1,#00b ;0 is written to HI nibble
CALL LCDTOGGLE ;And then toggled.
MOV P1,#00010000b ;The required value to LO nibble is written.
CALL LCDTOGGLE ;And then toggled.

RET
--------------------------------------------------------------------

I know this is a rather big question. All comments about the code specifically or just general advice are welcome.
All questions will be answered as best possible.
 

Attachments

  • CPUandLCD.PNG
    CPUandLCD.PNG
    35.6 KB · Views: 274
Oh, I forgot to add, that I left out irrelevant parts of the schematic not to confuse any one. The LCDENABLE pin is tied to P3.3 on the CPU.
As for the board, it has been in use for a long time without the display, and has had no other flaws, so I have reason to believe that all wiring is OK, provided the display itself is wired right.
 
It would help if you put code tags around your code and included the low level routine LCD and a description of what IN4 does.

Mike.
 
Once I had this problem

Hi

Once I had this problem " lcd displays garbage when ever a switch is on (AC230v)" I am sensing AC by an opto coupler.

If not one of your data lines should be the problem

Regards
Nandhu
 
hi pax,
Are you waiting at least 40mSec after switching ON before you start the LCD init sequence? ..
If the Init seq is at the top/beginning of your program it could be trying to initialise the LCD during this mandatory wait time.

From what you describe, that sometimes the LCD runs OK, others times it comes up garbage,
its an indicator that the LCD is not being correctly initialised.

In a PIC, one method for the power on delay is to use the PWRTE in the config.

When you post code it would help if you post it in full, you could attach it as a asm or text file.

Regards
 
Hi all
Thanks for your response.
Some answers:
Pommie: I'm not sure I know what you mean by code tags. Do you have difficulties finding out what part of the text is code and what is comments (as written in the first post: "NOTE: Code is in capitals, comments in italics.").
The IN4-routine uses Port 3 on the CPU to select an unused circuit on the board (specifically a transciever functioning as the fourth in-port in the system), so I don't have problems with unintentional transitional states on Port 1, when switching between the relevant circuits. The display is controlled by Port 1 except for the enable pin, which is tied to P3.3 on the CPU. This is why I didn't explain IN4 more thoroughly.

Nandhu015: Good suggestion, but the turning on and off of AC230V does not affect the display. All signs seem to indicate that this is an issue with the initialisation rather than noise. This particular board was designed to use many different kinds of hardware, and has been in use without the display for a couple of years with no problems earlier, so I don't think that the data lines have a problem (although I can't rule it out, of course).

Ericgibbs: Well, your first question hits a sore point. As shown in the code
(LCDINIT:
;Display init in 4-bit mode
MOV A,#15d
CALL WAIT_M ;Wait routine providing apprx. 15mS of waiting time, so that VCC may reach stable level, if this subroutine is the first in program to be executed.)
... The initial waiting time is only 15 milliseconds.

The problem I experience is that when I start the kit, about half the time, it starts up showing garbage. I then hit the reset tact-switch and then the second init comes out alright and the display works properly for the duration of the session.
As for the complete code, I can paste it into a reply if necessary, but I chose only to show this subroutine at first because it is the only new addition to some software which was written for the board back when it was designed, and the rest of the code doesn't seem to have any problems (of course part of the problem is also that the code isn't optimised, and I don't particularly like the thought of publically flaunting my laziness :p - I'll do it, though, if you think its relevant to solve the problem).
 
A quick follow-up:
In response to Erics mail, I increased the initial waiting time to 50mS rather than 15mS, and initial tests show that the the error rate has fallen dramatically. The display now only mess things up in 1 of 8 cases, so I think from here on out, its just a matter of tweaking the code.
Thanks for the help.
 
Hi Pax

Check your code
Code:
CALL WAIT_M ;...And then executed.
MOV P1,#110000b ;Port 1 is set up as instructed in data sheet.
CALL LCDTOGGLE_L ;Toggle using lang wait time of apprx. 4mS.
CALL LCDTOGGLE ;Followed by two short toggles of apprx. 100uS.
CALL LCDTOGGLE
MOV P1,#100000b ;P1 is set up to instruct lcd to go in 4-bit mode.
CALL LCDTOGGLE ;lcd toggled to write instruction to lcd.
;Function set - 4-bit, 2-line, 5x8-font below:
MOV P1,#100000b ;Toggle of HI and LO nibble...
CALL LCDTOGGLE
MOV P1,#10000000b
CALL LCDTOGGLE

The first three mov P1,# has olny six bits !!!
What state (0 or 1) will your assemble assign to the two lowest bits?

I wait 250ms before sending anything to an LCD after power up and use 100ms delay between all initialize routines (FunctionSet, EntryMode). After that I use the busy flag to check the state of the LCD.

This is part of the main routine to initialize an LCD. I skipped declarations and subroutines :) If you're interested, let me know.
Code:
			mov  TH0,#HIGH Time_0		;initialize interrupts
                	mov  TL0,#LOW  Time_0
	        	mov  TMOD,#01H          	;timer 0 mode 1
                	setb ET0				;enable interrupt timer 0
			setb EA           
			setb TR0				;start timer 0
			
			mov  Delay,#25			;Delay 250 msec
L000:			mov  a,Delay
			jnz  L000
			
			
PowerUpLCD:		mov  LCD_1,#8			;Datalength 8 bits
			mov  LCD_2,#7			;Font 5*7 dots
			mov  LCD_3,#4			;Vier lijnen
			call LCD_FunctionSet
			
			mov  LCD_1,#1			;Cursor increment
			mov  LCD_2,#0			;No display shift
			call LCD_EntryMode
			
			mov  LCD_1,#01Fh			;Aanmaak user character 1 Af
			mov  LCD_2,#011h
			mov  LCD_3,#011h
			mov  LCD_4,#011h
			mov  LCD_Format,#11h		;Char 1 deel 1
			call LCD_SaveUserCharacter
			mov  LCD_1,#011h
			mov  LCD_2,#011h
			mov  LCD_3,#01Fh
			mov  LCD_4,#0
			mov  LCD_Format,#12h		;Char 1 deel 2
			call LCD_SaveUserCharacter
			
			mov  LCD_1,#00Eh			;Aanmaak user character 2 Aan
			mov  LCD_2,#00Eh
			mov  LCD_3,#00Eh
			mov  LCD_4,#00Eh
			mov  LCD_Format,#21h		;Char 2 deel 1
			call LCD_SaveUserCharacter
			mov  LCD_1,#00Eh
			mov  LCD_2,#00Eh
			mov  LCD_3,#00Eh
			mov  LCD_4,#0
			mov  LCD_Format,#22h		;Char 2 deel 2
			call LCD_SaveUserCharacter
			
			clr  a
			mov  LCD_1,a			;Aanmaak user character 3 Schakeltijd bereikt
			mov  LCD_2,a
			mov  LCD_3,#00Eh
			mov  LCD_4,#00Eh
			mov  LCD_Format,#31h		;Char 3 deel 1
			call LCD_SaveUserCharacter
			clr  a
			mov  LCD_1,#00Eh
			mov  LCD_2,a
			mov  LCD_3,a
			mov  LCD_4,a
			mov  LCD_Format,#32h		;Char 3 deel 2
			call LCD_SaveUserCharacter
			
			call LCD_ClearDisplay		;Clear display
			mov  LCD_1,#1			;Lijn 1
			mov  LCD_2,#1			;Positie
			mov  LCD_3,#0			;Tekst 0
			mov  LCD_4,#0			;0 msec tussen karakters
			call LCD_WriteText
 
Status
Not open for further replies.

Latest threads

Back
Top