Reading from a CFAG12864B

poteau

New member
Hello,

I know it's kind of weird to read from an LCD screen, but the pic I'm using doesn't have a lot of ram, so I can't store all the information on the PIC.

So anyways.. I need to read some information from the LCD screen... I've looked at the timing.. and came up with this code:

LCD_DATA = parallel bus to the LCD
I'm running a 40MHz clock... so wait = 100nS

Code:
ubyte LCD_RD_data(ubyte controller)
{
//returns data from the selected controller
	ubyte data = 0;
	LCD_DATA = 0x0F;
	LCD_DI = high;
	LCD_EN = high;
	LCD_RW = low;
	LCD_CS1 = high;
	LCD_CS2 = high;
	
	wait;
	wait;
	LCD_EN = low;
	wait;
	wait;
	LCD_RW = high;
	if (controller) LCD_CS1 = low;
	else LCD_CS2 = low;
	wait;
	wait;
	LCD_EN = high;
	wait;
	wait;
	data = LCD_DATA;

	wait;
	LCD_EN = low;
	LCD_RW = low;	

	return data;
}
data always comes up as 0x0F as I set it to in the beginning of the procedure.

As always... any help is very much appreciated.. Thanks.
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

poteau

New member
doh, I got it!

You are right, I forgot to set it as an input.. but also... I was setting the R/W low like the timing diagram showed... this caused it to write a random character to the screen. I removed it and it works great now!

Just because I couldn't find too much info on this on the forum, I'll put my working code...

Code:
ubyte LCD_RD_data(ubyte controller)
{
//returns data from the selected controller
	ubyte data = 0;

	
	LCD_DI = high;
	LCD_EN = high;
	LCD_RW = high;
	LCD_CS1 = high;
	LCD_CS2 = high;
	TRISD = 0xFF;

	LCD_EN = low;
	if (controller) LCD_CS1 = low;
	else LCD_CS2 = low;
	LCD_EN = high;
	wait_10(1);
	LCD_EN = low;
	data = LCD_DATA;


	LCD_EN = high;
	LCD_RW = low;	
	LCD_CS1 = high;
	LCD_CS2 = high;
	TRISD = 0x00;
	return data;
}
 

poteau

New member
Ok ok... after playing around.. this code would only work the first time.. once I started including it in loops it was giving crappy read backs and screwing up my display.

I was searching around the forum and discovered you need to pulse the enable 2x when reading from the LCD

so HERE is finally code that will work for you!

Code:
ubyte LCD_RD_data(ubyte controller)
{
//returns data from the selected controller
	ubyte data = 0;
	
	TRISD = 0xFF;
	wait_10(5);
	LCD_DI = high;
	LCD_RW = high;

	pulse_enable(controller);
	wait_10(5)
	LCD_EN = high;	
	wait_10(5);
	data = LCD_DATA;
	LCD_EN = low;
	wait_10(5);
	TRISD = 0x00;
	wait_10(5);
	return data;
	
}


void pulse_enable(unsigned char controller)
{
// controller 1 is for the left of screen, controller 2 is for right of screen 
// controller = 0 is for both
	LCD_CS1 = high;
	LCD_CS2 = high;
	switch(controller)
	{
		case 0:
			LCD_CS1 = low;
			LCD_CS2 = low;
			break;
		case 1:
			LCD_CS1 = low;
			break;
		case 2:
			LCD_CS2 = low;
			break;
	}

	LCD_EN = high;
	wait_10(1);
	LCD_EN = low;
	return;
}
 
Top