MSP430 - LCD Example

Here is the MSP430G2553 to LCD example, test setup, circuit diagram and program.









Code:
//************************************************
// MSP430 - LCD Test Program
//************************************************

/************************************************

2013.06.22 - MrChips
           - LCD Interface Test
     
************************************************/

#include "io430.h"

#define title1 "MrChips Terminal"
#define title2 "Hello World!"

#define DELAY 20000

//---------------------------------------------------
// LCD Interface
//---------------------------------------------------

void LCD_init(void);
void LCD_ready(void);
void LCD_ir(char ch);
void LCD_dr(char ch);
void LCD_txt(char *s);
void LCD_home(void);
void LCD_clear(void);
void LCD_Line1(void);
void LCD_Line2(void);
void LCD_Line3(void);
void LCD_Line4(void);
void LCD_posn(char n);

// define LCD interface on PORT2
#define LCD_OUT  P2OUT
#define LCD_IN   P2IN
#define LCD_DDR  P2DIR
#define LCD_RS P2OUT_bit.P4
#define LCD_RW P2OUT_bit.P5
#define LCD_E  P2OUT_bit.P6

void LCD_init(void)
{
  LCD_ir(0x28);         // dual line, 4 bits
  LCD_ir(0x06);         // increment mode
  LCD_ir(0x0C);         // cursor turned off
  LCD_ir(0x10);         // cursor right
  LCD_ir(0x01);         // clear display
}

void LCD_clear(void)
{
  LCD_ir(0x01);
}

void LCD_home(void)
{
  LCD_ir(0x02);
}

void LCD_Line1(void)
{
  unsigned char i;
  LCD_ir(0x80);
  for (i = 0; i < 16; i++)
  {
    LCD_dr(0x20);
  }
  LCD_ir(0x80); 
}

void LCD_Line2(void)
{
  unsigned char i;
  LCD_ir(0xC0);
  for (i = 0; i < 16; i++)
  {
    LCD_dr(0x20);
  }
  LCD_ir(0xC0); 
}

void LCD_Line3(void)
{
  LCD_ir(0x94);
}

void LCD_Line4(void)
{
  LCD_ir(0xD4);
}

void LCD_posn(char n)
// direct positioning where n = 0-79
{
  char ch;
  ch = n;
  if (ch  >= 40) ch += 24;
  LCD_ir(ch | 0x80);
}

void LCD_ready(void)
{
  char busy;
  LCD_DDR = 0xF0;
  LCD_RW = 1;
  LCD_RS = 0;
  do
  {
    LCD_E  = 1;
    // high 4 bits read first
    // busy flag is D7 of LCD = bit 3 of P2IN
    busy = (LCD_IN & 0x08);
    LCD_E  = 0;
    LCD_E  = 1;
    LCD_E  = 0;
  } while (busy);
  LCD_OUT = 0;
  LCD_DDR = 0xFF;
}

void LCD_ir(char ch)
{
  LCD_ready();
  //LCD_RS = 0;     // not needed      // select instruction register
  //LCD_RW = 0;     // not needed
  LCD_OUT |= ((ch >> 4) & 0x0F);
  LCD_E = 1;
  LCD_E = 0;
  LCD_OUT = 0;
  LCD_OUT |= (ch & 0x0F);
  LCD_E = 1;
  LCD_E = 0;
}

void LCD_dr(char ch)
{
  LCD_ready();
  LCD_RS = 1;        // select data register
  //LCD_RW = 0;      // not needed
  LCD_OUT |= ((ch >> 4) & 0x0F);
  LCD_E = 1;
  LCD_E = 0;
  LCD_OUT = 0;
  LCD_RS = 1;
  LCD_OUT |= (ch & 0x0F);
  LCD_E = 1;
  LCD_E = 0;
}

void LCD_txt(char *s)
{
  while(*s) LCD_dr(*s++);
}

//---------------------------------------------------
// Hardware Initialization
//---------------------------------------------------

void init(void)
{
   // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD; 
 
  P1DIR = 0xFF;  // configure output ports
  
  P2DIR = 0xFF;
  P2SEL = 0x00;  //select for I/O function
  P2OUT = 0x00;
}

//---------------------------------------------------
// software delay
//---------------------------------------------------

void delay(unsigned long d)
{
  unsigned long i;
  for (i = 0; i < d; i++);
}

//-----------------------------------
//  Main
//-----------------------------------

void main(void)
{
  init();
  LCD_init();
  
  LCD_txt(title1);
  LCD_Line2();
  LCD_txt(title2);
  
  while(1)
  {
    P1OUT_bit.P0 = 0;
    delay(DELAY);
    P1OUT_bit.P0 = 1;
    delay(DELAY);
  }
  
}

//-----------------------------------
//  end of Main
//-----------------------------------
Notes:

1) I have cut and paste the LCD functions from projects I have already done. The extra features such as direct cursor positioning will come in handy in the future.

2) While the display shown has 16 characters x 2 lines, the code is written to be compatible with 1, 2 or 4 line display modules.

3) The test program outputs two messages, title1 and title2 on the LCD and then flashes an LED on P1.0 (pin-2) at about 2Hz.

4) Note that the supply voltage on the MSP430G2553 is +3.6V while the supply voltage for the LCD is +5V. I will have to source LCDs that run at +3.6V.

In the next post, I will create a "dumb terminal" application that accepts ASCII text via the UART RXD input and displays this on the LCD screen. This is extremely useful for debugging embedded systems.

Blog entry information

Author
MrChips
Views
19,051
Comments
4
Last update

More entries in General

More entries from MrChips

Share this entry

Top