Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] [Moved] 8051 Assembler LCD Programming

Status
Not open for further replies.
Him

Thanks BigDog.

Corrected:

24MHz (clock)
24MHz / 6 (cycles per instruction clock) = 4MHz (instruction clock).
2 instruction clocks per dnjz = 2MHz => 500ns

500ns x 10 (mov R6, #10) gives 5.0us
5.0us + 250ns ( mov) additionally = 5.3us
5.3us x 10 (mov R7, #10) = 53.0us.
53us + some +verhead = maybe 55us
--> this is far away from the estimated 100us.
Now when we use SDelay and expect it to last 100us but indeed it takes only 55us then the delay is too short for the display. This may cause the display not to work correctely.
The same is with the other delay routines.

Please review my calculations. And correct the delay setup.

So the correct SDelay code should be:

Code:
SDelay: // 10x10 = 100us = 0.1ms
mov R7, #10
DS1:	mov R6, #10
DS2: NOP
NOP
djnz R6, DS2
djnz R7, DS1
ret

Please add the new label and the two NOPs to each delay routine.

Klaus
 

Him

Thanks BigDog.

Corrected:

24MHz (clock)
24MHz / 6 (cycles per instruction clock) = 4MHz (instruction clock).
2 instruction clocks per dnjz = 2MHz => 500ns

500ns x 10 (mov R6, #10) gives 5.0us
5.0us + 250ns ( mov) additionally = 5.3us
5.3us x 10 (mov R7, #10) = 53.0us.
53us + some +verhead = maybe 55us
--> this is far away from the estimated 100us.
Now when we use SDelay and expect it to last 100us but indeed it takes only 55us then the delay is too short for the display. This may cause the display not to work correctely.
The same is with the other delay routines.

Please review my calculations. And correct the delay setup.

So the correct SDelay code should be:

Code:
SDelay: // 10x10 = 100us = 0.1ms
mov R7, #10
DS1:	mov R6, #10
DS2: NOP
NOP
djnz R6, DS2
djnz R7, DS1
ret

Please add the new label and the two NOPs to each delay routine.

Klaus

Ok. you are correct, thank you alot for doing all of this for me. But to be honest, We can just try to make 50ms delay after every line. I made 500 ms before commands, 50ms to each command, 50ms to each data send and still LCD has black bars for 3seconds and then its disappearing and no single character displayed.

I made this code with your calculations:

Code:
EN EQU P1.3 // Enable Pin
RS EQU P1.2 // Register Select

// Setting Ports
mov P0,#0FFh // Setting P0 as Input
mov P2,#0E0h // Setting P2 as Output
setb P1.0
clr P1.2
clr P1.3
setb P3.6
setb P3.7
lcall LDelay
lcall LDelay
lcall LDelay
lcall LDelay

// Insure 8 Bit Mode
mov P0, #3Eh // Function Set
lcall SendCommand
lcall SendCommand
lcall SendCommand
lcall SendCommand

mov P0, #014h // Display Control
lcall SendCommand

mov P0, #0E0h // Entry mode set
lcall SendCommand

mov P0, #06h // Display Control
lcall SendCommand

mov P0, #01h // Clear Display
lcall SendCommand

mov P0, #'M'
lcall SendData

mov P0, #'A'
lcall SendData

mov P0, #'X'
lcall SendData

sjmp $

SendCommand:
clr RS // Setting 0 in RS (0=commands,1=data)
setb EN // Setting 1 in EN (pulse)
clr EN // Setting 0 in EN (send pulse)
lcall MDelay
ret

SendData:
setb RS // Setting 1 in RS (0=commands,1=data)
setb EN // Setting 1 in EN (pulse)
clr EN // Setting 0 in EN (send pulse)
lcall SDelay
ret

SDelay: // 10x10 = 100us = 0.1ms
mov R7, #10
DS1:	mov R6, #10
DS2: NOP
NOP
djnz R6, DS2
djnz R7, DS1
ret

SDelay: // 100x5 = 500us = 0.5ms
mov R7, #100
DS3:	mov R6, #5
DS4: NOP
NOP
djnz R6, DS3
djnz R7, DS4
ret

LDelay: // 200x250 = 50000us = 50ms
mov R7, #200
DS5:	mov R6, #250
DS6: NOP
NOP
djnz R6, DS5
djnz R7, DS6
ret

end

LCD is not showing a-thing.
 
Last edited:

Hi,

Your code of post #42 does not include my suggestions of
* post#22
* post#33

Klaus
 

Hi,

Your code of post #42 does not include my suggestions of
* post#22
* post#33

Klaus

Made it with more delays in the SendCommand and SendData and now the lcd showing black bars.. Still not initialized now and its because of the delay routine.. probably not working well.. my delay routine worked well.. the only issue is that the lcd is not displaying characters
 

Hi,

It's hard for me to review all your code again and again.

Your given datasheet for the display tells to keep the folowing minimum delays.
If you want the display to work properly, you must work according datasheet. There is no way around.
As said before: you may use longer delay times but you must not use shorter (no) delay times.

So please program all the 140/450/550 ns delay times.
(A single delay after the instructions is no alternative)

Code:
SendCommand:
clr RS // Setting 0 in RS (0=commands,1=data)
(Delay 140ns)
setb EN // Setting 1 in EN (pulse)
(Delay 450ns)
clr EN // Setting 0 in EN (send pulse)
(Delay  500ns)
ret

SendData:
setb RS // Setting 1 in RS (0=commands,1=data)
(Delay 140ns)
setb EN // Setting 1 in EN (pulse)
(Delay 450ns)
clr EN // Setting 0 in EN (send pulse)
(Delay  500ns)
ret

****
Mind to initialise your display with 0x0E instead of 0xE0.

****

Please show your code

Klaus
 

Hi,

It's hard for me to review all your code again and again.

Your given datasheet for the display tells to keep the folowing minimum delays.
If you want the display to work properly, you must work according datasheet. There is no way around.
As said before: you may use longer delay times but you must not use shorter (no) delay times.

So please program all the 140/450/550 ns delay times.
(A single delay after the instructions is no alternative)

Code:
SendCommand:
clr RS // Setting 0 in RS (0=commands,1=data)
(Delay 140ns)
setb EN // Setting 1 in EN (pulse)
(Delay 450ns)
clr EN // Setting 0 in EN (send pulse)
(Delay  500ns)
ret

SendData:
setb RS // Setting 1 in RS (0=commands,1=data)
(Delay 140ns)
setb EN // Setting 1 in EN (pulse)
(Delay 450ns)
clr EN // Setting 0 in EN (send pulse)
(Delay  500ns)
ret

****
Mind to initialise your display with 0x0E instead of 0xE0.

****

Please show your code

Klaus

As i said already, I made all those delays and other more delays with 50ms overall. The display doesn't show a thing.
 

Hi,

How can we know when your lates code shows this?

Code:
mov P0, [COLOR="#FF0000"]#0E0h[/COLOR] // Entry mode set
lcall SendCommand

Code:
SendCommand:
clr RS // Setting 0 in RS (0=commands,1=data)
[COLOR="#FF0000"][missing delay][/COLOR]
setb EN // Setting 1 in EN (pulse)
[COLOR="#FF0000"][missing delay][/COLOR]
clr EN // Setting 0 in EN (send pulse)
lcall MDelay
ret

We only can see what you show us.
******************

Back to the display:
code:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#55h[/COLOR] // Function Set
[COLOR="#FF0000"]sjmp $[/COLOR]
...
Confirm to see.
EN = 0, RS = 0, RW = 0, data = 0b 0101 0101

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#AAh[/COLOR] // Function Set
sjmp $
...
Confirm to see.
EN = 0, RS = 0, RW = 0, data = 0b 1010 1010

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#0Eh[/COLOR] // Function Set
[COLOR="#FF0000"]setb EN[/COLOR]
sjmp $
...
Confirm to see.
EN = 1, RS = 0, RW = 0, data = 0b 0000 1110

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, #0Eh // Function Set
setb EN
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]clr EN[/COLOR]
[COLOR="#FF0000"]setb RS // just for RS check[/COLOR]
sjmp $
...
Confirm to see.
EN = 0, RS = 1, RW = 0, data = 0b 0000 1110

Klaus
 

Hi,

How can we know when your lates code shows this?

Code:
mov P0, [COLOR="#FF0000"]#0E0h[/COLOR] // Entry mode set
lcall SendCommand

Code:
SendCommand:
clr RS // Setting 0 in RS (0=commands,1=data)
[COLOR="#FF0000"][missing delay][/COLOR]
setb EN // Setting 1 in EN (pulse)
[COLOR="#FF0000"][missing delay][/COLOR]
clr EN // Setting 0 in EN (send pulse)
lcall MDelay
ret

We only can see what you show us.
******************

Back to the display:
code:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#55h[/COLOR] // Function Set
[COLOR="#FF0000"]sjmp $[/COLOR]
...
Confirm to see.
EN = 0, RS = 0, RW = 0, data = 0b 0101 0101

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#AAh[/COLOR] // Function Set
sjmp $
...
Confirm to see.
EN = 0, RS = 0, RW = 0, data = 0b 1010 1010

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#0Eh[/COLOR] // Function Set
[COLOR="#FF0000"]setb EN[/COLOR]
sjmp $
...
Confirm to see.
EN = 1, RS = 0, RW = 0, data = 0b 0000 1110

next step:
Code:
...
// Insure 8 Bit Mode
mov P0, #0Eh // Function Set
setb EN
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]clr EN[/COLOR]
[COLOR="#FF0000"]setb RS // just for RS check[/COLOR]
sjmp $
...
Confirm to see.
EN = 0, RS = 1, RW = 0, data = 0b 0000 1110

Klaus

To insure the data gets to LCD i have decided to check the pins on the LCD itself and not port 0.
Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#55h[/COLOR] // Function Set
[COLOR="#FF0000"]sjmp $[/COLOR]
...
I see:
EN = 0,RS = 0, RW = 0, data 0101 0101

Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#0AAh[/COLOR] // Function Set
sjmp $
...
I see:
EN = 0, RS = 0, RW = 0, data = 1010 1010

Code:
...
// Insure 8 Bit Mode
mov P0, [COLOR="#FF0000"]#0Eh[/COLOR] // Function Set
[COLOR="#FF0000"]setb EN[/COLOR]
sjmp $
...
I see:
EN = 1, RS = 0, RW = 0, data = 0000 1110

Code:
...
// Insure 8 Bit Mode
mov P0, #0Eh // Function Set
setb EN
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]NOP[/COLOR]
[COLOR="#FF0000"]clr EN[/COLOR]
[COLOR="#FF0000"]setb RS // just for RS check[/COLOR]
sjmp $
...
I see:
EN = 0, RS = 1, RW = 0, data = 0000 1110

As for the overall code, here is the code i use without the testings:
Code:
EN EQU P1.3 // Enable Pin
RS EQU P1.2 // Register Select

// Setting Ports
mov P0,#0FFh // Setting P0 as Input

// Insure 8 Bit Mode
lcall LongDelay
lcall LongDelay
	
mov A, #38h // Function Set
lcall SendCommand
lcall Delay

mov A, #38h // Function Set
lcall SendCommand
lcall Delay

mov A, #38h // Function Set
lcall SendCommand
lcall Delay

mov A, #01h // Clear Display
lcall SendCommand
lcall Delay

mov A, #02h // Cusor Home
lcall SendCommand
lcall Delay

mov A, #06h // Entry mode set
lcall SendCommand
lcall Delay

mov A, #0Eh // Display Control #1
lcall SendCommand
lcall Delay

mov A, #14h // Display Control #2
lcall SendCommand
lcall Delay

mov P0, #'M'
lcall SendData
lcall Delay

mov P0, #'A'
lcall SendData
lcall Delay

mov P0, #'X'
lcall SendData
lcall Delay

SendCommand:
mov P0,A
clr RS // Setting 0 in RS (0=commands,1=data)
lcall Delay
setb EN // Setting 1 in EN (pulse)
lcall Delay
clr EN // Setting 0 in EN (send pulse)
ret

SendData:
mov P0,A
setb RS // Setting 1 in RS (0=commands,1=data)
lcall Delay
setb EN // Setting 1 in EN (pulse)
lcall Delay
clr EN // Setting 0 in EN (send pulse)
ret

Delay: // 100x20 = 2000us = 2 ms
mov R7, #100
D3: mov R6, #20
djnz R6,$
djnz R7,D3
ret

LongDelay: // 250x200 = 50000us = 50 ms
mov R7, #250
D4: mov R6, #200
djnz R6,$
djnz R7,D4
ret

And for the last time i have already said that im not using less then 2ms delays so its not effecting badly LCD, it needs 50~+ us you said. Well 2ms is more then enough!
I don't want to send to lcd 3e as function set i want 2 lines 8bit mode which is 38h! thats all i want and show characters. I'm not sure the connection i have made to LCD is correct by the data means.

Here is a little something i draw to show it:
My Connection.png
 

Hi,

I´m a bit stressed now.

I wonder if you really want us to help you.
You change multiple things without saying, giving multiple erros we can´t reproduce.

1) Your "Delay" says 2ms. But as discussed before it is far away from giving 2ms delay. You may use longer delay, but this gives shorter delay.
2) Your "LongDelay" says 50ms. But as discussed before it is far away from giving 50ms delay. You may use longer delay, but this gives shorter delay.
3) The datasheet tells to write 4 times the function set register (data 0x3E). But now you changed it to 3 times.
4) A "Cursor home" is useless after a "Clear display". But it is not wrong.
5) the order of initialisation is not like in the datasheet. May work, but I´m not sure. The safe way is to keep on the datasheet.
6) Now to transmit display data you say "mov P0, #'M' --> lcall SendData" but in "SendData" you overwrite P0 with the contents of A: "mov P0,A"
7) there is no STOP at the end of your main so the program runs into nirvana
8) "it needs 50~+ us you said." I can´t find this. If you are in doubt, please refer to the datasheet it is wiser than me.
9) "I don't want to send to lcd 3e as function set i want 2 lines 8bit mode which is 38h!". Yes, 0x38 is correct. (But since the datasheet says the lower three bits are "invalid bits" it makes no difference)
10) "I'm not sure the connection i have made to LCD is correct by the data means." --> Therefore I asked you to measure the signals at the display. The display is the point of interest, if you measure them else where you may possible hide some error.
11) I asked you to go to the debug routine of post#47. And I asked to give feedback ---> confirm correct pin values. But you did not.

So I´m asking you now: How to go on?
* with me --> then please step by step. And with feedback.
* with any other user in the forum
* or go your own way.

Klaus
 

Hi,

I´m a bit stressed now.

I wonder if you really want us to help you.
You change multiple things without saying, giving multiple erros we can´t reproduce.

1) Your "Delay" says 2ms. But as discussed before it is far away from giving 2ms delay. You may use longer delay, but this gives shorter delay.
2) Your "LongDelay" says 50ms. But as discussed before it is far away from giving 50ms delay. You may use longer delay, but this gives shorter delay.
3) The datasheet tells to write 4 times the function set register (data 0x3E). But now you changed it to 3 times.
4) A "Cursor home" is useless after a "Clear display". But it is not wrong.
5) the order of initialisation is not like in the datasheet. May work, but I´m not sure. The safe way is to keep on the datasheet.
6) Now to transmit display data you say "mov P0, #'M' --> lcall SendData" but in "SendData" you overwrite P0 with the contents of A: "mov P0,A"
7) there is no STOP at the end of your main so the program runs into nirvana
8) "it needs 50~+ us you said." I can´t find this. If you are in doubt, please refer to the datasheet it is wiser than me.
9) "I don't want to send to lcd 3e as function set i want 2 lines 8bit mode which is 38h!". Yes, 0x38 is correct. (But since the datasheet says the lower three bits are "invalid bits" it makes no difference)
10) "I'm not sure the connection i have made to LCD is correct by the data means." --> Therefore I asked you to measure the signals at the display. The display is the point of interest, if you measure them else where you may possible hide some error.
11) I asked you to go to the debug routine of post#47. And I asked to give feedback ---> confirm correct pin values. But you did not.

