Jump to content
43oh

Launchpad to SparkFun Serial LCD


Recommended Posts

Found another project for those infatuated with LCDs. I am.

 

This one is for the Sparkfun Serial LCD back pack. The LCD displays the number of times the button is pressed.

Courtesy of Matt Wilson. I'll leave a comment on his page inviting him here.

 

Link:

Code: Link

 

/*
* UART TX demonstration program for MSP430G2231, using
* SparkFun Serial LCD module.
*
* Hook up the RX line on the SparkFun Serial LCD backpack to
* P1.1 (TXD) on the LaunchPad board, power everything appropriately,
* and you're all set to go.
*
* Matthew R. Wilson 
* http://mattwilson.org/msp430/
* August 16, 2010
*
* The code to deal with serial data transmission in the following
* functions is copied and modified from the sample program that ships
* with the TI MSP430 LaunchPad:
*   ConfigureTimerUart()
*   Transmit()
*   Timer_A()
*
* Release for demonstration and education purposes only, I make no
* promises that this code will even work properly, let alone do anything
* useful.
*/

#include "msp430g2231.h"

// Pins on the MSP430 we're using
#define     TXD                   BIT1     // TXD on P1.1
#define     BUTTON                BIT3     // Button on P1.3

//   Conditions for 9600 Baud SW UART, SMCLK = 1MHz
#define     Bitime                13       // 1,000,000 / 8 / 9600 = ~13

// variables for serial communication
unsigned char BitCnt;
unsigned int  TXByte;

// How many times have we pushed the button?
unsigned int  buttonPresses = 0;

// function prototypes
void TXString(char *string);
void ConfigureTimerUart(void);
void Transmit();
void brag(void);
void itoa(unsigned int val, char *str, unsigned int limit);

void main( void )
{
 // Stop watchdog timer to prevent time out reset
 WDTCTL = WDTPW + WDTHOLD;

 // Set clock to 1MHz, and SMCLK to 125kHz
 BCSCTL1 = CALBC1_1MHZ;
 DCOCTL = CALDCO_1MHZ;
 BCSCTL2 &= ~(DIVS_3);         //SMCLK is DCO/8

 // Set up the timer to simulate a UART
 ConfigureTimerUart();

 // Set up button (P1.3)
 P1DIR &= ~BUTTON;
 P1OUT |= BUTTON;
 P1REN |= BUTTON;
 P1IES |= BUTTON;
 P1IFG &= ~BUTTON;
 P1IE |= BUTTON;

 // Turn on the LED
 P1DIR |= (BIT0|BIT6);
 P1OUT |= BIT0;
 P1OUT &= ~BIT6;

 // wait for LCD display to initialize
 __delay_cycles(1000000);

 __enable_interrupt();

 // Set brightness full
 //TXByte = 0x7c; Transmit();
 //TXByte = 157; Transmit();

 brag();

 // Display the current button count, then go into LPM4. The button
 // interrupt handler will turn the CPU back on which will bring us back
 // to the beginning of the while() loop.
 while(1)
 {
   brag();
   __bis_SR_register(LPM4_bits + GIE);
 }
}

// base-10 itoa for positive numbers. Populates str with a null-terminated string.
// limit lets you overflow back to 1 when you hit the limit+1, 2*limit+1, ...
// make sure *str is an array that can hold the number of digits in your limit + 1.
void itoa(unsigned int val, char *str, unsigned int limit)
{
 int temploc = 0;
 int digit = 0;
 int strloc = 0;
 char tempstr[5]; //16-bit number can be at most 5 ASCII digits;

 if(val>limit)
   val %= limit;

 do
 {
   digit = val % 10;
   tempstr[temploc++] = digit + '0';
   val /= 10;
 } while (val > 0);

 // reverse the digits back into the output string
 while(temploc>0)
   str[strloc++] = tempstr[--temploc];

 str[strloc]=0;
}

// Output the number of button presses to LCD
void brag(void)
{
 // Clear LCD
 TXByte = 0xFE; Transmit();
 TXByte = 0x01; Transmit();

 TXString("You pressed the button ");
 char times[4];
 itoa(buttonPresses, times, 999);
 TXString(times);
 if(buttonPresses!=1)
   TXString(" times");
 else
   TXString(" time");
}

// Transmit a string via serial UART by looping through it and transmitting
// each character one at a time.
void TXString(char *string)
{
 while(*string != 0)
 {
   TXByte = *string; Transmit();
   string++;
 }
}

// Set up timer for simulated UART. Copied from MSP430 LaunchPad sample code.
void ConfigureTimerUart(void)
{
 TACCTL0 = OUT;                             // TXD Idle as Mark
 TACTL = TASSEL_2 + MC_2 + ID_3;            // SMCLK/8, continuous mode
 P1SEL |= TXD;                              //
 P1DIR |= TXD;                              //
}

// Function Transmits Character from TXByte
// Copied from MSP430 LaunchPad sample code
void Transmit()
{
 BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
 while (TACCR0 != TAR)                       // Prevent async capture
   TACCR0 = TAR;                             // Current state of TA counter
 TACCR0 += Bitime;                     // Some time till first bit
 TXByte |= 0x100;                        // Add mark stop bit to TXByte
 TXByte = TXByte   TACCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
 while ( TACCTL0 & CCIE );                   // Wait for TX completion
}

