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.
Tool/software: Code Composer Studio
Hello,
I am trying to interface a generic 1602 LCD (model number or any similar identifier is not written anywhere on my LCD except A1602) with my MSP430FR2355 launchpad using CCSv9 (x64).
I don't want to use any ready-made library and want to drive the LCD on my own. The LCD works fine when driven using an Arduino UNO (using LiquidCrystal.h).
I am taking help from this tutorial and operational details of the LCD form this link
Also, I am aware of the fact that LCD operates on 5V whereas MSP430 is 3V3 device. So I am not using any read operation for LCD (transfer of data from LCD to MCU) and only LCD write operations are used which are compliant as per logic levels for the LCD (Vih and Vil) (Or please let me know If I am incorrect here).
All the pin connections are done correctly (and directly without using any level shifter or potential divider for 5V-3V3)
Please let me know if there is any mis-match in the code as per the timing diagrams of the LCD or any other error.
Thanks in advance.
Below is the code that I am trying to run on the launchpad.
/*LCD interfacing using MSP430FR2355 launch pad * LCD is working in 8bit mode with RS RW EN signals */ #include <msp430.h> //Pin declarations #define RS BIT0 //P2.0 as RS signal #define RW BIT2 //P2.2 as RW signal #define EN BIT1 //P2.1 as EN signal //LCD commands #define IFSCR 0x38 //Use full screen of LCD i.e. 2 lines and 5×7 matrix #define LCDON 0x0F //LCD ON, Cursor ON, Cursor blinking ON #define ICURSOR 0x06 //Increment cursor #define CLRSCR 0x01 //Clear screen #define DCURSOR 0x04 //Decrement cursor #define RHOME 0x02 //Return home #define DNCBF 0x0E //Display ON ,Cursor blinking OFF #define C0101 0x80 //Force cursor to the beginning of 1st line #define C0201 0xC0 //Force cursor to the beginning of 2nd line #define CPOSITION 3 0x83 //Cursor line 1 position 3 #define AL2 0x3C //Activate second line #define DFCF 0x08 //Display OFF, Cursor OFF #define seconLINEposition1 0xC1 //Jump to second line, position1 #define DNCF 0xOC //Display ON, Cursor OFF #define seconLINEposition1 0xC1 //Jump to second line, position1 #define JPOSITION2 0xC2 //Jump to second line, position2 //LCD signal handling shortcuts #define lcdDL (P3OUT) //Using Port 3 for LCD data lines (D0-D7) #define cmdRegSel (P2OUT &= ~RS) //Select command register by RS=LOW #define datRegSel (P2OUT |= RS) //Select data register by RS=HIGH #define lcdRead (P2OUT |= RW) //Select Read mode by RW=HIGH #define lcdWrite (P2OUT &= ~RW) //Select Write mode by RW=LOW #define lcdFall (P2OUT &= ~EN) //Set enable signal LOW #define lcdRise (P2OUT |= EN) //Set enable signal HIGH //GPIO LED #define RON (P1OUT = BIT0) #define ROFF (P1OUT = 0x00) void delay(int T); void lcdInit(void); int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer PM5CTL0 &= ~LOCKLPM5; //Disable High impedance mode of pins P1DIR = BIT0; //GPIO indicator LED at P1.0 lcdInit(); //LCD initialization function defined after main() //Printing a character '3' on the LCD datRegSel; //Select data register of LCD lcdWrite; //Set RW signal lcdRise; // Rising edge on EN lcdDL = 51; //Sending 00110011b to the LCD data register delay(1); lcdFall; //Falling edge on EN delay(1); while(1) {RON; delay(100); ROFF; delay(100);} return 0; } void lcdInit(void) { //Using pins as Output P2DIR = RS|RW|EN; //Control signals as output pins P3DIR = 0xFF; //All pins as output //Initialize signal lines lcdFall; lcdRead; lcdDL=0; //Sending IFSCR command cmdRegSel; lcdWrite; lcdRise; lcdDL = IFSCR; delay(1); lcdFall; delay(1); //Sending LCDON command cmdRegSel; lcdWrite; lcdRise; lcdDL = LCDON; delay(1); lcdFall; delay(1); //Sending ICURSOR command cmdRegSel; lcdWrite; lcdRise; lcdDL = ICURSOR; delay(1); lcdFall; delay(1); //Sending CLRSCR command cmdRegSel; lcdWrite; lcdRise; lcdDL = CLRSCR; delay(1); lcdFall; delay(1); //Sending C0101 command cmdRegSel; lcdWrite; lcdRise; lcdDL = C0101; delay(1); lcdFall; delay(1); } void delay(int T) { TB2EX0=0x04; //Divide input clock by 4 TB2CCR0 = T;// Set the count of milliseconds TB2CTL = TBSSEL_1 | ID_3 | MC_1; //ACLK (32.768KHz) divided by 8 running in UP Mode. Thus resulting time is 976.5uS (1mS approx.) while( (TB2CCTL0 & CCIFG) != CCIFG ); TB2CCTL0 &= ~CCIFG; TB2CTL = MC_0; }
The data sheets for the character LCD modules are pretty clear about the initialization process. In particular about the requirement for delays longer than 1ms at times. Such as waiting at least 15ms after power up before sending commands. You also have to send the function set command more than once.
I have used these 5V modules with the MSP430 in read mode by adding series resistors to limit fault currents
Hi David
Thanks for the reply.
I understood the concept behind those current limiting resistors but can you please elaborate a bit more as in where am I lacking? Imean in that delay part that you have mentioned.
Is it like I have to wait for atleast 15ms before calling lcdInit() ?
Thank you
Hey Maneesh,
I think David means that often the LCD needs some time between the LCD being enabled and being ready to receive commands. So, make sure that once the LCD is first powered and enabled to give it some time. This should be defined in the LCD datasheet.
Also, usually, the LCD contrast is tied to the voltage it is supplied and sometimes you can use a potentiometer to adjust it. If it's usually a 5V LCD and you supply it with 3.3V the contrast might be very light and difficult to see. So, maybe you can supply the LCD with 5V while still communication with 3.3V.
Good Luck,
JD
Hi JD
On the powering LCD part, I have supplied the LCD with 5V and the potentiometer circuit is also in its proper place (connected to 5V VO GND).
Along with that, I didn't power down the LCD at all. It is just that I am debugging updated codes in the MCU which is not giving output. As far as I know, PUC or POR doesn't affects the on-board power supply which means that LCD is always powered ON. That implies the code should work even without that 15ms delay (Though I will add a delay for that specification to remain on a safer side). I just wanna know if there is any error in the above posted code (other than the 15ms delay before calling lcdInit() ).
Thanks and Regards
Maneesh
Hi David
Thankyou for the PDF (it is a detailed one). I will look into that to correct any errors.
Thanks
**Attention** This is a public forum