So I´m asking you now: How to go on?
* with me --> then please step by step. And with feedback.
* with any other user in the forum
* or go your own way.

Klaus

Klaus, you made alot of contribution, I'm tottaly respecting you by all means. I'm changing stuff quickly and trying alot of things not to make you stressed but because I don't have much time to complete this project, and this LCD is not cooporating with our coding. I'm myself stressed.
I have decided to go back on course with the testing you made and go step by step.
1) The delays you made implemented back.
2) Same.
3) Changed back to 4 & now written 0x3E.
4) Removed the instruction 0x02.
5) The order is now as in the datasheet.
6) Changed the data to transmit first to A and then to P0.
7) Added 'sjmp $' at the end of the last delay.
8) I ment as for the calculations you made for me with the instruction cycle time and we found out that the delays are shorther. I ment that if i'm using 2ms its more then enough.
9) True, didn't notice that, I'm sorry.
10) I'm actually pretty sure its the connections, but because the LCD not showing a thing then the data bus might be connected somewhat else? I fear this is the last solution?
11) I debug everything you asked me to, gave you results, Its the same as you wished they were, Port 0 & LCD pins showing the voltage 4.92v-5v when '1' and 0v-0.12v when '0'. Confirmed it all.

Heres the most updated code:
Code:
EN EQU P1.3 // Enable Pin
RS EQU P1.2 // Register Select

// Setting Ports
mov P0,#0FFh // Setting P0 as Input
setb P1.0
clr P1.2
clr P1.3
setb P3.6
setb P3.7

// 500ms Delay before initialization
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay
lcall LongDelay

// Initialization Instructions
mov A, #3Eh // Function Set
lcall SendCommand
lcall Delay
lcall SendCommand
lcall Delay
lcall SendCommand
lcall Delay
lcall SendCommand
lcall Delay

mov A, #14h // Entry mode set
lcall SendCommand
lcall Delay

mov A, #0Eh // Display Control #1
lcall SendCommand
lcall Delay

mov A, #06h // Display Control #2
lcall SendCommand
lcall Delay

mov A, #01h // Clear Display
lcall SendCommand
lcall Delay

// Data
mov A, #'M'
lcall SendData
lcall Delay

mov A, #'A'
lcall SendData
lcall Delay

mov A, #'X'
lcall SendData
lcall Delay

sjmp $

SendCommand:
mov P0,A
clr RS // Setting 0 in RS (0=commands,1=data)
lcall Delay
setb EN // Setting 1 in EN (pulse)
lcall Delay
clr EN // Setting 0 in EN (send pulse)
ret

SendData:
mov P0,A
setb RS // Setting 1 in RS (0=commands,1=data)
lcall Delay
setb EN // Setting 1 in EN (pulse)
lcall Delay
clr EN // Setting 0 in EN (send pulse)
ret

