Friday , February 28 2020

Interface LCD with LPC2148 ARM7 Microcontroller

Let’s interface LCD with LPC2148 ARM7 Microcontroller. In most of embedded systems applications, the need for a display is must. We can use display to represent text, numeric data or even graphics. JHD162A is a 16×2 character LCD module which is compatible to HD44780 drivers from Hitachi. The JHD162A has 16 pins and can be interfaced into 4-bit or 8-bit mode. We will get into that in a minute. In this tutorial we will be using 4-bit mode to interface LCD with LPC2148 Microcontroller.

NOTE: Procedure to interface LCD with LPC2148 ARM7 Microcontroller could be little bit different when compared to other 8-bit microcontrollers such as 8051, AVR and other chips which operates at 5V. Usually, LCD operates at 5V but LPC2148 operates at 3.3V. So we have to take care of this fact. Since, the board we will be using for our experiment have on board +5V so we don’t need to use any level shifter circuit. Otherwise, you may need to wire up additional circuitry. We’ll get into that later in circuit diagram.

JHD162A LCD Module: Character LCD Display

The JHD162A has 16 Pins. This LCD controller can be operated in 4-bit or 8-bit mode. You can easily buy this cheap china made LCD in almost every supplier shop. Let’s first try to understand its pins and related functions. I recommend you to keep datasheet in-hand, to download click here: JHD162A LCD Datasheet

JHD162A 16x2 Character LCD
JHD162A 16×2 Character LCD
JHD162A LCD Pins Desciption
JHD162A LCD Pins Desciption

Before wiring up circuit between JHD162A LCD and LPC2148 Microcontroller. Let’s understand function of each pin provided on JHD162A LCD Module and are given as below:

PIN1 (VSS): Ground (GND) Pin of JHD162A LCD Module

PIN2 (VCC): +5V supply should be given to this pin as VCC

PIN3 (VEE): This pin usually used to adjust a contrast. This is usually done by connecting 10K potentiometer to +5V and ground and then connecting slider pin to VEE of LCD Module. This voltage across VEE pin defines the contrast. In general case this voltage is between 0.4V to 0.9V.

PIN4 (RS): This pin referred as Register Select (RS). The JHD126A LCD has two registers called command register & data register. Logic HIGH (‘1’) at Pin RS selects data register and Logic LOW (‘0’) at Pin RS will select command register. When we make RS Pin HIGH and put data on data lines (DB0-DB7). It will be recognized as data. And if we make RS Pin LOW and put any value on data lines, then it will recognizes as a command.

PIN5(R/W): This Pin is used for selecting pin function between read and write mode. Logic HIGH (‘1’) at this pin activates read mode and Logic LOW at this pin activates write mode.

PINs (DB0-DB7): These are data pins. The commands and data can be transferred through these pins in either 8-bit or 4-bit mode.

PIN15 (A or LED+): Anode of the backlight LED. When operated on 5V a 10E resistor should be connected in series to this pin.

PIN16 (K or LED-): Cathode of the backlight LED.

You might be wondering why we are using 4-bit and not 8-bit mode to Interface LCD with LPC2148 ARM7 Microcontroller. Here I have presented some differences. 

It actually depends on requirements, availability of pins and timing requirement etc. etc.

  1. 4-bit mode uses 4 I/O Port Pins for data and two or three additional I/O Pins for control.
  2. 8-bit mode uses 8 I/O Port Pins for data and two or three additional I/O Pins for control.
  3. 4-bit mode requires two 4-bit transfers for each instruction and character that is sent to the display.
  4. 8-bit mode requires only one 8-bit transfer for each instruction and character that is sent to the display.
  5. The implication is that, 4-bit data transfers will take twice as much time to transfer as 8-bit data transfer. 4-bit data transfers use 4 I/O lines less than 8-bit data transfer.
  6. It is a trade off! We save up to 4 I/O lines using 4-bit mode over that of 8-bit mode but, the data transfer takes twice as long in 4-bit mode as it does in 8-bit mode.
  7. If I/O is limited, 4-bit mode might preferred. If I/O is enough in number available and timing is important then 8-bit mode may be the way to go.
  8. 4-bit data transfers also require a bit more code as, the lower nibble will need to be shifted into the upper nibble with each command and character transfer.

As we all aware that almost everything in this field is trade-off! We have to decide on an application by application basis, which is best approach to take.

To establish proper communication and interface between JHD162A LCD with LPC2148 Microcontroller. We need to supply commands in a given order to the data pins with small amount of delay in between to initialize LCD properly. These commands are listed in given table. We’ will use these commands in our program.

COMMAND CODES (JHD162A): Interface LCD to LPC2148 ARM7

*This example project has been tested on STK2148-UltraLite Development Board.EXAMPLE PROJECT: Let’s display custom text on to LCD screen. Here we will interface JHD162A LCD with LPC2148 ARM7 Microcontroller. The connection between LCD pins and LPC2148 into 4-bit mode has shown as below. We also have presented fully functioning program and free to download project.

CIRCUIT CONNECTION: Interface LCD with LPC2148 ARM7

Interface LCD with LPC2148 ARM7
Circuit: Interface LCD with LPC2148 ARM7
JHD162A LCD Command Codes
JHD162A LCD Command Codes

C PROGRAM: Interface LCD with LPC2148 ARM7 Microcontroller

/************************************************************/
/* PROJECT NAME: Interface JHD162A LCD with LPC2148	        */
/* Device:       LPC2148                										*/
/* Filename:     lcd.c                                   		*/
/* Language:     C                      	                	*/
/* Compiler:     Keil ARM				                						*/
/* For more detail visit www.binaryupdates.com		        	*/
/************************************************************/
#include <LPC214x.h>

