Problem with LCD interface for msp430

Hi, I am trying to interface an LCD w/ Hitachi hd44780 controller in 4-bit mode. I am having lots of trouble, and it is not working. I am suspecting that something is wrong with my delay function, but I am not sure. Could anyone please help me out???

P1.0 = RS, P1.1 = R/W’, P1.2 = Enable, P1.3 = D7, P1.4 = D6, P1.5 = D5, P1.3 = D4

#include “msp430x20x2.h”

#include “LCD.h”

#define EN 0x04

#define RW 0x02

#define RS 0x01

int main( void )

{

LCD_init();

LCD_data(0x48); // Write ‘H’

LCD_data(0x49); // Write ‘I’

return 0;

}

void LCD_data(unsigned char data)

{

P1OUT = (((data >> 4) & 0x78) | EN | RS);

P1OUT = (((data >> 4) & 0x78) | RS);

P1OUT = ((data & 0x78) | EN | RS);

P1OUT = ((data & 0x78) | RS);

delay(7); // 218.75 us delay (32 kHz internal clock for Timer A)

delay(7); // 218.75 us delay

}

void LCD_init()

{

delay(640); // 20 ms delay

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

_NOP();

P1DIR |= 0x7F; /* P1.0 - P1.6 set to output direction

(D4-D7, E, R/W’, RS) */

LCD_command(0x20); // Set to 4-bit operation

delay(7);

delay(7);

LCD_command(0x20); // Select 1-line display, 5x8 dot character font, & 4-bit display

LCD_command(0x00);

delay(7);

LCD_command(0x00); // Turn on display and cursor

LCD_command(0x38);

delay(7);

delay(7);

LCD_command(0x00); // Increment address by one and shift cursor to the right

LCD_command(0x30);

delay(7);

delay(7);

}

void LCD_command (char command)

{

P1OUT = (command | EN);

P1OUT = command;

}

//void delayus (int us)

void delay (int count)

{

CCR0 = (count + 50000); // CCR0 is the value that TAR (Timer counter) counts to

TACTL = TASSEL_1 + MC_2; // Start ACLK, continuous mode

while (TAR < count); // Waits until specified count is reached

CCR0 = 0; // Stops timer

TACTL &= TACLR; // Resets counter (TAR) and timer

}

Is the LCD suitable for low-voltage operation? You might need a negative supply for the contrast input, even if it is suitable.

Leon

I have the LCD 5V supply and contrast voltage connected separately from the micro, and it is visibly turning on (the default on state with no signals going to it). I just cannot figure out what is wrong with the software.

You seem to be sending the bits of data to the LCD in a completely random order. With the LCD data pins assigned to port pins in reverse, you can’t just shift & mask the character data; you’d have to set each bit individually.

Thanks for spotting that problem. I fixed my LCD_data so that I’m assigning each individual bit separately. However, I’m still not showing anything. I’m pretty sure something else is wrong b/c even with the incorrect LCD_data function, I should have been getting some junk characters. However, I’m just getting the same screen that appears when voltage is supplied initially. Should I be asserting my R/W signal at any time? (I am not right now.)

void LCD_data(unsigned char data)

{

unsigned char upper, lower;

unsigned char d7, d6, d5, d4, d3, d2, d1, d0;

d7 = ((data >> 4) & 0x08);

d6 = ((data >> 2) & 0x10);

d5 = (data & 0x20);

d4 = ((data << 2) & 0x40);

upper = (d4 | d5 | d6 | d7);

P1OUT = ((upper & 0x78) | EN | RS);

P1OUT = ((upper & 0x78) | RS);

d3 = ((data >> 4) & 0x08);

d2 = ((data >> 2) & 0x10);

d1 = (data & 0x20);

d0 = ((data << 2) & 0x40);

lower = (d0 | d1 | d2 | d3);

P1OUT = ((lower & 0x78) | EN | RS);

P1OUT = ((lower & 0x78) | RS);

delay(7);

delay(7);

}

That can’t possibly be right: you’re generating exactly the same value in ‘upper’ and ‘lower’, no matter what the character is.

You have to perform the same bit shuffling on LCD commands, too. If you don’t get that right, you never enable the display.

I also think the init sequence is wrong. shouldn’t there be something before the 20 mS delay? I don’t recall what it is off the top of my head, though.