The LCD that I currently use is NMTC-S0802XRGHS with the following address to its guide-sheet.
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.
The LCD that I currently use is NMTC-S0802XRGHS with the following address to its guide-sheet.
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
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?
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
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 == 1If 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.
**Attention** This is a public forum