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.

LCD S0802X how to communicate with MSP430F

Other Parts Discussed in Thread: MSP430F47197

The LCD that I currently use is NMTC-S0802XRGHS with the following address to its guide-sheet.

 I can show 2 line by 8 character in each line.
The thing is I am using MSP430F47197  and would like to connect it to the LCD.
The issue is even though I know my connection of LCD to the board (hardware-wise), I do not know if the ports are communicating with micro or not?
On the pages 74 and 75, it is said "Function" but I don't know whether I need to use P(O/I) or S which is a pin number.
Let's say E is assigned to the pin P8.2 but this pin has DIR, SEL, LCD Control. 
That is why I am a little bit confused. Do you have any experience on this?
The question is how to address the MCU's pins in order to communicate with LCD.
Refer to my previous post, please kindly read it here:
  • Communication between LCD and MCU is kind of challenging. Nobody to explain please?

  • CaEngineer said:
    Let's say E is assigned to the pin P8.2 but this pin has DIR, SEL, LCD Control. 
    That is why I am a little bit confused. Do you have any experience on this?

    Chip MSP430F47197 you use can drive bare LCD directly which is not your case because display you use already have built-in LCD controller chip which shall be controlled using CMOS logic signals as per datasheet.

    Simple google search https://www.google.com/search?q=msp430+2+line+lcd+display

    resulted in many results, such as:

    http://www.instructables.com/id/Interfacing-16x2-LCD-with-msp430-launchpad-in-8-bi/

  • Ilmars said:
    Chip MSP430F47197 you use can drive bare LCD directly

    You mean that I do not need to initialize and define functions and just use LCD controls in MSP?

  • CaEngineer said:
    You mean that I do not need to initialize and define functions and just use LCD controls in MSP?

    Opposite:

    Ilmars said:
    display you use already have built-in LCD controller chip which shall be controlled using CMOS logic signals

  • Ilmars said:
    display you use already have built-in LCD controller chip which shall be controlled using CMOS logic signals

    Well, actually I know that I need to set its bits (as you said logic signals) to the right modes. But have no progress to make it communicate with MCU yet.

    As my LCD DBs are connected to P7 of MCU and in the datasheet of MSP430 as you can see here:

    Function part is tricky as I don't know should I set LCD24 and P7SEL to zero and DIR to 1 and follow the first line or follow the settings for S27?!

    Set the functions in LCD is easy but connecting to MCU is confusing as I can see only LCD's cells on the screen and nothing changes!

  • CaEngineer said:
    I don't know should I set LCD24 and P7SEL to zero and DIR to 1 and follow the first line or follow the settings for S27?!

    As I said already - you don't touch built-in LCD controller of msp430 because display of your choice have one, so do not set LCDS24 bits. P1SEL is about peripheral functions which you also don't need in your application, leave them set to 0. So P1DIR register is only you shall touch (set to "1")  if your signal goes in direction from msp430 to LCD (having embedded controller). Otherwise set it to 0.

  • Ok llmars but I did not understand the link between LCD and P1DIR as my connection has nothing to do with P1?!

    En LCD ==> P8.3 MSP430F

    RW ==> P8.1

    RS ==> P8.0

    DB7 ==> P7.7

    DB6 ==> P7.6

    DB5 ==> P7.5

    DB4 ==> P7.4

    DB3 ==> P7.3

    DB2 ==> P7.2

    DB1 ==> P7.1

    DB0 ==> P7.0

  • CaEngineer said:
    I did not understand the link between LCD and P1DIR as my connection has nothing to do with P1?!

    This is good that you noticed my typing error.

  • Oh Ok then P7 and P8 DIR should be set to high as outputs. Right? From there on, I guess I need to define the functions and use in my main. but still need to set  LCDAPCTL0 and LCDACTL. Is this right?

  • CaEngineer said:
    still need to set  LCDAPCTL0 and LCDACTL. Is this right?

    No. Because:

    Ilmars said:
    display you use already have built-in LCD controller chip which shall be controlled using CMOS logic signals

     

  • Oh I see. I will keep you updated about my findings shortly.  Thanks a lot!

  • The LCD controller you are using is a descendant of Hitachi HD44780. Similar ones are very common. (See http://en.wikipedia.org/wiki/Hitachi_HD44780_LCD_controller.) There are many MSP430 examples using them. They have nothing to do with the LCD controller inside the F4xx and F6xx and are can be used by F1xx, F2xx, F5xx and other MSP430 or other micros alike. The URL cited by llmas is very helpful.

    Please note that aside from connecting its Vdd and Vss to the same power rail of MSP430, you need an adjustable negative voltage on its Vo pin so that Vo is about 4.5V below Vdd. (That is, it needs to be about -1.5V relative to Vss. when Vdd is 3V) This voltage is the contrast adjustment. Without this, you will not be able to read the LCD. If you want, you can use MSP430 to generate this negative voltage. But do not side track yourself. You can do that later.

    From MSP430s point of view,  E, RS, R/W should be output pins. B7...B0 are bidirectional. That is, normally in high impedance (input), read them as input before the falling edge of E. Change them to output and drive them as output during R/W=0 before the rising edge of E and restore them to high impedance (input) after falling edge of E.

    -- OCY

  • Thanks for your explanation OCY. But I guess I have to write  a driver for the LCD which is not as easy as it looks like! I try to find a code somewhere from maybe a similar LCD here:

    https://www.sparkfun.com/products/11708

  • Can anyone help me on the following code regarding the LCD driver please?


    #include "msp430f47197.h"

    /*
    #define LCD_data P7OUT // P7
    #define LCD_D7 BIT3 // P7.7
    #define LCD_rs BIT0 // P8.0
    #define LCD_rw BIT1 // P8.1
    #define LCD_en BIT2 // P8.2


    */

    /*


    En LCD ==> P8.2 MSP430F

    RW ==> P8.1

    RS ==> P8.0

    DB7 ==> P7.7

    DB6 ==> P7.6

    DB5 ==> P7.5

    DB4 ==> P7.4

    DB3 ==> P7.3

    DB2 ==> P7.2

    DB1 ==> P7.1

    DB0 ==> P7.0


    */

    void LCD_busy()
    {

    P7OUT += 0x01 ; //Make D7th bit of LCD as i/p ==> P7OUT += 0x01 or LCD_D7 == 1
    P8OUT += 0x04 ; //Make port pin as o/p P8.2 += 0x04 or LCD_en
    P8OUT *= 0xFE ; //Selected command register P8.0 *= 0xFE or LCD_rs == 0
    P8OUT += 0x02 ; //We are reading P8.1 or LCD_rw == 1

    while(P7OUT){ //read busy flag again and again till it becomes 0
    P8OUT *= 0xFB; //Enable H->L LCD_en == 0
    P8OUT += 0x04; // LCD_en == 1
    }

    }

    void LCD_init()
    {
    P7OUT = 0x38; //Function set: 2 Line, 8-bit, 5x7 dots LCD_data = 0x38
    P8OUT *= 0xFE ; //Selected command register
    P8OUT *= 0xFD; //We are writing in data register
    P8OUT += 0x04 ; //Enable H->L
    P8OUT *= 0xFB;
    LCD_busy(); //Wait for LCD to process the command
    P7OUT = 0x0F; //Display on, Curson blinking command
    P8OUT *= 0xFE ; //Selected command register
    P8OUT *= 0xFD; //We are writing in data register
    P8OUT += 0x04 ;//Enable H->L
    P8OUT *= 0xFB;
    LCD_busy(); //Wait for LCD to process the command
    P7OUT = 0x01; //Clear LCD
    P8OUT *= 0xFE ; //Selected command register
    P8OUT *= 0xFD;//We are writing in data register
    P8OUT += 0x04 ; //Enable H->L
    P8OUT *= 0xFB;
    LCD_busy(); //Wait for LCD to process the command
    P7OUT = 0x06; //Entry mode, auto increment with no shift
    P8OUT *= 0xFE ; //Selected command register
    P8OUT *= 0xFD; //We are writing in data register
    P8OUT += 0x04 ; //Enable H->L
    LCD_busy();
    }

    void LCD_senddata(unsigned char var)
    {
    P7OUT = var; //Function set: 2 Line, 8-bit, 5x7 dots
    P8OUT += 0x01; //Selected data register
    P8OUT *= 0xFD; //We are writing
    P8OUT += 0x04; //Enable H->L
    P8OUT *= 0xFB;
    LCD_busy(); //Wait for LCD to process the command
    }
    // Using the above function is really simple
    // we will pass the character to display as argument to function
    // e.g.
    //
    // LCD_senddata('A');

    void LCD_sendstring(unsigned char *var)
    {
    while(*var) //till string ends
    LCD_senddata(*var++); //send characters one by one
    }


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

    P8DIR += 0x07; // Set P8 as an output
    P8SEL *= 0xF8;


    P7DIR += 0xFF;
    P7SEL *= 0x00;



    LCD_sendstring("Hello World");
    }

  • CaEngineer said:
    Can anyone help me on the following code regarding the LCD driver please?

    Approach "here's my code, please fix it" - to say it politely, is not that good.

    You missed to tell your question. What did not happen as you expect? What did you try to fix it?

  • I was expecting to see "Hello World" on the LCD and I started from scratch to make MCU and LCD connected with each other.

  • You was expecting "hello wold" but did not see it? That's it?? Did you try to debug your code? Go step by step looking into register values to see that your code actually are doing what you intend to?

    What I can say - your bit manipulation code is totally wrong:

    P7OUT += 0x01 ; //Make D7th bit of LCD as i/p ==> P7OUT += 0x01 or LCD_D7 == 1
    P8OUT += 0x04 ; //Make port pin as o/p P8.2 += 0x04 or LCD_en
    P8OUT *= 0xFE ; //Selected command register P8.0 *= 0xFE or LCD_rs == 0
    P8OUT += 0x02 ; //We are reading P8.1 or LCD_rw == 1

    If you want to set BIT0 of P7OUT then you do this:

    P7OUT |= 0x01

    If you want to reset same bit, then you do this:

    P7OUT &= ~0x01

  • while(P7OUT){ //read busy flag again and again till it becomes 0

    It will not become 0 unless you (your code) don't set P7OUT to 0.

    Perhaps you wanted to check some input pin on port7?

  • Ilmars said:

    You was expecting "hello wold" but did not see it? That's it?? Did you try to debug your code? Go step by step looking into register values to see that your code actually are doing what you intend to?

    What I can say - your bit manipulation code is totally wrong:

    P7OUT += 0x01 ; //Make D7th bit of LCD as i/p ==> P7OUT += 0x01 or LCD_D7 == 1
    P8OUT += 0x04 ; //Make port pin as o/p P8.2 += 0x04 or LCD_en
    P8OUT *= 0xFE ; //Selected command register P8.0 *= 0xFE or LCD_rs == 0
    P8OUT += 0x02 ; //We are reading P8.1 or LCD_rw == 1

    If you want to set BIT0 of P7OUT then you do this:

    P7OUT |= 0x01

    If you want to reset same bit, then you do this:

    P7OUT &= ~0x01

    Oh shoot! Good point. Thanks!

  • Ilmars said:

    while(P7OUT){ //read busy flag again and again till it becomes 0

    It will not become 0 unless you (your code) don't set P7OUT to 0.

    Perhaps you wanted to check some input pin on port7?

    Yes, another mistake. I just change it to the following.

    void LCD_busy()
    {
    unsigned char i,j;
    for(i=0;i<50;i++) //A simple for loop for delay
    for(j=0;j<255;j++);
    }

  • Ilmars said:

    Can anyone help me on the following code regarding the LCD driver please?

    Approach "here's my code, please fix it" - to say it politely, is not that good.

    You missed to tell your question. What did not happen as you expect? What did you try to fix it?

    [/quote]

    Ok I will ask my questions more specifically from now on! I promise! 

  • Why don't you look around and see how others do it? It's interesting to invent wheel, but sometimes you shall just look how others did it.

    https://www.olimex.com/Products/MSP430/Starter/MSP430-169STK/

    This board have 2x16 display connected to P5. Source code available:

    https://www.olimex.com/Products/MSP430/Starter/MSP430-169STK/resources/MSP430-169STK.zip

  • Actually I found the following much easier to understand and follow. BTW, thanks for your time.

    http://www.ece.utep.edu/courses/web3376/Lab_5_-_LCD.html

**Attention** This is a public forum