SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By TheDirty
#71021
There's a datasheet and app notes right on the product page. What exactly do you want help with?
By BiOzZ
#71028
TheDirty wrote:There's a datasheet and app notes right on the product page. What exactly do you want help with?
There's a datasheet and app notes right on the product page. What exactly do you want help with?[/quote]
i have the data sheet but it does not help me, i have it all connected but i need some example code or at least an explanation, like lets just say i want to draw a simple line, what do i send to it? i don't have any experience with graphic displays
By Blackfin
#71041
BiOzZ wrote:i have the data sheet but it does not help me, i have it all connected but i need some example code or at least an explanation, like lets just say i want to draw a simple line, what do i send to it? i don't have any experience with graphic displays
I just used that display in a project using a Cypress PSoC CY8C27443 micro. It's a nice piece though it's got an ideosyncracy or two.

The biggest is the fact that there are actually two controllers to work with, one for pixels 0-63 and the second for pixels 64-127: CS1 serves pixel columns 0-63, CS2 columns 64-127. I found it easiest to treat them as two separate controllers. Some commands may work with simultaneous writes (i.e. assert both CS1 and CS2 at the same time for writing) but I opted not to do that.

Like many mono graphic LCDs, each pixel on the screen represents a single bit in a data byte written to the controller. You can use the various LCD command bytes (like SETYADDRESS 0x40 and SETXADDRESS 0xB8, setting other bits in the command byte as required) to point the data pointer on the screen. The X address is actually set in pages: the pixels down a column are the bits of bytes written. Rows 0-7 in column zero are pointed to with:

SETYADDRESS 0x40 | 0x00 (sets column 0)

and

SETXADDRESS 0xB8 | 0x00 (sets page 0)

When you write data there, the bits show up on the screen like this:

Code: Select all
R00  Page 0 000...0
R01  Page 0 111...1
R02  Page 0 222...2
R03  Page 0 333...3
R04  Page 0 444...4
R05  Page 0 555...5
R06  Page 0 666...6
R07  Page 0 777...7
R08  Page 1 000...0
R09  Page 1 111...1
.
.
.
R62 Page 7 666...6
R63 Page 7 777...7
The columns range from 0-63 for each half of the display. Each data write advances the pointer one column so you can write multiple bytes on a page before having to reset the X and Y pointers. You'll need special code to handle images that bridge the 63-64 pixel boundary; you'll stop writing to one controller and switch to the other keeping in mind you're once again counting columns starting from 0... It gets a bit tricky.

Drawing a line is actually non-trivial unless you want an 8-pixel vertical line at the top left. This could do that:
Code: Select all
void DrawLine1( void )
{
    LCD_Write( LCD_COMMAND, (LCD_SETXADDRESS + 0), LCD_CS1MASK );	//Set Page number for controller 1 to page 0
    LCD_Write( LCD_COMMAND, (LCD_SETYADDRESS + 0), LCD_CS1MASK );		//set Y coordinate on controller 1 to col 0
    LCD_Write( LCD_DATA, 0xFF ); // light up all pixels forming an 8-pixel line
}
If you want to draw a line from (0,0) to (127,63) you're in for quite a bit more work than that. Computing the slope, the step-size, the bits in each row and column that need to be set etc. I found it easier to start by drawing a small 16x16 bitmap than a line...

To get started, post what you've got for initialization code.
By BiOzZ
#71052
Blackfin wrote:
BiOzZ wrote:i have the data sheet but it does not help me, i have it all connected but i need some example code or at least an explanation, like lets just say i want to draw a simple line, what do i send to it? i don't have any experience with graphic displays
I just used that display in a project using a Cypress PSoC CY8C27443 micro. It's a nice piece though it's got an ideosyncracy or two.

The biggest is the fact that there are actually two controllers to work with, one for pixels 0-63 and the second for pixels 64-127: CS1 serves pixel columns 0-63, CS2 columns 64-127. I found it easiest to treat them as two separate controllers. Some commands may work with simultaneous writes (i.e. assert both CS1 and CS2 at the same time for writing) but I opted not to do that.

Like many mono graphic LCDs, each pixel on the screen represents a single bit in a data byte written to the controller. You can use the various LCD command bytes (like SETYADDRESS 0x40 and SETXADDRESS 0xB8, setting other bits in the command byte as required) to point the data pointer on the screen. The X address is actually set in pages: the pixels down a column are the bits of bytes written. Rows 0-7 in column zero are pointed to with:

