Introduction: Interfacing 16x2 LCD With Msp430 Launchpad in 4 Bit Mode

In this instructable I'm writing about 16x2 LCD interfacing with msp430g2553 microcontroller. If you don't know about 8 bit mode then I recommend that you read my instructable on 8 bit interfacing. Now I'm assuming in this instructable that you've already read that part.

Step 1: Theory

Need for 4 bit mode

Well for interfacing anything with any processor we need system-bus (data-bus, address-bus and control-bus). In our case for 8 bit mode the 8 data pins (D0-D7) are the data and address bus while the 3 control pins(RS, R/W and E) are the control bus. Thus using these we can control the peripheral that we are interfacing. We are greedy so we want to interface as many peripherals as possible with the same microcontroller. This requires either large number of ports or we need to be smart and utilize what we have to the fullest. Thus first thing is we try to do is reduce the number of pins required for controlling the peripheral. Here comes the need for 4 bit mode. Thus we reduce the port pins required from 11 to 7. It might not seem much, but for a small microcontroller like msp430g2553 with limited port pins this is really a big amount. Now coming to the other method. Maybe we can use demultiplexing , in this way we can use 'n' lines to share the system bus with '2^n' devices. I got one tip that we can use SIPO shift register for sending data. Now this will require only 5 port pins. Three control pins and two for serial data and clock.

4 bit mode working

In 4 bit mode we send the data nibble by nibble, first upper nibble and then lower nibble. For those of you who don't know what a nibble is: a nibble is a group of four bits, so the lower four bits (D0-D3) of a byte form the lower nibble while the upper four bits (D4-D7) of a byte form the higher nibble. This enables us to send 8 bit data be it the ASCII code or the command code by using 4 pins instead of 8. The connections remain identical. The only change is that the lower nibble pins of LCD are unused.

Initializing the LCD in 4 bit mode

This is perhaps the most tricky part of this interfacing. When LCD is powered ON it is by default in 8 bit mode.

reset(see pic)

This is the command code format for function set operation. Using this we form the command code for 4 bit mode operation.

mode_set(see pic)

The function set bits are explained in the following section.

functions_mode_set_bits(see pic)

We need 4 bit mode so make DL '0'. Thus the upper nibble of the command code is 0010b which is 0x02. If we need 2 lines we set N and the normal font so F is 0 thus lower nibble comes out to be 1000b i.e 0x08. Thus total command code is 0x28.

Before sending this 0x28 we need to perform a specific initialization.

initialization(see pic)

So we send 0x33 as the command code. This will do the initial 8 bit mode starting of LCD. Now after this we need to send 0x32.(Note : We're using the nibble method so what will go for 0x33 is 3 followed by 3 and for 0x32 is 3 followed by 2.)

So now we have initialized the LCD in 4 bit mode. All we need to learn is how to send the value nibble by nibble in c and without affecting other port pins except the ones that we use for sending data. (In assembly its just the rotate instruction.)

Nibble sending logic

P1OUT = (P1OUT & 0xF0)|((data>>4) & 0x0F); // send higher nibble

In this we make use of masking concept and logical shift operation in c. Now in my program I'm using P1.0 - P1.3 pins as the data pins. Thus I'll explain the logic accordingly. Here data is the parameter that is passed in the function. I shift the data right by four bits, thus bringing the higher nibble in the lower nibble location. Mask the upper part. Then I make the P1OUT lower nibble 0 so that 'or'ing with nibble data will give nibble data on P1OUT pin. (x and 0 is 0 ; x and 1 is x; x or 1 is 1 and x or 0 is x----> (x&0)|(data_bit)= 0|data_bit= data_bit. Thus we get data bit on the port pin without affecting P1.4-P1.7) This takes care of upper nibble.

P1OUT = (P1OUT & 0xF0)|(data & 0x0F); // send lower nibble

Now lower nibble involves the same operations except the shifting operation.

Step 2: Code and Connections

Header file :
// Author : Manpreet Singh Minhas
// This file is for 4 bit mode LCD interfacing with msp430g2553 chip
// 16x2 LCD is used
#include <msp430g2553.h>
#define DR P1OUT = P1OUT | BIT4 // define RS high
#define CWR P1OUT = P1OUT & (~BIT4) // define RS low
#define READ P1OUT = P1OUT | BIT5 // define Read signal R/W = 1 for reading
#define WRITE P1OUT = P1OUT & (~BIT5) // define Write signal R/W = 0 for writing
#define ENABLE_HIGH P1OUT = P1OUT | BIT6 // define Enable high signal
#define ENABLE_LOW P1OUT = P1OUT & (~BIT6) // define Enable Low signal
unsigned int i;
unsigned int j;
void delay(unsigned int k)
{
for(j=0;j<=k;j++)
{
for(i=0;i<100;i++);
}
}
void data_write(void)
{
ENABLE_HIGH;
delay(2);
ENABLE_LOW;
}
void data_read(void)
{
ENABLE_LOW;
delay(2);
ENABLE_HIGH;
}
void check_busy(void)
{
P1DIR &= ~(BIT3); // make P1.3 as input
while((P1IN&BIT3)==1)
{
data_read();
}
P1DIR |= BIT3; // make P1.3 as output
}
void send_command(unsigned char cmd)
{
check_busy();
WRITE;
CWR;
P1OUT = (P1OUT & 0xF0)|((cmd>>4) & 0x0F); // send higher nibble
data_write(); // give enable trigger
P1OUT = (P1OUT & 0xF0)|(cmd & 0x0F); // send lower nibble
data_write(); // give enable trigger
}
void send_data(unsigned char data)
{
check_busy();
WRITE;
DR;
P1OUT = (P1OUT & 0xF0)|((data>>4) & 0x0F); // send higher nibble
data_write(); // give enable trigger
P1OUT = (P1OUT & 0xF0)|(data & 0x0F); // send lower nibble
data_write(); // give enable trigger
}
void send_string(char *s)
{
while(*s)
{
send_data(*s);
s++;
}
}
void lcd_init(void)
{
P1DIR |= 0xFF;
P1OUT &= 0x00;
send_command(0x33);
send_command(0x32);
send_command(0x28); // 4 bit mode
send_command(0x0E); // clear the screen
send_command(0x01); // display on cursor on
send_command(0x06); // increment cursor
send_command(0x80); // row 1 column 1
}
Main Code:
/* LCD_own.c
* Created on: 12-Nov-2013
* Author: Manpreet
* In this program we interface the lcd in 4 bit mode. We send strings and display it on the screen.
*/
#include "lcd.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer
lcd_init();
send_string("Manpreet Singh");
send_command(0xC0);
send_string("Minhas");
while(1){}
}
Connections
P1.0 - D4 Pin11
P1.1 - D5 Pin12
P1.2 - D6 Pin13
P1.3 - D7 Pin14
P1.4 - RS Pin4
P1.5 - R/W Pin5
P1.6 - E Pin6

