# Read data from 16x2 LCD using 89C52.

Thread Starter

#### ranjithrn

Joined Oct 11, 2011
2
hello,
I am trying out some experiments with a 16x2 LCD interfaced with 89C52.I am able to display data on the LCD.Now I found it a requirement to read data from LCD .I am using
P1.1=R/W
P1.2=RS.
P1.3=EN.
P1.4-P1.7=D4-D7.
Please send me the logic & code for the same.Thanks in advance.
rgds,
Ranjith.

#### t06afre

Joined May 11, 2009
5,934
hello,
I am trying out some experiments with a 16x2 LCD interfaced with 89C52.I am able to display data on the LCD.Now I found it a requirement to read data from LCD .I am using
P1.1=R/W
P1.2=RS.
P1.3=EN.
P1.4-P1.7=D4-D7.
Please send me the logic & code for the same.Thanks in advance.
rgds,
Ranjith.
I can not help since I do not use your micro. But would it not be wise to at least say what compiler/program language you use. You will also find how to do this in the LCD data sheet

Thread Starter

#### ranjithrn

Joined Oct 11, 2011
2
I can not help since I do not use your micro. But would it not be wise to at least say what compiler/program language you use. You will also find how to do this in the LCD data sheet
I am using keil C (V 9.02).

#### mackher

Joined Jul 25, 2010
3
Hi, did u get the code to read data from the LCD??

If so please let me know how it works.

Thanks in advance.

#### ErnieM

Joined Apr 24, 2011
8,055
There are 3 things you could read from the display:
- busy flag DB7
- display data (ie, the ASCII codes stored for the screen)
- character generator pixel data

To read these you set the RW line high

Rich (BB code):
RS RW    Function
0  1    Read Busy Flag DB7
1  1    Read Data
What data you read is determined by setting the address.
This changes which and where the data is read from:

Rich (BB code):
RS RW DB7 DB6    Function
0  0  0   1    set CGRAM (pixel) address   (64-127)
1  1  1   -    set DDRAM (ASCII) address  (128-255)
It's all on the data sheet.

I've always found this page to be very helpful: LCD Info Page by Dincer Aydin

#### mackher

Joined Jul 25, 2010
3
Thank you very much for your reply Sir. I have been trying to get my code working from the time you posted your reply. Below is my code which is not working as expected:

unsigned char read_lcd()
{
unsigned char r;
regsel = 1;
readwrite = 1;
enable = 0;
enable = 1;
lcd_shortdelay();
r = P0;
return r;
}

The point that i'm not getting is that, how do you set the address in the code before you read?
Also, even if you were able to read successfully from DDRAM, what would be the format of the data read? Will it be in binary or ascii?

If possible please help Sir.

Thanks in advance.

#### ErnieM

Joined Apr 24, 2011
8,055
The code you posted looks fine. The devices return the same data bit for bit you wrote, either for the character bitmaps (simple bits) or the character codes (basically ASCII).

Are you using a 4 bit or 8 bit data path?

Is your display responding at all? Can you write anything on the screen?

And stop calling me "sir." Makes me feel as old as I really am.

#### mackher

Joined Jul 25, 2010
3
Hi friend thank you for the reply.

I'm using 8-bit data path. Also i'm able to display characters properly. The only problem is reading them back into a variable.

#### MrChips

Joined Oct 2, 2009
21,846
There is a common misunderstanding between binary and ASCII. If you have to ask what is the difference then it is an indication that you do not fully understand the difference.

ASCII is binary.

#### MrChips

Joined Oct 2, 2009
21,846
Usually the same mcu port is used to interface to the LCD for both read and write operations.
Make sure that you configure the port as input or output as required for a read or write operation, respectively.

#### ErnieM

Joined Apr 24, 2011
8,055
Great. If you can display characters then the LCD is initialized properly. So it is just a code issue.

The one issue I did not like in your code is you leave the E enable line active (high) when you have completed a command. I use a library of functions from Microchip (that of course I've modified) for LCD and this is the order of operations that the library reads the devices:

Rich (BB code):
unsigned char read_lcd()
{
unsigned char r;
regsel = 1;
readwrite = 1;
Delay500nS();
enable = 1;        // activate the enable
Delay500nS();
r = P0;
enable = 0;        // disable the enable
return r;
}
I don't think that is your issue but something to consider before calling the work "all done."

MrChips point about the direction of the Port is well taken. I don't use the 89C52 so I can't check that. Does "regsel = 1;" make that port an input port? That is what need to be right there.

The point that i'm not getting is that, how do you set the address in the code before you read?
Do you have routines to set WHERE on the display the characters appear? That is setting the DDRAM address which determines where the letters appear. It also sets where you could be reading characters.

#### astrotom

Joined Jul 14, 2012
16
I am not sure here as I have never read from an lcd before, but don't you have to set the cursor back to beginning of line 1 to read anything? After the write operation, the cursor is set at the end. So there is no data to read i guess? So set the cursor back to beginning by passing 0x80 as a hex data to the command register. I am not sure if this works. This is just something I learned from file i/o in c++.

#### ErnieM

Joined Apr 24, 2011
8,055
I am not sure here as I have never read from an lcd before, but don't you have to set the cursor back to beginning of line 1 to read anything? After the write operation, the cursor is set at the end. So there is no data to read i guess? So set the cursor back to beginning by passing 0x80 as a hex data to the command register. I am not sure if this works. This is just something I learned from file i/o in c++.
Yes you typically have to do that. When you write characters into the display the internal character address will either automatically increment or decrement (you can set it either way) for every character written. So you do indeed have to set the DDRAM address to where you want to start reading from.

AFAIK the pixel data address CGRAM will only auto increment but the same applies: you need to point it to where you wish to begin reading.

For the 4 line display I used the lines live at these addresses:

Rich (BB code):
#define LINE_1  0x80  // home first line
#define LINE_2  0xC0  // home second line
#define LINE_3  0x94  // home third line
#define LINE_4  0xD4  // home fourth line