SETYADDRESS 0x40 | 0x00 (sets column 0)

and

SETXADDRESS 0xB8 | 0x00 (sets page 0)

When you write data there, the bits show up on the screen like this:

Code: Select all
R00  Page 0 000...0
R01  Page 0 111...1
R02  Page 0 222...2
R03  Page 0 333...3
R04  Page 0 444...4
R05  Page 0 555...5
R06  Page 0 666...6
R07  Page 0 777...7
R08  Page 1 000...0
R09  Page 1 111...1
.
.
.
R62 Page 7 666...6
R63 Page 7 777...7
The columns range from 0-63 for each half of the display. Each data write advances the pointer one column so you can write multiple bytes on a page before having to reset the X and Y pointers. You'll need special code to handle images that bridge the 63-64 pixel boundary; you'll stop writing to one controller and switch to the other keeping in mind you're once again counting columns starting from 0... It gets a bit tricky.

Drawing a line is actually non-trivial unless you want an 8-pixel vertical line at the top left. This could do that:
Code: Select all
void DrawLine1( void )
{
    LCD_Write( LCD_COMMAND, (LCD_SETXADDRESS + 0), LCD_CS1MASK );	//Set Page number for controller 1 to page 0
    LCD_Write( LCD_COMMAND, (LCD_SETYADDRESS + 0), LCD_CS1MASK );		//set Y coordinate on controller 1 to col 0
    LCD_Write( LCD_DATA, 0xFF ); // light up all pixels forming an 8-pixel line
}
If you want to draw a line from (0,0) to (127,63) you're in for quite a bit more work than that. Computing the slope, the step-size, the bits in each row and column that need to be set etc. I found it easier to start by drawing a small 16x16 bitmap than a line

To get started, post what you've got for initialization code.
thank you but im a bit confused, LCD_Write does not seam like a normal command do you know what data is being sent? and in what order?
i have no experience with graphic displays and every other display i have worked with i send mostly raw data to it like if each row is a pin form 0-7 i normally work like this
01000111
10110111
01101001
01001111
and than i make librarys from that and work from there. right now i want to go simple and play with the arduino
can you tell me what i need to send to what pin (besides the deta pins)
than how to use the data pins?
im sorry but this is my first graphic display
By Blackfin
#71067
BiOzZ wrote:thank you but im a bit confused, LCD_Write does not seam like a normal command do you know what data is being sent? and in what order?
Let's take a step back: The LCD in question has a 20-pin header:

1 Vdd
2 Vss
3 V0
4 D0
5 D1
6 D2
7 D3
8 D4
9 D5
10 D6
11 D7
12 CS2
13 CS1
14 RST
15 R/W
16 D/I
17 E
18 Vee
19 Anode
20 Cathode

Do you have these connections made?

