How to interface 16x2 character LCD with 8051 microcontroller

Introduction

The most commonly used Character based LCDs are based on Hitachi's HD44780 controller or other which are compatible with HD44580. In this tutorial, we will discuss about character based LCDs, their interfacing with various microcontrollers, various interfaces (8-bit/4-bit), programming, special stuff and tricks you can do with these simple looking LCDs which can give a new look to your application.

Pin Description
The most commonly used LCDs found in the market today are 1 Line, 2 Line or 4 Line LCDs which have only 1 controller and support at most of 80 charachers, whereas LCDs supporting more than 80 characters make use of 2 HD44780 controllers.

Most LCDs with 1 controller has 14 Pins and LCDs with 2 controller has 16 Pins (two pins are extra in both for back-light LED connections). Pin description is shown in the table below.


Figure 1: Character LCD type HD44780 Pin diagram


Pin No.NameDescription
1VSSPower supply (GND)
2VCCPower supply (+5V)
3VEEContrast adjust
4RS0 = Instruction input
1 = Data input
5R/W0 = Write to LCD module
1 = Read from LCD module
6ENEnable signal
7D0Data bus line 0 (LSB)
8D1Data bus line 1
9D2Data bus line 2
10D3Data bus line 3
11D4Data bus line 4
12D5Data bus line 5
13D6Data bus line 6
14D7Data bus line 7 (MSB)
Table 1: Character LCD pins with 1 Controller
Pin No.NameDescription
1D7Data bus line 7 (MSB)
2D6Data bus line 6
3D5Data bus line 5
4D4Data bus line 4
5D3Data bus line 3
6D2Data bus line 2
7D1Data bus line 1
8D0Data bus line 0 (LSB)
9EN1Enable signal for row 0 and 1 (1stcontroller)
10R/W0 = Write to LCD module
1 = Read from LCD module
11RS0 = Instruction input
1 = Data input
12VEEContrast adjust
13VSSPower supply (GND)
14VCCPower supply (+5V)
15EN2Enable signal for row 2 and 3 (2ndcontroller)
16NCNot Connected
Table 2: Character LCD pins with 2 Controller
Usually these days you will find single controller LCD modules are used more in the market. So in the tutorial we will discuss more about the single controller LCD, the operation and everything else is same for the double controller too. Lets take a look at the basic information which is there in every LCD.


DDRAM - Display Data RAM

Display data RAM (DDRAM) stores display data represented in 8-bit character codes. Its extended capacity is 80 X 8 bits, or 80 characters. The area in display data RAM (DDRAM) that is not used for display can be used as general data RAM. So whatever you send on the DDRAM is actually displayed on the LCD. For LCDs like 1x16, only 16 characters are visible, so whatever you write after 16 chars is written in DDRAM but is not visible to the user.



CGROM - Character Generator ROM

Now you might be thinking that when you send an ascii value to DDRAM, how the character is displayed on LCD? so the answer is CGROM. The character generator ROM generates 5 x 8 dot or 5 x 10 dot character patterns from 8-bit character codes (see Figure 5 and Figure 6 for more details). It can generate 208 5 x 8 dot character patterns and 32 5 x 10 dot character patterns. Userdefined character patterns are also available by mask-programmed ROM.


As you can see in both the code maps, the character code from 0x00 to 0x07 is occupied by the CGRAM characters or the user defined characters. If user want to display the fourth custom character then the code to display it is 0x03 i.e. when user send 0x03 code to the LCD DDRAM then the fourth user created charater or patteren will be displayed on the LCD.

CGRAM - Character Generator RAM

As clear from the name, CGRAM area is used to create custom characters in LCD. In the character generator RAM, the user can rewrite character patterns by program. For 5 x 8 dots, eight character patterns can be written, and for 5 x 10 dots, four character patterns can be written. Later in this tutorial i will explain how to use CGRAM area to make custom character and also making animations to give nice effects to your application.

BF - Busy Flag

Busy Flag is an status indicator flag for LCD. When we send a command or data to the LCD for processing, this flag is set (i.e BF =1) and as soon as the instruction is executed successfully this flag is cleared (BF = 0). This is helpful in producing and exact ammount of delay. for the LCD processing.

To read Busy Flag, the condition RS = 0 and R/W = 1 must be met and The MSB of the LCD data bus (D7) act as busy flag. When BF = 1 means LCD is busy and will not accept next command or data and BF = 0 means LCD is ready for the next command or data to process.

Instruction Register (IR) and Data Register (DR)

