Skip to content

2.2″ LCD Over Hardware SPI

March 2, 2014

The ElecFreaks LCD comes mounted on a shield but the pins it uses are not the standard arduino spi output so instead of using the hardware shift register each bit had to be painfully clocked out. I got it to work t be sure i understood the sequences but it was going to take almost an hour to paint the screen!  It would be asy to fix the circuit at home – only two traces need to be re-routed but i don’t have soldering gear here. I dismounted the LCD and connected power, ground, MOSI and Clock, along with the reset and data/command pins.
14-03-02 hookup
I put in a short routine in 1802 assembler to repeatedly write the same byte to the spi port and changed the pant routine to call it. This is a lot quicker, it takes maybe 8 seconds to do the whole screen – in the video i limited to half so i could cycle the colours quicker. That sounds terrible but even the arduino took a couple of seconds – it’s just a lot of data to move: 320*240*2 bytes= something like 153,600 bits/second.

void Pant(char VL)
  int i,j,k;
void hwspilcdasm(){ //asm routines for hardware spi lcd
	asm("	align 16\n"		//make sure lcdclearer jumps will fit on page
		"_lcdfiller:\n" 	//fills R12 bytes of lcd with R13.0
		"$$clrloop:\n"		//come back here for more
			"	dec 2\n	glo 13\n	str 2\n	out 6\n"	//send a fill byte
			"	dec R12\n"	//decrease counter
			"	glo R12\n	bnz $$clrloop\n" //back for more
			"	ghi R12\n	bnz $$clrloop\n" //til done
		"	cretn\n");	//and we're done

As part of doing that, I learned a few things about the LCD and controller:
First of all, the Address_set routine doesn’t just tell the LCD controller where to start writing – it actually establishes a window on the screen where your bytes get written. So Address_set(0,0,100,100) puts the data into a 100*100 window at the origin.
Second, the colour of a pixel is defined by the bits you send as in RRRBBGGG i.e. 0xE0 is the brightest Red, 0x18 is Blue, and 0x07 is green. You combine these as usual for example Red+Green=0xE7 for yellow. The colours are not vibrant but they’re respectable.
Third, you do have to send two bytes for each pixel. If you use the same codes as above for both writes you get the colours listed. If you use a different code(or a zero) for the second write you get something different. I’ve looked at the data sheet from here but I haven`t figured it out yet.

A few minutes poking around though and I made a program that would paint a randomly chosen area on the screen in a random colour

The code looks like

void paintpart(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2,char VL)

void main(){
	unsigned int x,y,r;
	unsigned int qx[]={0,60,120,180};  //screen quadrants
	unsigned int qy[]={0,80,160,240};
	unsigned char clr[]={0xff,0xE0,0x18,0xE7};//white, red, blue, yellow

I figure now I can make a routine that will draw a sprite or stamp kind of thing in an arbitrary window on the screen.  The only trouble is, it’s going to be small – a 16X16 sprite would take 256 bytes and would only be 1/12 inch on a side.  To be 1/2 inch on a side would take a 90*90 stamp, weighing in around 8k.  I could maybe fit in two of those and they’d be a bear to make.


From → Uncategorized

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: