This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Interfacing LCD module JHD 162A with MSP430g2553

Other Parts Discussed in Thread: MSP430G2553

Hi. ..

       I am currently using msp430g2553 which came along the launchpad. I am facing problems regarding interfacing the LCD module. I am currently using JHD 162A 16x2.

I am new to the msp, so can anyone suggest me some online tutorials specific for the msp. I have found many tutorials on other platforms but not able to find one for the msp's.

i am current using the following code form a site, its as under

i have connected the pins as per the tutorial.

I have changed the include file with "msp430g2553.h".

// MSP430 LCD interface
//
//                  |      LCM      |  
// LCM Pin #  |  Function  |   MSP Pin #
//----------------------------
//  PIN 5        |      RW        |     GND
//  PIN 4        |      RS         |     P1.0
//  PIN 6        |      EN         |    P1.1
//  PIN 14      |      DB7       |    P1.7     
//  PIN 13      |      DB6       |    P1.6     
//  PIN 12      |      DB5       |    P1.5     
//  PIN 11      |      DB4       |    P1.4     
//
The other LCM pins connections are as follows:
Pin #16         |       GND         
Pin #15         |       Vcc 
Pin #3           |       Outout from potentiometer for LCD contrast
Pin #1           |       GND
Pin #2           |       Vcc
This is all the code for the MSP430 LCD driver. A simple flow is demonstrated in the main() function. This code should be copy-paste runnable on the value line part plugged into the shipping launchpad. If things aren't working it might be because your LCD module is slower.  Try extending the __delay_cycles, first in the Initialization routine. If that doesn't fix it extend the delay time in the pulse module as well.


 
//
// MSP430 LCD Code
//
 
#include  "msp430x20x2.h"

#define     LCM_DIR               P1DIR
#define     LCM_OUT               P1OUT

//
// Define symbolic LCM - MCU pin mappings
// We've set DATA PIN TO 4,5,6,7 for easy translation
//
#define     LCM_PIN_RS            BIT0          // P1.0
#define     LCM_PIN_EN            BIT1          // P1.1
#define     LCM_PIN_D7            BIT7          // P1.7
#define     LCM_PIN_D6            BIT6          // P1.6
#define     LCM_PIN_D5            BIT5          // P1.5
#define     LCM_PIN_D4            BIT4          // P1.4


#define     LCM_PIN_MASK  ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4))

#define     FALSE                 0
#define     TRUE                  1

//
// Routine Desc:
// 
// This is the function that must be called 
// whenever the LCM needs to be told to 
// scan it's data bus.
//
// Parameters:
//
//     void.
//
// Return
//
//     void.
//
void PulseLcm()
{
    //
    // pull EN bit low
    //
    LCM_OUT &= ~LCM_PIN_EN;
    __delay_cycles(200);

    //
    // pull EN bit high
    //
    LCM_OUT |= LCM_PIN_EN;
    __delay_cycles(200);

    //
    // pull EN bit low again
    //
    LCM_OUT &= (~LCM_PIN_EN);
    __delay_cycles(200);
}



//
// Routine Desc:
// 
// Send a byte on the data bus in the 4 bit mode
// This requires sending the data in two chunks.
// The high nibble first and then the low nible
//
// Parameters:
//
//    ByteToSend - the single byte to send
//
//    IsData - set to TRUE if the byte is character data
//                  FALSE if its a command
//
// Return
//
//     void.
//
void SendByte(char ByteToSend, int IsData)
{
    //
    // clear out all pins
    //
    LCM_OUT &= (~LCM_PIN_MASK);
    //
    // set High Nibble (HN) - 
    // usefulness of the identity mapping
    // apparent here. We can set the 
    // DB7 - DB4 just by setting P1.7 - P1.4 
    // using a simple assignment
    //
    LCM_OUT |= (ByteToSend & 0xF0);
 
    if (IsData == TRUE)
    {
        LCM_OUT |= LCM_PIN_RS;
    }
    else
    {
        LCM_OUT &= ~LCM_PIN_RS;
    }
 
    //
    // we've set up the input voltages to the LCM.
    // Now tell it to read them.
    // 
    PulseLcm();
     //
    // set Low Nibble (LN) -
    // usefulness of the identity mapping
    // apparent here. We can set the 
    // DB7 - DB4 just by setting P1.7 - P1.4 
    // using a simple assignment
    //
    LCM_OUT &= (~LCM_PIN_MASK);
    LCM_OUT |= ((ByteToSend & 0x0F) << 4);

    if (IsData == TRUE)
    {
        LCM_OUT |= LCM_PIN_RS;
    }
    else
    {
        LCM_OUT &= ~LCM_PIN_RS;
    }

    //
    // we've set up the input voltages to the LCM.
    // Now tell it to read them.
    // 
    PulseLcm();
}


//
// Routine Desc:
// 
// Set the position of the cursor on the screen
// 
// Parameters:
//
//     Row - zero based row number
//
//     Col - zero based col number
// 
// Return
//
//     void.
//
void LcmSetCursorPosition(char Row, char Col)
{
    char address;

    //
    // construct address from (Row, Col) pair
    //
    if (Row == 0)
    {
        address = 0;
    }
    else
    {
        address = 0x40;
    }

    address |= Col;

    SendByte(0x80 | address, FALSE);
}


//
// Routine Desc:
// 
// Clear the screen data and return the
// cursor to home position
// 
// Parameters:
//
//    void.
// 
// Return
//
//     void.
//
void ClearLcmScreen()
{
    //
    // Clear display, return home
    //
    SendByte(0x01, FALSE);
    SendByte(0x02, FALSE);
}


//
// Routine Desc:
// 
// Initialize the LCM after power-up.
// 
// Note: This routine must not be called twice on the
//           LCM. This is not so uncommon when the power
//           for the MCU and LCM are separate.
// 
// Parameters:
//
//    void.
// 
// Return
//
//     void.
//
void InitializeLcm(void)
{
    //
    // set the MSP pin configurations
    // and bring them to low
    //
    LCM_DIR |= LCM_PIN_MASK;
    LCM_OUT &= ~(LCM_PIN_MASK);


    //
    // wait for the LCM to warm up and reach
    // active regions. Remember MSPs can power
    // up much faster than the LCM.
    //
    __delay_cycles(100000);

    
    //
    // initialize the LCM module
    //
    // 1. Set 4-bit input 
    //
    LCM_OUT &= ~LCM_PIN_RS;
    LCM_OUT &= ~LCM_PIN_EN;

    LCM_OUT = 0x20;
    PulseLcm();

    //
    // set 4-bit input - second time.
    // (as reqd by the spec.)
    // 
    SendByte(0x28, FALSE);

    //
    // 2. Display on, cursor on, blink cursor
    //
    SendByte(0x0E, FALSE);
    
    //
    // 3. Cursor move auto-increment
    //
    SendByte(0x06, FALSE);
}


//
// Routine Desc
//
// Print a string of characters to the screen
//
// Parameters:
// 
//    Text - null terminated string of chars
//
// Returns
// 
//     void.
//
void PrintStr(char *Text)
{
    char *c;

    c = Text;

    while ((c != 0) && (*c != 0))
    {
        SendByte(*c, TRUE);
        c++;
    }
}


//
// Routine Desc
//
// main entry point to the sketch
//
// Parameters
// 
//     void.
//
// Returns
// 
//     void.
//
void main(void)
{
    WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

    InitializeLcm();

    ClearLcmScreen();

    PrintStr("Hello World!");

    while (1)
    {
        __delay_cycles(1000);
    }

}
  • On LaunchPad, P1.1 (EN) is connected with the FET part of the LaunchPad for backchannel UART. Maybe you need to remove the RX/TX jumpers from the LaunchPad to make it work.

    On original LaunchPad, it was the TX line, so the connection was output (connected to a FET input), but on newer LaunchPads, these lines are switched by default, since the 2553 has a hardware UART with switched lines. Now P1.1 is an input, driven from the FET. Your software was written for the original LaunchPad and doesn't reflect this.

    For future projects keep in mind that the assignment of pin functions may change from one family member to another, so simply changing the header file is perhaps not enough. hence the defines at program start for LCM_DIR, LCM_PIN_x etc.

  • thanks... for your suggestion.

    I removed the TXD and RXD JUMPERS but nothing happened. Could you suggest more on it.

    Is it always necessary to add library files for the lcd? 

  •  Hi Lovelesh, I corrected a code but is a time consuming task, I debugged it after checking my code finding a bug on 4bit mode, this code has an original idea of use non in order pin of port and definitively can solve your problem so please in first read this thread:

    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/146434.aspx?PageIndex=2

     try final code tailoring to your hardware then tell me if it work, some refinement can be apply'd to code but it's ok for now, you can adapt with a simple shift and write if you use in order bit from port.

     Regards

     Roberto

**Attention** This is a public forum