MSP430f2013 and a LCD

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++;

}

}

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

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…

LCD character displays have a contrast pin. It usually needs to be taken negative when operating at voltages below 5V.

Leon

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?

leon_heller:
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?

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

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