There are two 8-bit registers in HD44780 controller Instruction and Data register. Instruction register corresponds to the register where you send commands to LCD e.g LCD shift command, LCD clear, LCD address etc. and Data register is used for storing data which is to be displayed on LCD. when send the enable signal of the LCD is asserted, the data on the pins is latched in to the data register and data is then moved automatically to the DDRAM and hence is displayed on the LCD.
Data Register is not only used for sending data to DDRAM but also for CGRAM, the address where you want to send the data, is decided by the instruction you send to LCD. We will discuss more on LCD instuction set further in this tutorial.


Commands and Instruction set

Only the instruction register (IR) and the data register (DR) of the LCD can be controlled by the MCU. Before starting the internal operation of the LCD, control information is temporarily stored into these registers to allow interfacing with various MCUs, which operate at different speeds, or various peripheral control devices. The internal operation of the LCD is determined by signals sent from the MCU. These signals, which include register selection signal (RS), read/write signal (R/W), and the data bus (DB0 to DB7), make up the LCD instructions (Table 3). There are four categories of instructions that: 


  • Designate LCD functions, such as display format, data length, etc.
  • Set internal RAM addresses
  • Perform data transfer with internal RAM
  • Perform miscellaneous functions



Table 3: Command and Instruction set for LCD type HD44780


Although looking at the table you can make your own commands and test them. Below is a breif list of useful commands which are used frequently while working on the LCD.


No.InstructionHexDecimal
1Function Set: 8-bit, 1 Line, 5x7 Dots0x3048
2Function Set: 8-bit, 2 Line, 5x7 Dots0x3856
3Function Set: 4-bit, 1 Line, 5x7 Dots0x2032
4Function Set: 4-bit, 2 Line, 5x7 Dots0x2840
5Entry Mode0x066
6Display off Cursor off
(clearing display without clearing DDRAM content)
0x088
7Display on Cursor on0x0E14
8Display on Cursor off0x0C12
9Display on Cursor blinking0x0F15
10Shift entire display left0x1824
11Shift entire display right0x1C30
12Move cursor left by one character0x1016
13Move cursor right by one character0x1420
14Clear Display (also clear DDRAM content)0x011
15Set DDRAM address or coursor position on display0x80 + address*128 + address*
16Set CGRAM address or set pointer to CGRAM location0x40 + address**64 + address**
Table 4: Frequently used commands and instructions for LCD
* DDRAM address given in LCD basics section see Figure 2,3,4
** CGRAM address from 0x00 to 0x3F, 0x00 to 0x07 for char1 and so on..

The table above will help you while writing programs for LCD. But after you are done testing with the table 4, i recommend you to use table 3 to get more grip on working with LCD and trying your own commands. In the next section of the tutorial we will see the initialization with some of the coding examples in C as well as assembly.


LCD Initialization

Before using the LCD for display purpose, LCD has to be initialized either by the internal reset circuit or sending set of commands to initialize the LCD. It is the user who has to decide whether an LCD has to be initialized by instructions or by internal reset circuit. 
Initialization by instructions
Initializing LCD with instructions is really simple. Given below is a flowchart that describles the step to follow, to initialize the LCD.

As you can see from the flow chart, the LCD is initialized in the following sequence...

  1. Send command 0x30 - Using 8-bit interface
  2. Delay 20ms
  3. Send command 0x30 - 8-bit interface
  4. Delay 20ms
  5. Send command 0x30 - 8-bit interface
  6. Delay 20ms
  7. Send Function set - see Table 4 for more information
  8. Display Clear command
  9. Set entry mode command - explained below

The first 3 commands are usually not required but are recomended when you are using 4-bit interface. So you can program the LCD starting from step 7 when working with 8-bit interface. Function set command depends on what kind of LCD you are using and what kind of interface you are using (see Table 4 in LCD Command section).
LCD Entry mode:
From Table 3 in command section, you can see that the two bits decide the entry mode for LCD, these bits are:
a) I/D - Increment/Decrement bit
b) S - Display shift.
With these two bits we get four combinations of entry mode which are 0x04,0x05,0x06,0x07 (see table 3 in LCD Command section). So we get different results with these different entry modes. Normally entry mode 0x06 is used which is No shift and auto incremement. I recommend you to try all the possible entry modes and see the results, I am sure you will be surprised.


Sending Commands to LCD

To send commands we simply need to select the command register. Everything is same as we have done in the initialization routine. But we will summarize the common steps and put them in a single subroutine. Following are the steps:
  • Move data to LCD port
  • select command register
  • select write operation
  • send enable signal
  • wait for LCD to process the command

Sending Data to LCD

To send data we simply need to select the data register. Everything is same as the command routine. Following are the steps:
  • Move data to LCD port
  • select data register
  • select write operation
  • send enable signal
  • wait for LCD to process the data

CGRAM and Character Building

As already explained, all character based LCD of type HD44780 has CGRAM area to create user defined patterns. For making custom patterns we need to write values to the CGRAM area defining which pixel to glow. These values are to be written in the CGRAM adress starting from 0x40. If you are wondering why it starts from 0x40? Then the answer is given below.

Bit 7 is 0 and Bit 6 is 1, due to which the CGRAM adress command starts from 0x40, where the address of CGRAM (Acg) starts from 0x00. CGRAM has a total of 64 Bytes. When you are using LCD as 5x8 dots in function set then you can define a total of 8 user defined patterns (1 Byte for each row and 8 rows for each pattern), where as when LCD is working in 5x10 dots, you can define 4 user defined patterns.

Lets take an of bulding a custom pattern. All we have to do is make a pixel-map of 7x5 and get the hex or decimal value or hex value for each row, bit value is 1 if pixel is glowing and bit value is 0 if pixel is off. The final 7 values are loaded to the CGRAM one by one. As i said there are 8 rows for each pattern, so last row is usually left blank (0x00) for the cursor. If you are not using cursor then you can make use of that 8th row also. so you get a bigger pattern.


To explain the above explaination in a better way. I am going to take an example. Lets make a "Bell" pattern as shown below.


Now we get the values for each row as shown.


  1. Bit: 4 3 2 1 0 - Hex

  2. Row1: 0 0 1 0 0 - 0x04

  3. Row2: 0 1 1 1 0 - 0x0E

  4. Row3: 0 1 1 1 0 - 0x0E

  5. Row4: 0 1 1 1 0 - 0x0E

  6. Row5: 1 1 1 1 1 - 0x1F

  7. Row6: 0 0 0 0 0 - 0x00

  8. Row7: 0 0 1 0 0 - 0x04

  9. Row8: 0 0 0 0 0 - 0x00



We are not using row 8 as in our pattern it is not required. if you are using cursor then it is recommended not to use the 8th row. Now as we have got the values. We just need to put these values in the CGRAM. You can decided which place you want to store in. Following is the memory map for custom patterns in CGRAM.

Memory Map
Pattern No.CGRAM Address (Acg)
10x00 - 0x07
20x08 - 0x0F
30x10 - 0x17
40x18 - 0x1F
50x20 - 0x27
60x28 - 0x2F
70x30 - 0x37
80x38 - 0x3F




Displaying single character ‘A’ on LCD

The LCD is interfaced with microcontroller (AT89C51). This microcontroller has 40 pins with four 8-bit ports (P0, P1, P2, and P3). Here P1 is used as output port which is connected to data pins of the LCD. The control pins (pin 4-6) are controlled by pins 2-4 of P0 port. Pin 3 is connected to a preset of 10k? to adjust the contrast on LCD screen. This program uses the above concepts of interfacing the LCD with controller by displaying the character ‘A’ on it.

CIRCUIT DIAGRAM


 CODE


//Program to test LCD. Display single character "A"



#include<reg51.h>
#define cmdport P3
#define dataport P2
#define q 100
sbit rs = cmdport^0;  //register select pin
sbit rw = cmdport^1;  // read write pin
sbit e = cmdport^6;  //enable pin

void delay(unsigned int msec)  // Function to provide time delay in msec.
{
int i,j ;
for(i=0;i<msec;i++)
for(j=0;j<1275;j++);
}

void lcdcmd(unsigned char item)  //Function to send command to LCD
{
dataport = item;
rs= 0;
rw=0;
e=1;
delay(1);
e=0;
}

void lcddata(unsigned char item)  //Function to send data to LCD
{
dataport = item;
rs= 1;
rw=0;
e=1;
delay(1);
e=0;
}

void main()
{
lcdcmd(0x38);  // for using 8-bit 2 row mode of LCD
delay(100);
lcdcmd(0x0E);  // turn display ON for cursor blinking
delay(100);
lcdcmd(0x01);  //clear screen
delay(100);
lcdcmd(0x06);  //display ON
delay(100);
lcdcmd(0x86);  // bring cursor to position 6 of line 1
delay(100);
lcddata('A');
}

projectbandya

No comments:

Post a Comment