In order to write to or read from the LCD, you need to look at the datasheet and ensure you drive the pins per the sheet. I wrote myself a whole "driver", higher and lower-level functions for doing just that. For instance, writing a byte to the LCD involves twiddling the data and control lines to the LCD in a specific way. My write command looks like this:
Code: Select all
void LCD_Write( unsigned char ucCommandData, unsigned char ucData, unsigned char ucChipSelectMask )
{
	unsigned char
		bStatus;
		
	M8C_DisableGInt;
	
	EnableWrite();
	
	if( ucCommandData == LCD_COMMAND )
		LCD_CTLPRTSHADOW &= ~LCD_DIMASK;			//drive DI low for command
	else
		LCD_CTLPRTSHADOW |= LCD_DIMASK;				//drive DI high for data
	LCD_CTLPORT = LCD_CTLPRTSHADOW;	
	
	if( ucChipSelectMask == LCD_CS1MASK )
	{
		LCD_CTLPRTSHADOW &= ~LCD_CS1MASK;			//drive selected bank CS
		LCD_CTLPRTSHADOW |= LCD_CS2MASK;			//ensure other one is deselected
	}//if
	else
	{
		LCD_CTLPRTSHADOW |= LCD_CS1MASK;			
		LCD_CTLPRTSHADOW &= ~LCD_CS2MASK;			
	}//else	
	LCD_CTLPORT = LCD_CTLPRTSHADOW;
	
	asm( "nop" );
	asm( "nop" );	
	
	LCD_DATAPORT = ucData;							//put data there
	
	LCD_CTLPRTSHADOW |= LCD_EMASK;					//drive E high
	LCD_CTLPORT = LCD_CTLPRTSHADOW;	
	
	asm( "nop" );
	asm( "nop" );	
	asm( "nop" );	
	
	LCD_CTLPRTSHADOW &= ~LCD_EMASK;					//drive E low
	LCD_CTLPORT = LCD_CTLPRTSHADOW;	
	
	asm( "nop" );	
	asm( "nop" );	
	
	//
	LCD_CTLPRTSHADOW |= LCD_CS1MASK;			
	LCD_CTLPRTSHADOW |= LCD_CS2MASK;			
	LCD_CTLPORT = LCD_CTLPRTSHADOW;	
	
	asm( "nop" );
	asm( "nop" );	
	asm( "nop" );	
	
	if( ucCommandData == LCD_COMMAND )
	{	
		do
		{
			M8C_ClearWDT;
			if( ucChipSelectMask == LCD_CS1MASK )
				bStatus = LCD_ReadStatus( LCD_CS1MASK );
			else
				bStatus = LCD_ReadStatus( LCD_CS2MASK );
				
			bStatus &= LCDSTATUS_BUSY;		//mask out all but busy bit
		
		}while( bStatus );
		
	}//if
	
	M8C_EnableGInt;
	
}//LCD_Write
So LCD_Write(), the command I wrote, allows me to write command or data to the LCD. Similarly, I can read the status back after commands are sent to wait for the module to finish (looking at the busy flag...) My LCD_Write() command takes three parameters. The first is an indicator of whether the byte being written is a command or data. This determines how the logic drives the D/I pin and whether the busy flag is checked. The second is the byte to write and the third (which I inadvertently left out of the DrawLine1() example I posted earlier where I write 0xFF to the LCD...) is which of the two modules is being written to.

So with regard to what to send, look at the datasheet:

http://www.sparkfun.com/datasheets/LCD/GDM12864H.pdf

and go to page 10. There's a table showing everything you can do with the LCD. It illustrates the state of each pin (RS is "D/I" by the way...) and which data bits do what.

The tougher thing to understand is how the display is layed out and how a given pixel on the screen corresponds to a page, a column and the byte written there and the fact that there are essentially two distinct modules to deal with.
i have no experience with graphic displays and every other display i have worked with i send mostly raw data to it like if each row is a pin form 0-7 i normally work like this
01000111
10110111
01101001
01001111
and than i make librarys from that and work from there. right now i want to go simple and play with the arduino
can you tell me what i need to send to what pin (besides the deta pins)
than how to use the data pins?
im sorry but this is my first graphic display
May I ask if you've had much microcontroller and/or interfacing experience? The issue of reading the datasheet and determining what data bits do what when writing to or reading from an external device isn't unique to graphical LCDs. Even character LCDs with parallel interfaces use the same basic signaling (though they usually have only one controller.)

Aside from power for the LCD (Vdd and Vss) contrast (V0 and Vee) and the backlight (anode and cathode), from the micro, you need:

4..11 D0..D7 input/output
12 CS2 output
13 CS1 output
14 RST output
15 R/W output
16 D/I output
17 E output

The datasheet, on pages 7 and 8, show the idle and active levels for each signal and the timing requirements. Using this you should be able to write some low-level stuff to send command and data bytes to the LCD and read status and even data back. For many microcontrollers this means bit banging. Some micros might have a bus interface that allows a write to an address which automatically generates bus control signals (e.g. E) but most micros will require you to do this manually. My LCD_Write above shows this.

Once you have that, then you can use page 10 to write some slightly higher-level stuff to set the display memory pointer (X,Y), set the start line and turn the display on and off.

Once you've initialized the LCD, set the X,Y addresses to 0,0 and write 0xFF. What do you see?
By helluva engineer
#97201
Does anyone know of a way to check to see if I've bricked this LCD? When I connect power and adjust the contrast pot all the way to one side, I can see a single black line stretching across the top and the other pixels faintly turn on. If I manually connect the Reset pin to +5V or GND, it doesn't change. I've sent it a variety of commands, but I don't even get a flicker of garbled pixels on the LC. I've checked and rechecked my wiring connections to the PIC18F4321, and tried Blackfin's code in addition to my own. Any ideas? Thanks.