(65 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
[[category: LPC1768 Tutorials]]
 
[[category: LPC1768 Tutorials]]
 
 
=Objective=
 
 
In this tutorial we are going to see how to interface a 2x16 LCD with LPC1768 in 4-bit mode.
 
In this tutorial we are going to see how to interface a 2x16 LCD with LPC1768 in 4-bit mode.
 
As per the name the 2x16 has 2 lines with 16 chars on each lines. It supports all the ascii chars and is basically used for displaying the alpha numeric characters. Here each character is displayed in a matrix of 5x7 pixels.
 
As per the name the 2x16 has 2 lines with 16 chars on each lines. It supports all the ascii chars and is basically used for displaying the alpha numeric characters. Here each character is displayed in a matrix of 5x7 pixels.
Line 11: Line 8:
  
 
=LCD UNIT=
 
=LCD UNIT=
{{Box|type=l_green_light|text=
 
 
 
Let us look at a pin diagram of a commercially available LCD like '''JHD162''' which uses a '''HD44780''' controller and then describe its operation.
 
Let us look at a pin diagram of a commercially available LCD like '''JHD162''' which uses a '''HD44780''' controller and then describe its operation.
  
[[File:PIN_Diagram.PNG]]  
+
[[FILE:Pic16f877aLcdInterface.png]]
 
+
All the pins are identically to the lcd internal controller discussed above
+
 
+
}}
+
  
{|class="wikitable "  
+
{| class="table table-striped table-hover table-condensed table-bordered"
 +
|-class="info"
 +
| Pin Number || Symbol || Pin Function
 
|-
 
|-
! PIN NUMBER !! FUNCTION
+
|1 || VSS ||Ground
 
|-
 
|-
|1 || Ground
+
| 2|| VCC || +5v
 
|-
 
|-
| 2|| VCC
+
| 3 || VEE || Contrast adjustment (VO)
 
|-
 
|-
| 3 || Contrast adjustment (VO)
+
| 4 || RS || Register Select. 0:Command, 1: Data
 
|-
 
|-
| 4 || Register Select (RS). RS=0: Command, RS=1: Data
+
| 5 || R/W || Read/Write, R/W=0: Write & R/W=1: Read
 
|-
 
|-
| 5 || Read/Write (R/W). R/W=0: Write, R/W=1: Read
+
| 6|| EN || Enable. Falling edge triggered
 
|-
 
|-
| 6|| Clock (Enable). Falling edge triggered
+
| 7 || D0 || Data Bit 0 (Not used in 4-bit operation)
 +
|-       
 +
| 8 || D1 || Data Bit 1 (Not used in 4-bit operation)
 +
|-       
 +
| 9 || D2 || Data Bit 2 (Not used in 4-bit operation)
 
|-
 
|-
| 7 || Bit 0 (Not used in 4-bit operation)
+
| 10 || D3 || Data Bit 3 (Not used in 4-bit operation)  
 
|-
 
|-
| 8 || Bit 1 (Not used in 4-bit operation)
+
| 11 || D4 || Data Bit 4
 +
|-        
 +
| 12 || D5 || Data Bit 5
 +
|-         
 +
| 13 || D6 || Data Bit 6
 +
|-         
 +
| 14 || D7 || Data Bit 7/Busy Flag
 
|-
 
|-
| 9 || Bit 2 (Not used in 4-bit operation)
+
| 15 || A/LED+ || Back-light Anode(+)
 
|-
 
|-
| 10 || Bit 3 (Not used in 4-bit operation)
+
| 16 || K/LED- || Back-Light Cathode(-)  
|-
+
| 11 || Bit 4
+
|-
+
| 12 || Bit 5
+
|-
+
| 13 || Bit 6
+
|-
+
|  14|| Bit 7
+
|-
+
|  15|| Back-light Anode(+)
+
|-
+
| 16 || Back-Light Cathode(-)  
+
 
|}
 
|}
<br/>
+
<br><br>
<br/>
+
<br/>
+
<br/>
+
  
 
Apart from the voltage supply connections the important pins from the programming perspective are the data lines(8-bit Data bus), Register select, Read/Write and Enable pin.<br><br>   
 
Apart from the voltage supply connections the important pins from the programming perspective are the data lines(8-bit Data bus), Register select, Read/Write and Enable pin.<br><br>   
Line 73: Line 61:
 
<b>Enable(EN):</b> This pin is used to send the enable trigger to LCD.
 
<b>Enable(EN):</b> This pin is used to send the enable trigger to LCD.
 
After sending the data/cmd, Selecting the data/cmd register, Selecting the Write operation. A HIGH-to-LOW pulse has to be send on this enable pin which will latch the info into the LCD register and triggers the LCD to act accordingly.
 
After sending the data/cmd, Selecting the data/cmd register, Selecting the Write operation. A HIGH-to-LOW pulse has to be send on this enable pin which will latch the info into the LCD register and triggers the LCD to act accordingly.
 +
<br/>
 +
<br/>
  
 +
=Hardware Connections=
 +
[[File:LCD 4Bit.jpg|680px]]
 
=Schematic=
 
=Schematic=
 +
Below schematic shows the minimum connection required for interfacing the LCD with the microcontroller.<br>
 +
As we are interfacing the LCD in 4-bit mode, only the higher 4 data lines are used as data bus.
  
 +
<html>
 +
<img src=https://www.exploreembedded.com/wiki/images/b/b8/LPC1768_4bit_LCD.PNG class="img-responsive">
 +
</html>
 +
  
 
+
<br/>
 +
<br/>
  
 
=Port Connection=
 
=Port Connection=
 
This section shows how to configure the GPIO for interfacing the LCD.<br>
 
This section shows how to configure the GPIO for interfacing the LCD.<br>
 
The below configuration is as per the above schematic. You can connect the LCD to any of the PORT pins available on your boards and update this section accordingly
 
The below configuration is as per the above schematic. You can connect the LCD to any of the PORT pins available on your boards and update this section accordingly
 +
<html>
 +
<script src="https://gist.github.com/Amritach/dfd031e49d0335167eb8.js"></script>
 +
</html>
 +
<br/>
 +
<br/>
  
<syntaxhighlight>
+
=LCD Operation=
/* Configure the data bus and Control bus as per the hardware connection */
+
In this section we are going to see how to send the data/cmd to the LCD along with the timing diagrams.
 +
First lets see the timing diagram for sending the data and the command signals(RS,RW,EN), accordingly we write the algorithm and finally the code.
  
#define LcdDataBusPort      LPC_GPIO1->FIOPIN
+
===Timing Diagram===
#define LcdControlBusPort  LPC_GPIO2->FIOPIN
+
The below image shows the timing diagram for sending the data to the LCD.<br>
 +
As shown in the timing diagram  the data is written after sending the RS and RW signals. It is still ok to send the data before these signals.<br>
 +
The only important thing is the data should be available on the databus before generating the High-to-Low pulse on EN pin.
 +
[[File:LCD CmdWrite.jpg|figure: command write]]
 +
<br><br>
  
#define LcdDataBusDirnReg    LPC_GPIO1->FIODIR
 
#define LcdCtrlBusDirnReg      LPC_GPIO2->FIODIR
 
  
#define LCD_D4    24
+
===Steps for Sending Command:===
#define LCD_D5    25
+
# Send the I/P command to LCD.
#define LCD_D6    26
+
# Select the Control Register by making RS low.
#define LCD_D7    27
+
#Select Write operation making RW low.
 +
#Send a High-to-Low pulse on Enable PIN with some delay_us.
 +
<html>
 +
<script src="https://gist.github.com/Amritach/6e4b08f06568b82fcd64.js"></script>
 +
</html>
 +
<br><br>
  
#define LCD_RS    0
+
===Steps for Sending Data:===
#define LCD_RW    1
+
# Send the character to LCD.
#define LCD_EN    2
+
# Select the Data Register by making RS high.
</syntaxhighlight>
+
# Select Write operation making RW low.
 +
# Send a High-to-Low pulse on Enable PIN with some delay_us.
 +
The timings are similar as above only change is that '''RS''' is made high for selecting Data register.
  
=Interfacing LCD with 8051=
+
<html>
{{Box|type=l_green_light|text=
+
<script src="https://gist.github.com/Amritach/6a137d1bf6a27cefb8de.js"></script>
LCD can be interfaced with the 8051 micrcontroller in two modes, 8 bit and 4 bit.
+
</html>
Let us Interface it in 8 bit mode first.
+
<br><br>
}}
+
==8 bit Mode==
+
{{Box|type=l_green_light|text=<br />
+
===Objective===
+
[[File:LCD_output.PNG|thumbnail|fig LCD display ]]
+
There is lot of stuff that can be done with the LCDs, to start with we will simple display a couple of strings on the 2 lines of the LCD as shown in the image.
+
===Schematic Discription===
+
*'''Data  Lines:''' In this mode, all of the 8 datalines DB0 to DB7 are connected from the micrcontroller to a LCD module as shown the schematic.
+
*'''Control Lines:'''' The RS, RW and E are control lines, as discussed earlier.
+
*'''Power & contrast''':Apart from that the LCD should be powered with 5V between '''PIN 2(VCC)''' and  '''PIN 1(gnd)'''. '''PIN 3''' is the contrast pin and is output of center terminal of potentiometer(voltage divider) which varies voltage between 0 to 5v to vary the contrast.
+
*'''Back-light:''' The PIN 15 and 16 are used as backlight. The led backlight can be powered through a simple current limiting resistor as we do with normal leds.
+
}}
+
  
===Schematic===
+
= Code Examples =
[[File:8051 LCD8BIT Interface.PNG|Fig 3: Schematic LCD 8 bit mode]]
+
===Example 1===
 +
Here is the complete code for displaying the data on 2x16 LCD in 4-bit mode.
 +
<html>
 +
<script src="https://gist.github.com/SaheblalBagwan/96e2caabd9824981c464e68d3a11aa8b.js"></script>
 +
</html>
  
 
+
===Using Explore Embedded Libraries :===
{{Box|type=l_green_light|text=<br />
+
In the above tutorial we just discussed how to interface 2x16Lcd in 4-bit mode.<br>
===Code===
+
Once you know the working of lcd, you can directly use the ExploreEmbedded libraries to play around with your LCD.<br>
As with all the interfaces to simplify thing we have separated code into two files, main.c  and  lcd_8_bit.c. You may go through the [[8051 ToolsSetup|tools setup]] tutorial on configuring the code.
+
For that you need to include the lcd.c/lcd.h and the associated files(delay/stdutils).<br>  
 
+
After including these files, the only thing you got to do is to configure the PORTs in lcd.h as per your hardware connection.<br>
The main.c is very simple it includes the standard library files.
+
The below sample code shows how to use the already available LCD functions.<br>
Then it uses several functions from the lcd_8_bit.c file to set up and display messages. As you can see, it makes things very simple when the libraries are well written. We will discuss the implementation while discussing the lcd_8_bit.c file.
+
Refer this link for more info on LCD libraries.
}}
+
<html>
=Timing Diagram=
+
<script src="https://gist.github.com/Amritach/d5b38e3fc891c74a1032.js"></script>
<br>The above image shows the timing diagram for sending the data to the LCD.<br>
+
</html>
[[File:LCD CmdWrite.jpg|figure: command write]]<br />
+
<br><br>
 
+
<br ><br >
+
==Steps for Sending Command:== Below are the steps for sending the command
+
*step1: Send the I/P command to LCD.
+
*step2: Select the Control Register by making RS low.
+
*step3: Select Write operation making RW low.
+
*step4: Send a High-to-Low pulse on Enable PIN with some delay_us.
+
 
+
==Code snippet:==
+
<syntaxhighlight>
+
/* Function to send the command to LCD. As it is 4bit mode, a byte of data is sent in two 4-bit nibbles */
+
void Lcd_CmdWrite(char cmd)
+
{
+
    sendNibble((cmd >> 0x04) & 0x0F);  //Send higher nibble
+
    LcdControlBusPort &= ~(1<<LCD_RS); // Send LOW pulse on RS pin for selecting Command register
+
    LcdControlBusPort &= ~(1<<LCD_RW); // Send LOW pulse on RW pin for Write operation
+
    LcdControlBusPort |= (1<<LCD_EN);  // Generate a High-to-low pulse on EN pin
+
    delay(1000);
+
    LcdControlBusPort &= ~(1<<LCD_EN);
+
 
+
    delay(10000);
+
 
+
    sendNibble(cmd & 0x0F);            //Send Lower nibble
+
    LcdControlBusPort &= ~(1<<LCD_RS); // Send LOW pulse on RS pin for selecting Command register
+
    LcdControlBusPort &= ~(1<<LCD_RW); // Send LOW pulse on RW pin for Write operation
+
    LcdControlBusPort |= (1<<LCD_EN);  // Generate a High-to-low pulse on EN pin
+
    delay(1000);
+
    LcdControlBusPort &= ~(1<<LCD_EN);
+
 
+
    delay(10000);
+
}
+
</syntaxhighlight>
+
 
+
 
+
'''2. void LCD_DataWrite( char dat)'''
+
This function sends a character to be displayed on LCD in the following steps.
+
*step1: Send the character to LCD.
+
*step2: Select the Data Register by making RS high.
+
*step3: Select Write operation making RW low.
+
*step4: Send a High-to-Low pulse on Enable PIN with some delay_us.
+
The timings are similar as above only change is that '''RS''' is made high.
+
<syntaxhighlight>
+
void LCD_DataWrite( char dat)
+
{
+
  databus=dat;   // Send the data to LCD
+
    rs=1;   // Select the Data Register by pulling RS HIGH
+
    rw=0;        // Select the Write Operation by pulling RW LOW
+
    en=1;   // Send a High-to-Low Pusle at Enable Pin
+
    delay_us(10);
+
    en=0;
+
  delay_ms(1);
+
}
+
</syntaxhighlight>
+
 
+
'''3. void LCD_Init()'''<br />
+
Looking at the instruction set of the LCD controller, we can initialize the LCD with following steps
+
* Set the display mode as 2 lines, 5 x 7 matrix
+
* Turn On the dislay, and cursor.
+
* Clear the LCD
+
* Get the cursor to first line first position.
+
The code is listed below.
+
 
+
<syntaxhighlight>
+
void LCD_Init()
+
{
+
  delay_us(5000);
+
  LCD_CmdWrite(0x38);  // LCD 2lines, 5*7 matrix
+
  LCD_CmdWrite(0x0E); // Display ON cursor ON  Blinking off
+
  LCD_CmdWrite(0x01); // Clear the LCD
+
  LCD_CmdWrite(0x80); // Cursor to First line First Position
+
}
+
</syntaxhighlight>
+
The remaining code is listed below. You could observe that the basic functions to read data and write write command are used extensively and entire library is built upon them. There are also other functions that are used to display number etc in the lcd library file. The entire listing can be found [[8051_Family_C_Library#LCD_16x2_8_bit_mode|here]].
+
}}
+
 
+
{{scroll box|width=700px|height=500px|text=<br />
+
<syntaxhighlight>
+
#include<reg51.h>
+
#include "delay.h"
+
#include "lcd.h"
+
 
+
#define databus P2  // LCD databus connected to PORT2
+
 
+
sbit rs= P0^0; // Register select pin connected to P0.0
+
sbit rw= P0^1; // Read Write pin connected to P0.1
+
sbit en= P0^2; // Enable pin connected to P0.2
+
 
+
 
+
/* 16x2 LCD Specification */
+
#define LCDMaxLines 2
+
#define LCDMaxChars 16
+
#define LineOne 0x80
+
#define LineTwo 0xc0
+
 
+
#define BlankSpace ' '
+
 
+
 
+
void LCD_Init()
+
{
+
    delay_us(5000);
+
  LCD_CmdWrite(0x38);  // LCD 2lines, 5*7 matrix
+
  LCD_CmdWrite(0x0E); // Display ON cursor ON  Blinking off
+
  LCD_CmdWrite(0x01); // Clear the LCD
+
  LCD_CmdWrite(0x80); // Cursor to First line First Position
+
}
+
 
+
 
+
void LCD_CmdWrite( char cmd)
+
{
+
    databus=cmd;        // Send the command to LCD
+
    rs=0;            // Select Command Register by pulling RS LOW
+
    rw=0;            // Select Write Operation  by pulling RW LOW
+
    en=1;            // Send a High-to-Low Pusle at Enable Pin
+
    delay_us(10);
+
    en=0;
+
    delay_ms(1);
+
}
+
 
+
 
+
void LCD_DataWrite( char dat)
+
{
+
 
+
  databus=dat;   // Send the data to LCD
+
    rs=1;    // Select the Data Register by pulling RS HIGH
+
    rw=0;  // Select the Write Operation  by pulling RW LOW
+
    en=1; // Send a High-to-Low Pusle at Enable Pin
+
    delay_us(10);
+
    en=0;
+
    delay_ms(1);
+
}
+
 
+
void LCD_GoToXY(char row, char col)
+
{
+
  char pos;
+
 
+
    if(row<LCDMaxLines)
+
      {
+
pos= LineOne | (row << 6); // take the line number
+
                  //row0->pos=0x80  row1->pos=0xc0
+
 
+
if(col<LCDMaxChars)
+
            pos= pos+col;      //take the char number
+
              //now pos points to  XY pos
+
 
+
  LCD_CmdWrite(pos)
+
      }
+
}
+
 
+
 
+
void LCD_DisplayString(char *string_ptr)
+
{
+
  while(*string_ptr)
+
    LCD_DataWrite(*string_ptr++);
+
}
+
</syntaxhighlight>
+
}}
+
  
 
= Downloads=
 
= Downloads=
{{Box|type=l_green_light|text="The code is given for 4 and 8 bit modes with and without busy Flag"}}
+
Download the complete project folder from the below link:
[http://exploreembedded.com/wiki/images/0/02/8051_LCD_Tutorial_Code.zip '''Code''']
+
https://codeload.github.com/ExploreEmbedded/Explore-Cortex-M3-LPC1768-Stick-DVB-14001/zip/master<br>
 
+
 
+
[[File:SwitchesLEDs.jpg|left|thumbnail|x120px|{{Box|type=l_blue_light|text=Switches and LED Interfacing with 8051 }}|link=8051_Interfacing_swithes_leds|'''''PREVIOUS TUTORIAL''''']]
+
[[File:8051_Timers_Poster.jpg|right|thumbnail|x150px|link=8051_timers|'''''NEXT TUTORIAL''''']]
+
  
{{#widget:Facebook_Like_Box|profile=https://www.facebook.com/ExploreEmbedded}}
 
  
 
Have a opinion, suggestion , question or feedback about the article let it out here!
 
Have a opinion, suggestion , question or feedback about the article let it out here!
 
{{DISQUS}}
 
{{DISQUS}}

Latest revision as of 14:05, 5 May 2016

In this tutorial we are going to see how to interface a 2x16 LCD with LPC1768 in 4-bit mode. As per the name the 2x16 has 2 lines with 16 chars on each lines. It supports all the ascii chars and is basically used for displaying the alpha numeric characters. Here each character is displayed in a matrix of 5x7 pixels. Apart from alpha numeric chars it also provides the provision to display the custom characters by creating the pattern. Scope of this tutorial is to show how to display the alpha numeric chars on LCD, Generating and displaying the custom chars will be discussed in subsequent tutorials.


LCD UNIT

Let us look at a pin diagram of a commercially available LCD like JHD162 which uses a HD44780 controller and then describe its operation.

Pic16f877aLcdInterface.png

Pin Number Symbol Pin Function
1 VSS Ground
2 VCC +5v
3 VEE Contrast adjustment (VO)
4 RS Register Select. 0:Command, 1: Data
5 R/W Read/Write, R/W=0: Write & R/W=1: Read
6 EN Enable. Falling edge triggered
7 D0 Data Bit 0 (Not used in 4-bit operation)
8 D1 Data Bit 1 (Not used in 4-bit operation)
9 D2 Data Bit 2 (Not used in 4-bit operation)
10 D3 Data Bit 3 (Not used in 4-bit operation)
11 D4 Data Bit 4
12 D5 Data Bit 5
13 D6 Data Bit 6
14 D7 Data Bit 7/Busy Flag
15 A/LED+ Back-light Anode(+)
16 K/LED- Back-Light Cathode(-)



Apart from the voltage supply connections the important pins from the programming perspective are the data lines(8-bit Data bus), Register select, Read/Write and Enable pin.

Data Bus: As shown in the above figure and table, an alpha numeric lcd has a 8-bit data bus referenced as D0-D7. As it is a 8-bit data bus, we can send the data/cmd to LCD in bytes. It also provides the provision to send the the data/cmd in chunks of 4-bit, which is used when there are limited number of GPIO lines on the microcontroller.

Register Select(RS): The LCD has two register namely a Data register and Command register. Any data that needs to be displayed on the LCD has to be written to the data register of LCD. Command can be issued to LCD by writing it to Command register of LCD. This signal is used to differentiate the data/cmd received by the LCD.
If the RS signal is LOW then the LCD interprets the 8-bit info as Command and writes it Command register and performs the action as per the command.
If the RS signal is HIGH then the LCD interprets the 8-bit info as data and copies it to data register. After that the LCD decodes the data for generating the 5x7 pattern and finally displays on the LCD.

Read/Write(RW): This signal is used to write the data/cmd to LCD and reads the busy flag of LCD. For write operation the RW should be LOW and for read operation the R/W should be HIGH.

Enable(EN): This pin is used to send the enable trigger to LCD. After sending the data/cmd, Selecting the data/cmd register, Selecting the Write operation. A HIGH-to-LOW pulse has to be send on this enable pin which will latch the info into the LCD register and triggers the LCD to act accordingly.

Hardware Connections

LCD 4Bit.jpg

Schematic

Below schematic shows the minimum connection required for interfacing the LCD with the microcontroller.
As we are interfacing the LCD in 4-bit mode, only the higher 4 data lines are used as data bus.




Port Connection

This section shows how to configure the GPIO for interfacing the LCD.
The below configuration is as per the above schematic. You can connect the LCD to any of the PORT pins available on your boards and update this section accordingly

LCD Operation

In this section we are going to see how to send the data/cmd to the LCD along with the timing diagrams. First lets see the timing diagram for sending the data and the command signals(RS,RW,EN), accordingly we write the algorithm and finally the code.

Timing Diagram

The below image shows the timing diagram for sending the data to the LCD.
As shown in the timing diagram the data is written after sending the RS and RW signals. It is still ok to send the data before these signals.
The only important thing is the data should be available on the databus before generating the High-to-Low pulse on EN pin. figure: command write


Steps for Sending Command:

  1. Send the I/P command to LCD.
  2. Select the Control Register by making RS low.
  3. Select Write operation making RW low.
  4. Send a High-to-Low pulse on Enable PIN with some delay_us.



Steps for Sending Data:

  1. Send the character to LCD.
  2. Select the Data Register by making RS high.
  3. Select Write operation making RW low.
  4. Send a High-to-Low pulse on Enable PIN with some delay_us.

The timings are similar as above only change is that RS is made high for selecting Data register.



Code Examples

Example 1

Here is the complete code for displaying the data on 2x16 LCD in 4-bit mode.

Using Explore Embedded Libraries :

In the above tutorial we just discussed how to interface 2x16Lcd in 4-bit mode.
Once you know the working of lcd, you can directly use the ExploreEmbedded libraries to play around with your LCD.
For that you need to include the lcd.c/lcd.h and the associated files(delay/stdutils).
After including these files, the only thing you got to do is to configure the PORTs in lcd.h as per your hardware connection.
The below sample code shows how to use the already available LCD functions.
Refer this link for more info on LCD libraries.

Downloads

Download the complete project folder from the below link: https://codeload.github.com/ExploreEmbedded/Explore-Cortex-M3-LPC1768-Stick-DVB-14001/zip/master


Have a opinion, suggestion , question or feedback about the article let it out here!