P.S: To know more about msp430 please visit my blog Learning-msp430

Comments

author
Joshua+nziku made it!(author)2017-02-17

thanks for your codes, from there i want to interface msp430 with tdc7200 how can i do

author
vishal28 made it!(author)2015-07-04

i am using mspg2553

author
vishal28 made it!(author)2015-07-04

i am using mspg2553

author
vishal28 made it!(author)2015-07-04

is it necessary to use lcd.h before the void main () as ccs software says that couldn't open source file
plz tell the solution

author
MagnusF made it!(author)2015-06-19

Hello

I have implemented your code on MSP430f5529 with a 4x20 display.
After i figured out the commands for the right cursor positions, it works perfectly.
However i can't figure out how to print a variable on the display..

I was thinking of something like:

int number = 12;
send_string("And the winner is .. %d", number);

Which is supposed to return:

"And the winner is .. 12"

Any ideas?

author
msminhas93 made it!(author)2015-06-21

You have to just create a function with two parameters or arguments.

send_var(char *s, int i)

{

send_string(s);

send_integer(i);

}

The logic for both the send functions is already explained in the instructable. Hope this helps.

author
RanjitR made it!(author)2015-01-03

sir

pls give me programming code for LDR and

how to connect ldr to the msp430g2553 for measuring light intensity.

ldr o/p connect to ADC pin and these pin connect to the Tx pin of same board for transmit the data.

50% work will be completed only ADC part remaining...so help me.

RANJIT

author
dineshn19 made it!(author)2014-10-30

Hi,

thanks for the clear explanation, it worked for me in the first shot.

my problem was that the lcd was not initializing in the properly.

after i used

send_command(0x33);
send_command(0x32);
send_command(0x28); // 4 bit mode
send_command(0x0E); // clear the screen
send_command(0x01); // display on cursor on
send_command(0x06); // increment cursor
send_command(0x80); // row 1 column 1

in this this order it worked.

Dinesh

author
SSURESHREDDY made it!(author)2014-04-01

Hi, I tried the same with 8X2 LCD and MSP430 launchpad but nothing it is displaying.

I have a doubt, for the LCD communication oscillator is required or not? In my launchpad I didn't used and our code also didn't configured it....

SURESH

author
msminhas93 made it!(author)2014-02-09

Well you'll have to either include the code in the header file or copy paste it in the main program. That depends on you.

author
SSURESHREDDY made it!(author)2014-01-28

Hi, I tried to work on this code, but it is not working properly, please explain how this code will work without having "lcd.h" file.

SURESH

About This Instructable

32,071views

10favorites

License:

Bio: http://about.me/msminhas93
More by msminhas93:Wireless Notice Board using SIM 300 and EK-TM4C1294XLLine follower using msp430g2 launchpadInterfacing 16x2 LCD with msp430 launchpad in 4 bit mode
Add instructable to: