Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
03/28/10 17:37
Read: times


 
#174569 - nothing displayed on graphical lcd using P89V51rd2.
Hi
My name is Prachi Khadke. I am a student of B.E. IT. We (my group) are doing a project that involves a bit of hardware. We are interfacing a 128x64 LCD to a P89V51rd2. I have attached the link to the datasheets of the lcd and (ABG128064A15-BIW-R) its controller (S6B0108B) with this post.

The connections are explained as follows ( i can't seem to be able to upload a diagram here):

RST = P3.2
CS2 = P3.3
CS1 = P3.4

E = P1.2
RW = P1.3
RS = P1.4

DB0 = P0.7
DB1 = P0.6
DB2 = P0.5
DB3 = P0.4
DB4 = P0.3
DB5 = P0.2
DB6 = P0.1
DB7 = P0.0




The architecture, the instruction set and the read,write cycles for S6B0108B are the same as that for the famous KS0108 lcd controller. i compared them. i studied them thoroughly. i also googled a lot of code on various sites and wrote the following code based on my understanding. it is not 100% mine.


//***************************************************************//
//			DECLARATIONS AND DEFINITIONS						 //
//***************************************************************//


//---------------------------------------------------------------//
//			    Function Prototypes								 //
//---------------------------------------------------------------//

void GLCD_LcdInit();
void GLCD_ClearScreen();
void GLCD_Rectangle(unsigned char,unsigned char,unsigned char,unsigned char);

//---------------------------------------------------------------//
//				Hardware										 //
//---------------------------------------------------------------//
sbit LCD_RS = P1^4;
sbit LCD_RW = P1^3;
sbit LCD_E = P1^2;
sbit LCD_CS1 = P3^4;
sbit LCD_CS2 = P3^3;
sbit LCD_RST = P3^2;
#define LCD_DATA P0

//---------------------------------------------------------------//
//			      LCD Registers									 //
//---------------------------------------------------------------//

#define X_ADDRESS 0xB8			/* Address for Page 0 */
#define Y_ADDRESS 0x40			/* Address for Column 0 */
#define START_LINE 0xC0			/* Address base for line 0 */
#define DISPLAY_ON 0x3F			/* Turn Display on */
#define DISPLAY_OFF 0x3E		/* Turn Display off */

//---------------------------------------------------------------//
//			General use definitions								 //
//---------------------------------------------------------------//

#define RIGHT 0
#define LEFT 1
#define BUSY 0x80
 



#include <p89v51rx2.h>
#include <glcd.h>

//function prototypes
void LcdSelectSide(unsigned char u8LcdSide);
void LcdDataWrite(unsigned char u8Data);
void LcdInstructionWrite(unsigned char u8Instruction);
unsigned char LcdDataRead();
void LcdWaitBusy();
void GLCD_ClearScreen();
void LcdSetDot(unsigned char u8Xaxis,unsigned char u8Yaxis);

/* PROGRAM CODE */


/* CODE TO INVERT AN UNSIGNED BYTE */
unsigned char ByteInvert(unsigned char u8Byte)
{
	unsigned char u8InvertedByte=0;
	unsigned char u8Counter,u8Temporary;
	
	for(u8Counter=0;u8Counter<8;u8Counter++)
	{
		u8Temporary = u8Byte & 0x80;
		u8InvertedByte = u8InvertedByte | u8Temporary;
		u8Byte = u8Byte << 1;
		if(u8Counter != 7)
			u8InvertedByte = u8InvertedByte >> 1;
	}
	
	return u8InvertedByte;
}

/* CODE TO INITIALIIZE LCD */
void GLCD_LcdInit()
{
	LCD_RS = 0;
	LCD_RW = 0;
	LCD_E = 0;
	LCD_DATA = 0x00;

	LCD_RST = 1;
	
	LCD_RST = 0;

	LCD_RST = 1;


	LcdSelectSide(LEFT);
	LcdInstructionWrite(DISPLAY_OFF);	/* DISPLAY OFF */
	LcdInstructionWrite(START_LINE);
	LcdInstructionWrite(Y_ADDRESS);
	LcdInstructionWrite(X_ADDRESS);
	LcdInstructionWrite(DISPLAY_ON);	/* DISPLAY ON */

	LcdSelectSide(RIGHT);
	LcdInstructionWrite(DISPLAY_OFF);	/* DISPLAY OFF */
	LcdInstructionWrite(START_LINE);
	LcdInstructionWrite(Y_ADDRESS);
	LcdInstructionWrite(X_ADDRESS);
	LcdInstructionWrite(DISPLAY_ON);	/* DISPLAY ON */
	
	GLCD_ClearScreen();		
}

/* CODE TO SELECT SIDE OF LCD */
void LcdSelectSide(unsigned char u8LcdSide)
{
	switch(u8LcdSide)
	{
		case RIGHT:
				LCD_CS1=0;
				LCD_CS2=1;
				break;
		case LEFT:	
				LCD_CS1=1;
				LCD_CS2=0;
				break;
	}	//what else is there to do?
}


/* CODE TO SEND DATA TO LCD */
void LcdDataWrite(unsigned char u8Data)
{
	unsigned char u8InvertedData;

	u8InvertedData = ByteInvert(u8Data);

	LcdWaitBusy();						/* wait until LCD becomes free */

	LCD_RS = 1;						/* data mode */
	LCD_RW = 0;						/* write mode */
	LCD_DATA = u8InvertedData;				/* outbyte */	
	LCD_E = 1;						/* strobe to start write cycle*/

	LCD_E = 0;						/* end write cycle */
}	

/* CODE TO SEND INSTURCTION TO LCD */
void LcdInstructionWrite(unsigned char u8Instruction)
{
	unsigned char u8InvertedInstruction;

	u8InvertedInstruction = ByteInvert(u8Instruction);

	LcdWaitBusy();						/* wait until LCD becomes free */
	
	LCD_RS = 0;						/* instruction mode */
	LCD_RW = 0;						/* write mode */
	LCD_DATA = u8InvertedInstruction; 			/* outbyte */
	LCD_E = 1;						/* strobe to start write cycle*/

	LCD_E = 0;						/* end write cycle */
}


/* CODE TO READ DATA FROM LCD */
unsigned char LcdDataRead()
{
	unsigned char u8InvertedLcdData, u8LcdData;

	LCD_E = 0;						/* clear enable pin */
	LCD_RS = 1;						/* data mode */
	LCD_RW = 1;						/* read mode */
	LCD_DATA = 0xFF;					/* set LCD_DATA port in input mode */
	LCD_E = 1;						/* strobe to start read cycle */
	u8InvertedLcdData = LCD_DATA;				/* read data from controller */
	LCD_E = 0;						/* end read cycle */
	
	u8LcdData = ByteInvert(u8InvertedLcdData);
	return u8LcdData;
}


/* CODE TO WAIT AS LONG AS THE LCD IS BUSY */
void LcdWaitBusy()
{
	unsigned char u8InvertedLcdStatus, u8LcdStatus;

	do
	{
		LCD_E = 0;					/* clear enable pin */
		LCD_RS = 0;					/* instruction mode */
		LCD_RW = 1;					/* read mode */
		LCD_DATA = 0xFF;				/* set LCD_DATA in input mode */
		LCD_E = 1;					/* clock out command to LCD */
		u8InvertedLcdStatus = LCD_DATA;			/* read the return value */
		u8LcdStatus = ByteInvert(u8InvertedLcdStatus);
	}while((u8LcdStatus & 0x80) == BUSY);			/* mask the other bits and test the BUSY bit */

	LCD_E = 0;						/* finish the command */
	LCD_RW = 0;						/* turn off RW for future commands */
}


/* CODE TO CLEAR THE LCD SCREEN */
void GLCD_ClearScreen()
{
	unsigned char u8Page = 0;
	unsigned char u8Column = 0;
	
	for(u8Page = 0x0; u8Page < 0x08; u8Page = u8Page + 0x01)
	{
		LcdSelectSide(LEFT);					/* Select left side */
		LcdInstructionWrite(X_ADDRESS | u8Page);		/* set the page number */
		LcdInstructionWrite(Y_ADDRESS);				/* set column to 0 */
	
		for(u8Column = 0; u8Column < 128 ; u8Column++)
		{
			if(u8Column==64)
			{
				LcdSelectSide(RIGHT);			/* select right side */
				LcdInstructionWrite(X_ADDRESS|u8Page);	/* set the page number */
				LcdInstructionWrite(Y_ADDRESS);		/* set to column 0 */
			}
			LcdDataWrite(0x00);				/* erase a column */
		}	
	}
}	

/* CODE TO DRAW A DOT ON THE LCD */
void LcdSetDot(unsigned char u8Xaxis,unsigned char u8Yaxis)
{
	unsigned char u8DataRead=0;	

	if(u8Xaxis > 127 | u8Xaxis < 0 | u8Yaxis > 63 | u8Yaxis < 0)
		return;

	if(u8Xaxis < 64)
		LcdSelectSide(LEFT);
	else
	{
		LcdSelectSide(RIGHT);
		u8Xaxis -= 64;
	}

	LcdInstructionWrite(X_ADDRESS + (u8Yaxis / 8));		/* select page number */
	LcdInstructionWrite(Y_ADDRESS + u8Xaxis);		/* select column */
	u8DataRead = LcdDataRead();				/* dummy read */
	u8DataRead = LcdDataRead();				/* read the current location */

	LcdInstructionWrite(X_ADDRESS + (u8Yaxis / 8));		/* select page number */
	LcdInstructionWrite(Y_ADDRESS + u8Xaxis);		/* select column */
	LcdDataWrite(u8DataRead | (1<<(u8Yaxis % 8)));		/* plot the dot */
}

/* CODE TO DRAW A RECTANGLE ON THE LCD */

void GLCD_Rectangle(unsigned char u8Xaxis1,unsigned char u8Yaxis1, unsigned char u8Xaxis2,unsigned char u8Yaxis2)
{
	unsigned char u8CurrentValue=0;	

	/* Draw two horizontal lines */
	for(u8CurrentValue = 0 ; u8CurrentValue < ( u8Xaxis2 - u8Xaxis1 + 1 ) ; u8CurrentValue++)
	{	
		LcdSetDot(u8Xaxis1 + u8CurrentValue, u8Yaxis1);
		LcdSetDot(u8Xaxis1 + u8CurrentValue, u8Yaxis2); 
	}

	/* draw two vertical lines */
	for(u8CurrentValue = 0 ; u8CurrentValue < ( u8Yaxis2 - u8Yaxis2 + 1 ) ; u8CurrentValue++)
	{
		LcdSetDot(u8Xaxis1,u8Yaxis1 + u8CurrentValue);
		LcdSetDot(u8Xaxis2,u8Yaxis1 + u8CurrentValue);
	}
}

/* CODE TO DRAW A VERTICAL LINE */
void GLCD_VLine(unsigned char u8X1, unsigned char u8X2, unsigned char u8Y)
{
	unsigned char u8Counter;

	for(u8Counter = u8X1 ; u8Counter < u8X2 ; u8Counter++)
		LcdSetDot(u8Counter,u8Y);			
}

/* CODE TO DRAW A HORIZONTAL LINE */
void GLCD_HLine(unsigned char u8X, unsigned char u8Y1, unsigned char u8Y2)
{
	unsigned char u8Counter;

	for(u8Counter = u8Y1 ; u8Counter < u8Y2 ; u8Counter++)
		LcdSetDot(u8X,u8Counter);			
}


 



#include "glcdCopy2.h"

void main()
{
	GLCD_LcdInit();
	GLCD_Rectangle(10,10,100,100);
	GLCD_Rectangle(25,25,80,80);
	GLCD_HLine(30,25,80);
	GLCD_VLine(30,70,50);
}
 


You must have noticed that i have connected DB0 to P0.7, DB1 to P0.6 and so on. To overcome this, i wrote a byteInvert function in my code. i call this function before sending data/instructions on the data lines as well as after i read the status byte or read data.i wrote a simple program to draw 4 rectangles. the code gets compiled successfully by Keil. yet nothing gets displayed on the lcd. i debugged it line by line, but i still don't understand what's wrong.

1. the isp bootloader of the P89V51rd2 is working properly. i successfully downloaded other programs to the microcontroller via the serial com port using flashmagic and executed them.
2. when i supply power, the backlight of the lcd turns on. however, the rectangles do not get displayed.
Please help me by suggesting possible problems in the code/hardware.

I also do not clearly understand how to use the display start line address for scrolling. which address does it store? the address of the horizontal row (that is to become the topmost row)?

There are 64 rows on a 128x64 lcd (i.e. 8 vertical pages; 1 page = 8 pixels). As per my understanding, we should be able to specify any of the 64 rows of the lcd ( the startline address is 6 bit (i.e. 64 possible options)). Please tell me if i am wrong.





//the lcd module datasheet
http://www.es.co.th/detail.asp?Prod=ABG128064A15-BIW-R

//lcd controller datasheet
http://www.datasheetcatalog.com/datasheets_pdf/S/6/B/0/S6B0108.shtml



List of 23 messages in thread
TopicAuthorDate
nothing displayed on graphical lcd using P89V51rd2.            01/01/70 00:00      
   Try to adjust contrast            01/01/70 00:00      
   About The Bus Twist            01/01/70 00:00      
   Start Extremely Simple            01/01/70 00:00      
      But how will i know that data is getting written to the vari            01/01/70 00:00      
         read it            01/01/70 00:00      
         read it !!            01/01/70 00:00      
            RE: registers that may be read/write            01/01/70 00:00      
         Try the text mode            01/01/70 00:00      
            That could be step 2            01/01/70 00:00      
               no text mode            01/01/70 00:00      
   more on contrast            01/01/70 00:00      
      signals            01/01/70 00:00      
         Success!            01/01/70 00:00      
            work to do            01/01/70 00:00      
               i agree            01/01/70 00:00      
                  one more doubt            01/01/70 00:00      
                     an easier alternative            01/01/70 00:00      
                     Isn't this a question to the mentor?            01/01/70 00:00      
                     Need For A Buffer With GLCD            01/01/70 00:00      
                        dot line buffer            01/01/70 00:00      
            nothing displayed on graphical lcd using P89V51rd2            01/01/70 00:00      
   Thanks            01/01/70 00:00      

Back to Subject List