void LcdInit (void);
void DisplayRow (int row, char *str);
void Send_Command(unsigned char cmd);
void Send_Data(unsigned char dat);
void LcdCmd(unsigned char cmd);
void LcdDat(unsigned char dat);

void SmallDelay(void);
void Delay250(void);
void DelayMs(int n);

int main(void)
{
  LcdInit();	// Initialize LCD
  DisplayRow (1,"    Wel-Come  ");	// Display on 1st row	
  DisplayRow (2,"  BINARYUPDATES  ");	// Display on 2nd row

  while(1)
  {
  }
}

void LcdInit(void)
{
  IO1DIR = 0x03000000;		// Configure P1.24(EN) and P1.25(RS) as Output
  IO1CLR = 0x03000000;		// CLEAR(0) P1.24(EN) and P1.25(RS)

  IO0DIR = 0x40428000;		// Configure P0.15(D4), P0.17(D5), P0.22(D6) and P0.30(D7) as Output
  IO0CLR = 0x40428000;		// CLEAR(0) P0.15(D4), P0.17(D5), P0.22(D6) and P0.30(D7)

  DelayMs(6);
  Send_Command(0x03);
  
  DelayMs(6);
  Send_Command(0x03);
  Delay250();

  Send_Command(0x03);
  Delay250();

  Send_Command(0x02);
  Delay250();

  LcdCmd(0x28); //Function Set: 4-bit, 2 Line, 5x7 Dots 
  LcdCmd(0x08); //Display Off, cursor Off
  LcdCmd(0x0c); //Display On, cursor Off
  LcdCmd(0x06); //Entry Mode
}

/* send command on on data lines (D4 to D7) */
void Send_Command(unsigned char cmd)
{
  if (cmd & 0x01)  
    IO0SET = (1<<15);
  else
    IO0CLR = (1<<15);	

  if (cmd & 0x02)	
    IO0SET = (1<<17);
  else
    IO0CLR = (1<<17);
    
  if (cmd & 0x04) 
    IO0SET = (1<<22);
  else
    IO0CLR = (1<<22);	

  if (cmd & 0x08) 
    IO0SET = (1<<30);
  else
    IO0CLR = (1<<30);
    
  IO1CLR = 0x03000000;	// RS is LOW, for Instruction Register and EN is LOW 
  SmallDelay();
  IO1SET = 0x01000000;	// SET(1) EN 
  SmallDelay();
  IO1CLR = 0x01000000;	// CLEAR(0) EN 
  SmallDelay();
}

/* send data on on data lines (D4 to D7) */
void Send_Data(unsigned char dat)
{
  if (dat & 0x01)
    IO0SET = (1<<15);
  else
    IO0CLR = (1<<15);
    
  if (dat & 0x02)
    IO0SET = (1<<17);
  else
    IO0CLR = (1<<17);
    
  if (dat & 0x04)
    IO0SET = (1<<22);
  else
    IO0CLR = (1<<22);

  if (dat & 0x08)
    IO0SET = (1<<30);
  else
    IO0CLR = (1<<30);
    
  IO1SET = 0x02000000;	// SET(1) RS is set HIGH for Data Register 
  SmallDelay() ;	
  IO1CLR = 0x01000000;	// CLEAR(0) EN 
  SmallDelay() ;		
  IO1SET = 0x01000000;	// SET(1) EN 
  SmallDelay() ;
  IO1CLR = 0x01000000;	// CLEAR(0) EN 
  SmallDelay() ;	
}

void LcdCmd(unsigned char cmd)
{
  Send_Command(cmd >> 4);
  Send_Command(cmd);
  Delay250();
  Delay250();
}
void LcdDat(unsigned char dat)
{
  Send_Data(dat >> 4);
  Send_Data(dat);
  Delay250();
  Delay250();
}

void DisplayRow (int row, char *str)
{
/*
  pass pointer to 16 character string
  displayes the message on line1 or line2 of LCD, depending on whether row is 1 or 2.
*/
  int k ;

  if (row == 1)
    LcdCmd(0x80) ;  // Force cursor to beginning of 1st line
  else
    LcdCmd(0xc0) ;  // Force cursor to beginning of 2nd line
  for(k = 0 ; k < 16 ; k ++)
  {
    if (str[k])
      LcdDat(str[k]) ;
    else
      break ;
  }
  while(k < 16)
  {
    LcdDat(' ') ;
    k ++ ;
  }
}

void SmallDelay(void)
{
  int i;
  for(i=0;i<100;i++);	
}

void Delay250(void)
{
  int k,j ;
  j =200 ;
  for(k = 0 ; k < 100 ; k ++)
  {
    j-- ;
  }
}

void DelayMs(int n)
{
  int k ;
  for(k = 0 ; k < n ; k ++)
  {
    Delay250() ;
    Delay250() ;
  }
}

Download Project: Click Here

This is how we can interface LCD with LPC2148 ARM7 Microcontroller to display text message on LCD screen. Since explanation of code is not in the scope of this tutorial, we will soon upload videos for code explanation. We will suggest you to play little bit around code to explore functionality of JHD162A LCD Module. We will use LCD in our future projects while displaying ADC data, Sensor output on LCD display. If you have any questions then feel free to leave a comment.

About Umesh Lokhande

Umesh Lokhande holds a Master degree in Scientific Instrumentation from University of Applied Sciences Jena, Germany. and has previously worked at Orbotech, Alere Technologies etc. Umesh is also a founder and first author of BINARYUPDATES.COM

Login

Register | Lost your password?