Jump to content
RobG

Using 3 wires to control parallel LCD display

Recommended Posts

I have seen this done other ways, but I didn't want to deal with 7 pins, or 4 bits, etc., so I did it my way.

You send 8 bits to shift register, then set data out to whatever RS should be, and finally pulse E, that simple.

I will add my code later, once I clean it up.

BTW, if you are interested, the display is LMB162 and was purchased from ebay for $7.99 with free S/H to US of A (it took a week to get to NC.)

It requires 3.3V Vcc with 5V BL, that's why I like it (well, I don't like the fact that I need separate power for BL.)

 

 

post-197-13513549693_thumb.png

 

My next step is to reduce number of required pins to 2 by adding missing pulse detector (555 I think will do well here.)

post-197-135135496934_thumb.png

Share this post


Link to post
Share on other sites

Here's the code.

I was going to use USI, but since there isn't much benefit, I went with bit banging. The advantage is that you can easily reassign pins and you can use USI for something else.

 

#include "msp430g2231.h"

#define sendData(data) send(data, 1)
#define sendInstruction(data) send(data, 0)
#define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06)
#define clearDisplay() sendInstruction(0x01); _delay_cycles(2000)
#define DATAPIN BIT6
#define CLOCKPIN BIT5
#define ENABLEPIN BIT4

void send(char data, char registerSelect);
void sendDataArray(char data[], char length);

char charIndex = 0;
char bitCounter = 0;

const char message1[8] = {0x34,0x33,0x6F,0x68,0x2E,0x63,0x6F,0x6D};
char message2[10] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
const char message3[16] = {0x33,0x2D,0x70,0x69,0x6E,0x20,0x73,0x65,0x72,0x69,0x61,0x6C,0x20,0x4C,0x43,0x44};

void main(void)
{
WDTCTL = WDTPW + WDTHOLD;

_delay_cycles(100000);

P1OUT &= ~(CLOCKPIN + DATAPIN);
P1OUT |= ENABLEPIN;
P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN;

initDisplay();

while(1) {
 		// send const message using sendDataArray 
	clearDisplay();
	sendDataArray((char *)message1, 8);

	_delay_cycles(1000000);

	// send message using sendDataArray
	clearDisplay();
	sendDataArray(message2, 10);

 		_delay_cycles(1000000);

	// send message one char at the time
 		clearDisplay();
 		charIndex = 0;
 		while(charIndex < 16) {
 			sendData(message3[charIndex]);
 			charIndex++;
 		}

	_delay_cycles(1000000);
 	}
}

void sendDataArray(char data[], char length) {
charIndex = 0;
 	while(charIndex < length) {
 		sendData(data[charIndex]);
 		charIndex++;
 	}
}

void send(char data, char registerSelect) {
bitCounter = 0;
while(bitCounter < 8) {
 		(data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN);
 		data <<= 1;
 		P1OUT |= CLOCKPIN;
 		P1OUT &= ~CLOCKPIN;
 		bitCounter++;
 	}
 	registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN);
 	P1OUT &= ~ENABLEPIN;
 	P1OUT |= ENABLEPIN;
}

Share this post


Link to post
Share on other sites

Nice work!

 

Now I have to decide if I should use my parallel code, or grab a shift register and use yours to give me more pins. :? Maybe I'll do two versions! ;)

Share this post


Link to post
Share on other sites
Nice work!

Now I have to decide if I should use my parallel code, or grab a shift register and use yours to give me more pins. :? Maybe I'll do two versions! ;)

Small board in Eagle? I should be able to squeeze in 1-1.5 sq in.

Share this post


Link to post
Share on other sites
Nice work!

Now I have to decide if I should use my parallel code, or grab a shift register and use yours to give me more pins. :? Maybe I'll do two versions! ;)

Small board in Eagle? I should be able to squeeze in 1-1.5 sq in.

Do it with a 16-pin header row, and you've got a "backpack"! [me-fires up Eagle to try it out] :D

Share this post


Link to post
Share on other sites

How's this? I just hand routed the traces that would carry the most current, then auto-routed the rest. It's about 1.75 x 0.75; I got kind of lazy in the placement to allow easier routing. Top is for 16-pin header on bottom to attach to LCD (M/F to mate with header on LCD). Other header pulls everything needed out.

 

post-73-135135496938_thumb.png

LCD-Serial-Backpack.zip

Share this post


Link to post
Share on other sites

Hi guys,

 

I've taken advantage of the latch outputs to drive a switch matrix on several different backpack designs. I wonder if you guys think something like this might work or might be useful on Rob's design? I'm just not sure if sharing in this manner (as input and output) will work. What do you guys think?

 

Cheerful regards, Mike

 

post-1059-135135496948_thumb.png

 

  /**************************************************************
  *  shift '11111110' (walking 0) pattern into shift register  *
  *  and test each switch sequentially as we "walk the 0 bit"  *
  *  through the shift register.  call at 20-msec intervals.   *
  **************************************************************/
  void ReadKeys()                   // sample/manage switches
  { bitCounter = 7;                 //
 	P1OUT |= DATAPIN;               // Data = '1'
 	while(bitCounter)               // clock out seven '1's
 	{ P1OUT |= CLOCKPIN;            // 
 	  P1OUT ^= CLOCKPIN;            //
 	  bitCounter--;                 //
 	}                               // setup walking '0' bit
 	P1OUT ^= DATAPIN;               // Data = '0'
 	P1OUT |= CLOCKPIN;              // clock out the '0' bit
 	P1OUT ^= CLOCKPIN;              //
 	bitCounter = 1;                 // the column switch mask
 	while(bitCounter)               // read keys one at a time
 	{ P1DIR ^= DATAPIN;             // set DATAPIN to input
 	  swnew = swold;                // copy switch state latch
 	  swnew |= bitCounter;          // set switch bit to '1'
 	  if(P1IN & DATAPIN)            // if switch reads open
 	  { swnew ^= bitCounter;        // set switch bit to '0'
 	  }                             // 
 	  P1DIR |= DATAPIN;             // set DATAPIN to output
 	  P1OUT |= DATAPIN;             // Data = '1'
 	  P1OUT |= CLOCKPIN;            // shift the "walking 0" bit
 	  P1OUT ^= CLOCKPIN;            // 
 	  bitCounter <<= 1;             // advance column bit mask
 	}                               //
   /*
    *  swnew  ___---___---___---___    sample active lo switches
    *  swold  ____---___---___---__    switch state latch
    *  swnew  ___-__-__-__-__-__-__    changes, press or release
    *  swnew  ___-_____-_____-_____    filter out 'release' bits
    */
    swnew ^= swold;                 // changes, press or release
    swold ^= swnew;                 // update switch state latch
    swnew &= swold;                 // filter out 'release' bits
  }

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...