SparkFun Forums 

Where electronics enthusiasts find answers.

Discussions on how to get your MSP JTAG programmer up and running.
By Uarc
#74200
Hello, I'm a BSEE student working on a senior design project. I'm using the MSP430f2013 and I'm trying to program a LCD display. Eventually I'd like to use the MSP430 to display battery voltage using the ADC, but first I have to get the LCD to work. All it does right now is show all black boxes. I have some code but it's not working and I'm hoping someone may be able to steer me in the right direction. I don't have much experience programming micro-controllers by the way..

#include "io430.h"
#include "intrinsics.h"

#define DB4 BIT3
#define DB5 BIT2
#define DB6 BIT1
#define DB7 BIT0
#define E BIT4
#define RS BIT5

void wait(int ms); // wait for some designated milliseconds
void initialize_LCD(); // execute all the preferences, setup & initialization commands on the LCD
void send_LCD(int data, int rs_flag); // sends word to LCD and sets rs flag
void print_LCD(char* msg); // sends a specified string to the LCD, also clears the screen
void LCD_cmd(int command); // execute a specific command on the LCD. Sets flag correctly.
void LCD_data(char charcode); // send one character to the LCD, without clearing the screen first. Sets flag correctly.

int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
P1DIR = RS | E | DB7 | DB6 | DB5 | DB4; //Set the data, RS & E pins to output
P1OUT = 0; //Initialize output to zero/low.
initialize_LCD(); //Send our preferences to the LCD and initialize.

print_LCD("Testing");

__low_power_mode_4(); // Execution doesn't won't move past this line.
return 0;
}

//Set up LCD preferences and initiate initialization commands
void initialize_LCD()
{
wait(50); //Wait a little bit for the LCD to reach supply voltage.
//Set to 4-bit mode
P1OUT &= ~(RS); //this is a command, not data
wait(5);
send_LCD(0x02, 0);
wait(20);
LCD_cmd(0x28); // set 4bitmode: 1-Line Mode and 5x8 Font
wait(20);
LCD_cmd(0x0F); // Main Screen Turn On (Display ON) Use a cursor that blinks.
wait(20);
LCD_cmd(0x06); // Move the cursor from left to right on a character entry.
wait(20);
LCD_cmd(0x01); // Clear Display. Also resets the cursor to the first char on the left.
wait(20);
}

//Wait a designated amount of time in milliseconds.
void wait(int ms)
{
int whileCount = 0;
TACTL = MC_1 | ID_2 | TASSEL_2 | TACLR;
TACCR0 = 274;
for(int i=0; i<ms; i++)
{
while(TACTL_bit.TAIFG == 0) {
whileCount++;
}
TACTL_bit.TAIFG = 0;
}
}

// Send one word of data to the LCD, then clock it.
void send_LCD(int data, int rs_flag)
{
P1OUT |= E; // LCD Clocked High
P1OUT |= (data | 0xF); //Load up the data
if(rs_flag) { P1OUT |= RS; } //If RS is high, make sure it sends as 1.
else { P1OUT &= ~(RS); } //otherwise, specifically disable it.
wait(10);
P1OUT &= ~(E); // E low, activate LCD.
wait(10);
P1OUT &= ~(DB4 | DB5 | DB6 | DB7); //clear the data bits
}

//send a character code to the LCD:
void LCD_data(char charcode)
{
send_LCD( ((charcode&0xF0) >> 4), 1 ); //High nibble is sent first (4bit mode) RS=1
wait(20);
send_LCD( ((charcode&0x0F)), 1 ); //Followed by the low nibble (4bit mode) RS=1
wait(20);
}

//send a command to the LCD:
void LCD_cmd(int command)
{
wait(20);
send_LCD( ((command&0xF0) >> 4), 0 ); //High nibble is sent first (4bit mode) RS = 0
wait(20);
send_LCD( (command&0x0F), 0 ); //Followed by the low nibble (4bit mode) RS = 0
wait(20);
}

// Print out a full string to the LCD
void print_LCD(char* msg)
{
LCD_cmd(0x01); //clear the LCD
wait(20);
while (*msg) {
LCD_data(*msg);
msg++;
}
}
By gm
#74205
I haven't looked into your code too much but a couple of things occurred to me: Have you tried adjusting the contrast? Are the data lines really connected the way that you have them #define'd? They seem backward to me. I would think that you would want DB4 connected to BIT0, DB5 connected to BIT1, etc.

gm
By Uarc
#74305
Thanks, but I tried that and still nothing.. I don't see any way to adjust the contrast. I can increase or decrease the input voltage and that will make the solid lcd blocks lighter or darker, that's about it. Any other ideas though? Thanks..
User avatar
By leon_heller
#74312
LCD character displays have a contrast pin. It usually needs to be taken negative when operating at voltages below 5V.

Leon
By Uarc
#74762
Thank you, but this LCD doesn't have a contrast pin. The pinout is as follows:

P1 - VSS (GND)- LCD POWER
P2 - VCC (+3.3V) - LCD POWER
P3 - RS (Register Select)
P4 - R/W (Read/Write)
P5 - E (Data Enable)
P6 - DB4
P7 - DB5
P8 - DB6
P9 - DB7
P10 - VCC (+3.3V) - LCD BACKLIGHT
P11 - VSS (GND) - LCD BACKLIGHT

The link to the LCD is here:

http://www.newhavendisplay.com/specs/NH ... SW-GBW.pdf

Nothing is happening.. the screen just shows all black boxes unless I decrease the input voltage, then the screen lightens up. I went ahead and corrected the lines:

#define DB4 BIT0
#define DB5 BIT1
#define DB6 BIT2
#define DB7 BIT3
#define E BIT4
#define RS BIT5

But still nothing. Any other suggestions?
By Werthog
#79215
leon_heller wrote:LCD character displays have a contrast pin. It usually needs to be taken negative when operating at voltages below 5V.

Leon
I realize this is off-topic for the OP, but this is relevant for a similar project I'm working on, where I'd like to power the LCD at 3V - what do I need to do in order to invert the power for the contrast pin? Is there an IC that'll take care of this for me?
User avatar
By leon_heller
#79218
You only need a couple of volts or so, and the current is minimal. An easy way to get it is to toggle an output pin and generate it with a couple of diodes and capacitors.

Leon
By theatrus
#79220
For a precanned solution, use a capacitor switcher IC. Microchip makes a large number of them, in inverter, doubler, or even regulated output.