Delay: // 100x50 = 5000us = 5ms
mov R7, #250
DS1:	mov R6, #200
DS2: NOP
NOP
djnz R6, DS2
djnz R7, DS1
ret


LongDelay: // 250x200 = 50000us = 50ms
mov R7, #250
DS3:	mov R6, #200
DS4: NOP
NOP
djnz R6, DS3
djnz R7, DS4
ret

end

EDIT:
I've flashed the code above to the 8051 and the only difference is that at the end there black bars. There's no 2 lines of them, just one.. Its a big change because now with SJMP $ theres black bars and before there wasn't noting showen.
 
Last edited:

Hi,

I´m in hurry, only some minutes, then tomorrow...

First I have to apologise, I did not recognize your results in post#48. Sorry for this.

Those steps are very important and informative to find the error.

If there only is a little chance of uncertainty please go through the steps of post#47 again.
Measure directely at the display. Select display_gnd (pin1 ) as reference for the voltmeter.. (best is really to check all 14 pin voltage on every step)

If all the signals are correct at the display, then the display should work like expected. If it does not, then the display may be defective.
If you are sure all signals are like expected, then try another display.

Klaus
 

Hi,

I´m in hurry, only some minutes, then tomorrow...

First I have to apologise, I did not recognize your results in post#48. Sorry for this.

Those steps are very important and informative to find the error.

If there only is a little chance of uncertainty please go through the steps of post#47 again.
Measure directely at the display. Select display_gnd (pin1 ) as reference for the voltmeter.. (best is really to check all 14 pin voltage on every step)

If all the signals are correct at the display, then the display should work like expected. If it does not, then the display may be defective.
If you are sure all signals are like expected, then try another display.

Klaus

Okay checked with voltmeter, Found an error! I found out 0v on pin p0.2 and on the connection to the lcd its 5v.
Disconnecting LCD its turning into 0v. Connecting it back its turned into 5v. why lcd forcing pin d3 to 5v - '1' ??
I'll try fixing it.
 

Got to conclution that the connector i have causing it, I tried to use a pair of wires and my circuit got shorted. I'll get new connector soon and try it out. I'll update here.
 

Hello again, I haven't been here for a while & did not update the status of the lcd. Right now the LCD is working and showing characters.
Found out that VSS isn't 14 and VCC isn't 13. Its actually VCC-14 VSS-13. Which complety changes the pinout connection. It is making sense, since when RS was 0 it didn't initialize and when RS was 1 it shut off the display. The reason is actually it wasn't RS, it was RW, And EN was grounded.. :-|
How i found it out? Using the multimeter, I must check where is the starting pin, Figured it out, its VCC and not VSS.. If i check shortage it will clearly say there is, because i connected it worng, It doesn't mean there isn't & the problem would not be solved.

After long work with this, The problem wasn't delays & clock speed. It was just wrong pins connected. I'm sorry for making such a big thread on such a fearly fast fix.

I want to thank everyone who tried to help me, built with me the Delays.

KlausST - Did not give up on me & Helped me figure out the smallest problems which even if i'd found earlier the right pinout, I'd still need those fixs.
bigdogguru - Giving alot of information about how LCD should work, Got me smarter with this device.
FvM - Teaching me the "Nirwana" Mode. I never knew why i put SJMP $ untill you cleared it out, Now I will surely not forget the SJMP $ at the end of the program.

Me.jpg

Thanks again for anyone else who saw this thread and got intrested. :smile:

I gave points for each 3 of you on every thing you did for me. (Klaus I don't know how much to give points, i gave you 2 for 3 mainly stuff you did here. Thought on giving 5 but I'm first time trying this points system, I'm afraid to break the rules).
 
  • Like
Reactions: js

    js

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top