// Timer A0 interrupt service routine
// Copied from MSP430 LaunchPad sample code
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
 TACCR0 += Bitime;                           // Add Offset to CCR0
 if (TACCTL0 & CCIS0)                        // TX on CCI0B?
 {
   if ( BitCnt == 0)
     TACCTL0 &= ~ CCIE;                     // All bits TXed, disable interrupt
   else
   {
     TACCTL0 |=  OUTMOD2;                    // TX Space
     if (TXByte & 0x01)
     TACCTL0 &= ~ OUTMOD2;                   // TX Mark
     TXByte = TXByte >> 1;
     BitCnt --;
   }
 }
}

// Update the button press count, and toggle LEDs, when the button is pressed
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
 buttonPresses++;
 P1OUT ^= BIT0;
 P1OUT ^= BIT6;
 P1IFG = 0; // clear interrupt
 __bic_SR_register_on_exit(LPM4_EXIT);
}

Link to post
Share on other sites
There probably is a document online somewhere that would describe the interface your LCD's would use, in that case it is VERY easy to program a parallel interface (if you have enough IO pins, lol). Just look up the model number, or search the main chip you see on the board.

 

I think mine are cheap (very) knock-offs, with an epoxy blob on the interface board. That said, I think they follow the standard parallel pinout/interface, so I should be able to adapt some code.

 

I also have some 74VHC164 (8-Bit Serial-In, Parallel-Out Shift Register) chips laying in my parts box I might be able to use. I'm not sure where most of these chips came from... I must have ordered them a long time ago with the hope of learning to use them. I guess now's the time.

 

-Doc

Link to post
Share on other sites
  • 2 weeks later...
I think mine are cheap (very) knock-offs, with an epoxy blob on the interface board.

 

Indeed they are...

 

I believe a 2x20(?):

IMAG0135.jpg

IMAG0141.jpg

 

And a 4x20(?):

IMAG0137.jpg

IMAG0140.jpg

 

Anybody recognize these? So, I need eight data lines, anything else? I think the LED and contrast are better left to hardware control. Would the 74HC595 get me there? (@gatesphere?) Three for the 74HC595 would leave me five more pins on the LaunchPad for sensors!

 

This would be a pretty cool addition to my electricity usage monitor!

 

If anybody sees any (simple) example code that I can port, please send me a link.

 

-Doc

Link to post
Share on other sites

I would not know anything about interfacing with those LCD modules, I've never used one before... but, and this is just an assumption, you could easily control those 8 pins with a '595. It might involve a bit of higher level math and some overhead, so you might have to ditch any LPM you were thinking of using, and up the clock speed to 16mHz, but you could probably do it. At least in theory. The thing with the '595 chips is that the communications are not instant, so it adds some time for the data to settle before it gets shifted out. So, just be wary of that.

 

But yeah, I'm not sure completely.

 

Oh, some info on those modules:

They're manufactured by ETC or JHD, depending on where you actually acquired them.

The first one - JHD 162A - info here: http://www.alldatasheet.com/datasheet-p ... D162A.html

The second one - JHD 204AO - info here: http://www.alldatasheet.com/datasheet-p ... D204A.html

 

It's amazing what Google can do :)

 

I say try it and blog about it! If you end up writing some good code out of it, I could incorporate it into MSPhere even. :D

So, go for it. Learning is a great thing.

 

Good luck!

Link to post
Share on other sites

Hey gatesphere!

 

Thanks for the info, and the datasheet links. These modules are all about the same interface-wise, it seems. There are eight data lines and power, two grounds, LED backlight pins, contrast, read/write (yes, read), and a data/instruction switch pin.

 

I saw a tutorial over at ladyada.net where she hooked one up to an Arduino. Apparently, you can get away with just using four data pins and the LCD just works anyway. Unfortunately, the LCD controlling code is in a library for the Arduino. I think Arduino code (libraries) is open source though, so I'll have to get my hands on that particular library (and a big Amp energy drink) and have a look.

 

I'll get 'em running. And you bet I'll blog it on my site and share the code here! :D

 

-Doc

Link to post
Share on other sites

If I'm not mistaken, the driver chip on the LCD is the highly popular HD44780. Google for HD44780 library. You should get a a good number of hits. The code examples are normally for 8051/52, PICs and AVR, but you could port them.

 

eg: http://www.rpi.edu/dept/ecse/mps/LCD_Screen-8051.pdf

Link to post
Share on other sites

SUCCESS!!! kinda... :?

 

I found some code in the TI forums (thanks for the search term suggestion, bluehash!), and I modified it quite a bit to work on the MSP430G2211 and use just a 4-bit interface. The code had control commands too, so I used another pin for RS (data/command), and one for E (enable signal).

 

I wired it up, and it is sending data. Problem: The data is garbage characters/commands. I just need to strip down the code some more (looks to have originally been a readout from an ADC input) to simplify it and get it working correctly.

 

Just wanted everyone to know that it is so easy, a noob can (pretty much) understand it! I'll post clean code when I have it.

 

-Doc

Link to post
Share on other sites

A little tidbit of info I found in my tinkering for those who want to use parallel LCDs:

 

The 74HC594 is better for serial communication with the LCD. The LCD controller has a latch similar to the 74HC595 so, if you use the 595, you have to deal with two latches, in the proper order, to get the data to display.

 

Save a pin and some code: use the 594 and do all the data latching on the LCD!

 

I'll post schematics and code in a new post when I get it done.

 

-Doc

 

BTW: I found 16x2 parallel LCDs for as little as US$4.00 shipped on eBay!

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...