You are on page 1of 22

TUTORIAL ON INTERFACING LCD

EMBEDDED SYSTEMS SPRING 2009

This tutorial explains how to interface Liquid Crystal Display (LCD) to LPC2148. The interfacing of LCD is explained using HD44780U as the Dot Matrix Liquid Crystal Display Controller/Driver. HD44780U is a programmable chip for various LCD display control functions. It drives the dot-matrix liquid crystal display. It can be configured under the control of a microprocessor. In our example, we will connect the LCD controller to the LPC2148 microcontroller. We will use the GPIO pins of LPC2148 for the purpose of connecting the LCD controller. We will then write a program to output some specific values to the GPIO pins (what values to write we will discuss about them shortly). This program will be executed in the ARM processor of the LPC2148 microcontroller. The LCD controller, on receiving the bits sent over the GPIO pins, will display characters on the LCD and perform other control functions. So what are the specific values that should be output to the GPIO pins? This is what we will learn in the next few sections. Pins in the LCD Controller Among the pins available in a LCD controller, the following are being used for the purpose of interfacing. Their explanation follows.

1. DB0 to DB7 the data bus pins. These signals can be used to send 8 bits of data from the microcontroller to the LCD controller or from the LCD controller to the microcontroller. DB7 can be used a busy flag also. More about Bust flag later. 2. The R/W signal selects between a Read and a Write operation. If R/W is equal to 0, a Write operation will be performed. For a Write operation, DB0 to DB7 will be used to send data from the microcontroller to the LCD controller. If R/W is equal to 1, a Read operation will be performed. For a Read operation, DB0 to DB7 will be used to send data from the LCD controller to the microcontroller. 3. Two of the registers available in the LCD controller are the Instruction Register and the Data Register. More about how these registers are used later. The RS signal selects between these two registers. RS equal to 0 selects the Instruction register for a Write operation. This means that if RS=0 and R/W=0, the data sent over DB0 to DB7 will be put in the Instruction register. RS equal to 0 selects the Busy Flag for Read operation. This means that if RS=0 and R/W=1, the value in the Busy Flag will be sent over DB7. RS equal to 1 selects the Data register for Read and Write operation. This means that if RS=1 and R/W=0, the data sent over DB0 to DB7 will be put in the Data register. If RS=1 and R/W=1, the value in the Data register will be sent over DB0 to DB7. 4. The E signal is used to start data read or write. When the data is sent to the data pins of the LCD, a high to low pulse must be applied to the E signal so that the LCD latches the data present at its pins. Similarly a high to low pulse must be provided to the E signal during a Read operation.

LCD Controller Commands The table below shows all the commands that can be sent to the LCD controller. The table also lists the amount of time it takes to execute each command. The * symbol in the table means either a 0 or a 1 can be put at that position. Name RS R/W Clear Display 0 0 Return Home 0 0 Entry Mode 0 0 Set Display On/Off 0 0 Control Cursor or 0 0 Display Shift Function Set 0 0 Set CGRAM 0 0 Address Set DDRAM 0 0 Address Read Busy Flag and 0 1 Address Write data to CG or 1 0 DDRAM Read data from CG or 1 1 DDRAM DB7 0 0 0 0 0 0 0 1 BF DB6 0 0 0 0 0 0 1 A AC DB5 0 0 0 0 0 1 A A AC DB4 0 0 0 0 1 DL A A AC DB3 0 0 0 1 S/C N A A AC DB2 0 0 1 D R/L F A A AC DB1 0 1 I/D C * * A A AC DB0 1 * S B * * A A AC Time 1.60 ms 1.60 ms 40 sec 40 sec 40 sec 40 sec 40 sec 40 sec 0 sec 40 sec 40 sec

Each of the command is explained in details below. The LCD kits that we have do not use the R/W signal. Thus it do not support the Read operation. It supports only the Write operation. For this reason the R/W signal is not shown in the explanation below. Also the Read Busy Flag and Address and the Read Data from CG or DDRAM are not being explained as they are Read commands. Clear Display RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 0 DB1 0 DB0 1

The Clear Display command clears the entire display and sets DDRAM address 0 in the address counter. The LCD controller takes 1.60 milliseconds to execute this command.

Return Home RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 0 DB1 1 DB0 *

The command sets DDRAM address 0 in the address counter. It returns the display to the original position if it was shifted. The DDRAM contents do not change. The LCD controller takes 1.60 milliseconds to execute this command. Entry Mode Set RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 1 DB1 I/D DB0 S

This instruction sets the cursor move direction and specifies display shift. If I/D is equal to 1, the DDRAM address will be incremented by 1 when a character code is written to or read from DDRAM. If I/D is equal to 0, the DDRAM address will be decremented by 1 when a character code is written to or read from DDRAM. If S ie equal to 0, the display do not shift on a write to the DDRAM. If S is equal to 1, the display shift either to the right (if I/D = 0) or to the left (if I/D = 1) after a write to DDRAM. This command takes about 40 microseconds to execute. Display On/Off Control RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 1 DB2 D DB1 C DB0 B

This command sets entire display on or off, cursor on or off, and blinking of the cursor position character. The display is on when D is 1 and off when D is 0. When off, the display data remains in DDRAM and can be instantly displayed by setting D to 1. The cursor is displayed when C is 1 and not displayed when C is 0. The character indicated by the cursor blinks when B is equal to 1. This command takes about 40 microseconds to execute.

Cursor or Display Shift RS 0 DB7 0 DB6 0 DB5 0 DB4 1 DB3 S/C DB2 R/L DB1 * DB0 *

This command moves cursor and shifts display without changing DDRAM contents. If S/C is equal to 1, the display shifts. If S/C is equal to 0, the cursor moves. R/L bit controls the direction of move. If R/L is equal to 1, the shift happens to the right direction. If R/L is equal to 0, the shift happens to the left direction. This command takes about 40 microseconds to execute. Function Set RS 0 DB7 0 DB6 0 DB5 1 DB4 DL DB3 N DB2 F DB1 * DB0 *

This instruction sets the interface data length, the number of display lines, and the character font. If DL is equal to 1, the interface data length is 8 bits. If DL is equal to 0, the interface data length is 4 bits. If N is equal to 1, the number of lines is equal to 2. If N is equal to 0, the number of lines is 1. If F is equal to 1, the character font is 5x10 dots. If F is equal to 0, the character font is 5x8 dots. This command takes 40 microseconds to execute. Set CGRAM Address RS 0 DB7 0 DB6 1 DB5 A DB4 A DB3 A DB2 A DB1 A DB0 A

This command sets the CGRAM address AAAAAA into the address counter. CGRAM data is sent and received after this setting. This command takes about 40 microseconds to execute.

Set DDRAM Address RS 0 DB7 1 DB6 A DB5 A DB4 A DB3 A DB2 A DB1 A DB0 A

This command sets the DDRAM address AAAAAA into the address counter. DDRAM data is sent and received after this setting. This command takes about 40 microseconds to execute. Write Data to CG or DDRAM RS 1 DB7 0 DB6 D DB5 D DB4 D DB3 D DB2 D DB1 D DB0 D

This command writes the 8 bit binary data DDDDDDDD into CGRAM or DDRAM. Whether the data is written to CGRAM or DDRAM is determined by whether a Set CGRAM Address or Set DDRAM Address command was executed prior to this instruction. After the write the address is automatically incremented or decremented by 1 according to the entry mode. The entry mode also determines the display shift. This instruction takes about 40 microseconds to execute. How the interfacing will be done

J1 DB4 DB5
LCD CONTROLLER

J1 10 11 12 13 14 15 P0.8 P0.9 P0.10 P0.11 P0.12 P0.13


LPC2148

10 11 12 13 14 15

DB6 DB7 EN RS

In out experiment the interfacing will be done connecting the J1 connector in the LCD controller with the J1 connector in the microcontroller. In the LCD controller, following is how the connections are being made Pin 10 of the J1 connector is connected to the DB4 signal. Pin 11 of the J1 connector is connected to the DB5 signal. Pin 12 of the J1 connector is connected to the DB6 signal. Pin 13 of the J1 connector is connected to the DB7 signal. Pin 14 of the J1 connector is connected to the EN signal. Pin 15 of the J1 connector is connected to the RS signal. In the microcontroller, following is how the connections are being made Pin 10 of the J1 connector is connected to the P0.8 pin. Pin 11 of the J1 connector is connected to the P0.9 pin. Pin 12 of the J1 connector is connected to the P0.10 pin. Pin 13 of the J1 connector is connected to the P0.11 pin. Pin 14 of the J1 connector is connected to the P0.12 pin. Pin 15 of the J1 connector is connected to the P0.13 pin. Thus when the J1 connector in the LCD controller is connected with the J1 connector in the microcontroller, following how the connections are made DB4 signal of the LCD controller gets connected to the P0.8 pin of the microcontroller. DB5 signal of the LCD controller gets connected to the P0.9 pin of the microcontroller. DB6 signal of the LCD controller gets connected to the P0.10 pin of the microcontroller. DB7 signal of the LCD controller gets connected to the P0.11 pin of the microcontroller. EN signal of the LCD controller gets connected to the P0.12 pin of the microcontroller. RS signal of the LCD controller gets connected to the P0.13 pin of the microcontroller.

The program to display a string #include<LPC214x.h> void void void void LcdInit(); LcdCmd( unsigned int cmd, unsigned int rs ); LcdDisplayString( char str[] ); Delay( unsigned int ms );

int main() { unsigned int i; // 1.1 Configure the pins to be GPIO pins PINSEL0 = 0x00; // 1.2 Configure the GPIO pins as Output pins IO0DIR = 0x00003F00;

// 1.3 Initialize LCD LcdInit(); // 1.4 Send the Clear Display command LcdCmd( 0x01, 0 ); // 1.5 Send the Display On/Off command LcdCmd( 0x0E, 0 ); // 1.6 Send the Entry Mode Set command LcdCmd( 0x06, 0 ); // 1.7 Send the Set DD RAM Address command LcdCmd( 0x80, 0 ); // 1.8 Display a string LcdDisplayString( Embedded Systems ); // 1.9 Infinite while loop while( 1 ); return 0; }

void LcdInit()

{ // // // // // ****************************************************** Lines 2.1 to 2.4 is sending the first Function Set command. The Function Set command used is 0x28. For first Function Set command only 0x2 needs to be sent. ******************************************************

// 2.1 Set P0.8 to P0.13 to 0 sets EN, RS, DB4 to DB7 // to 0 IO0CLR = 0x3F00; // 2.2 Set EN (P0.12) to 1; DB7 to DB4 to 0x2 IO0SET = 0x1200; // 2.3 Delay for few microseconds Delay( 2 ); // 2.4 Clear EN (P0.12) IO0CLR = 0x1000; // 2.5 Delay for about 40 microseconds Delay( 1000 ); // 2.6 Send the Function Set command again LcdCmd( 0x28, 0 ); } void LcdCmd( unsigned int cmd, unsigned int rs ) { unsigned int temp; // // // rs // // // // 3.1 Left shift rs by 13 bits. This is to make sure that bit no. 13 in variable rs has the Register Select value. = rs << 13; ****************************************************** Line 3.2 to 3.8 is sending the high order four bits of the command. ******************************************************

// 3.2 Clear RS (P0.13), EN (P0.12) and DB4 to DB7 (P0.8 // to P0.11) IO0CLR = 0x3F00;

// 3.3 Get the high order four bits of the command

temp = cmd & 0xF0; // 3.4 Left shift the high order four bits by four bits. // The shifting is done so that the high order four bits // occupy bits 8 to 11 in the variable temp. temp = temp << 4; // 3.5 Make bit number 13 in temp equal to the Register // Select value. temp = rs | temp; // 3.6 Set bit number 12 in temp equal to 1 temp = temp | 0x1000; // 3.7 Set EN (P0.12) to 1, and DB4 to DB7 to the high // order four bits of the command IO0SET = temp; // 3.8 Delay for few microseconds Delay( 2 ); // 3.9 Clear EN (P0.12) IO0CLR = 0x1000; // // // // ****************************************************** Line 3.10 to 3.16 is sending the low order four bits of the command. ******************************************************

// 3.10 Get the low order four bits of the command temp = cmd & 0x0F; // 3.11 Right shift the low order four bits by eight // bits. The shifting is done so that the low order // four bits occupy bits 8 to 11 in the variable // temp. temp = temp << 8; // 3.12 Make bit number 13 in temp equal to the Register // Select value. temp = rs | temp; // 3.13 Set bit number 12 in temp equal to 1 temp = temp | 0x1000;

// 3.14 Clear RS (P0.13), EN (P0.12) and DB4 to DB7 (P0.8

// to P0.11) IO0CLR = 0x3F00; // 3.15 Set EN (P0.12) to 1, and DB0 to DB3 to the low // order four bits of the command IO0SET = temp; // 3.16 Delay for few microseconds. Delay( 2 ); // 3.17 Clear EN (P0.12) IO0CLR = 0x1000; // 3.18 Check if the command is a Clear Display or a // Return Home command if( ( cmd == 0x01 ) || ( cmd == 0x02 ) || (cmd == 0x03)){ // 3.19 If the command is a Clear Display or a Return // Home command, delay for about 1.37 milliseconds Delay( 30000 ); } else { // 3.20 If the command is not a Clear Display or a // Return Home command, delay for about 40 microseconds Delay( 1000 ); } } void LcdDisplayString( char str[] ) { unsigned int i, length; // 4.1 Find the length of the string length = strlen( str ); // 4.2 Get each character for( i = 0; i < length; i++ ) { // 4.3 Display each character LcdCmd( str[i], 1 ); } } void Delay( unsigned int ms ) { // 5.1 Loop ms number of times to create some delay while( ms != 0 ) { ms--; } }

Explanation of the function main Line 1.1 is configuring the pins P0.0 to P0.15 as GPIO pins. We will connect the LCD kit with the LPC2148 kit using the J1 connector on the LCD kit and the J1 connector on the LPC2148 kit. The J1 connector of the LPC2148 kit is connected to the GPIO Pins P0.0 to P0.15. Line 1.2 is configuring the pins P0.8 to P0.13 as output pins. Why did we select pins P0.8 to P0.13? This is because of the following reason. The pins of the J1 connector in the LCD kit are connected to the various LCD signals as follows Pin 10 of the J1 connector D4 signal Pin 11 of the J1 connector D5 signal Pin 12 of the J1 connector D6 signal Pin 13 of the J1 connector D7 signal Pin 14 of the J1 connector EN signal Pin 15 of the J1 connector RS signal Thus we have to communicate with the LCD controller using pins 10, 11, 12, 13, 14, and 15 of the J1 connector in the LCD kit. The J1 connector of the LDC kit is being connected to the J1 connector of the LPC2148 kit. Now pins 10, 11, 12, 13 and 14, of the J1 connector in the LPC2148 kit are connected to the P0.8, P0.9, P0.10, P0.11, P0.12 and P0.13 pins. Thus we have to use pins P0.8 to P0.13 to communicate with the LCD controller. It is important to note that when we connect the LCD kit with the LPC2148 kit using the J1 connector on the LCD kit and the J1 connector on the LPC2148 kit, the following connections are being made. P0.8 to D4 signal P0.9 to D5 signal P0.10 to D6 signal P0.11 to D7 signal P0.12 to EN signal P0.13 to RS signal Line 1.3 invokes LcdInit to initialize the LCD. The LcdInit function is being explained in a later section. Line 1.4 invokes LcdCmd to send the Clear Display command. As can be seen from the commands listed in an earlier section, following is the format for the Clear Display command. RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0

Thus the value 0x01 in DB7 to DB0 corresponds to the Clear Display command. Line 1.5 invokes LcdCmd to send the Display On/Off command. As can be seen from the commands listed in an earlier section, following is the format for the Display On/Off command. RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 1 DB2 D DB1 C DB0 B

Thus the value 0x0E in DB7 to DB0 corresponds to the Display On/Off command. 0x0E corresponds to the binary number 00001110. This means that D is set to 1, C is set to 1 and B is set to 0. As D is set to 1, the display will be turned on. As C is set to 1, the cursor will be displayed. As B is set to 0, the character indicated by the cursor will not blink. Line 1.6 invokes LcdCmd to send the Entry Mode Set command. As can be seen from the commands listed in an earlier section, following is the format for the Entry Mode Set command. RS 0 DB7 0 DB6 0 DB5 0 DB4 0 DB3 0 DB2 1 DB1 I/D DB0 S

Thus the value 0x06 corresponds to the Entry Mode Set command. 0x06 corresponds to the binary number 00000110. This means that I/D is set to 1 and S is set to 0. As I/D is set to 1, the DDRAM address will be incremented by 1 when a character code is written into or read from DDRAM. As S is set to 0, the display will not be shifted when a character code is written to read from DDRAM. Line 1.7 invokes LcdCmd to send the Set DD RAM Address command. As can be seen from the commands listed in an earlier section, following is the format for the Set DD RAM Address command. RS 0 DB7 1 DB6 ADD DB5 ADD DB4 ADD DB3 ADD DB2 ADD DB1 ADD DB0 ADD

Thus the value 0x80 corresponds to the Set DD RAM Address command. The Set DD RAM Address command sets the DDRAM address in the address counter. The DDRAM address is contained in DB6 to DB0. As 0x80 corresponds to the binary number 10000000, the Set DD RAM Address command in our case sets the DDRAM address 0000000 in the address counter. Line 1.8 invokes the function LcdDisplayString to display the string Embedded Systems. The explanation of the function LcdDisplayString is in a later section.

Line 1.9 executes an infinite while loop.

Explanation of the function LcdInit The LcdInit function initializes the LCD controller for 4-bit operation. The LCD controller can be interfaced with the LPC2148 kit in two ways. The two ways are 1. Using only 4 data lines In this method only four data line (DB4 to DB7) are used for data transfer. Data lines DB0 to DB3 are disabled. But we know that the commands are of size 8 bits. Thus transfer of the command from the microcontroller to the LCD controller is completed after the 4-bit data has been transferred twice. To complete the transfer of the 8 bits, first the high order 4 bits are transferred followed by the low order 4 bits. 2. Using 8 data lines In this method all the 8 data lines (DB0 to DB7) are used. So all the 8 bits are transferred at the same time. Using 8 data lines is faster that using only 4 data lines. All the 8 bits can be sent at the same time. If only 4 data lines are used, the data needs to be transmitted twice. The high order 4 bits followed by the low order 4 bits. But using only 4 data lines required less number of the microcontroller pins to be used. If only 4 data lines are used, then the interfacing can be done using only 6 microcontroller pins (4 pins for DB4 to DB7, 1 pin for RS, and 1 pin for EN; in our example we are not using the R/W signal as we only write to the LCD controller and do not read from it). If 8 data lines are used, then interfacing the LCD controller will require 10 pins (8 pins for DB0 to DB7, 1 pin for RS, and 1 pin for EN; in our example we are not using the R/W signal as we only write to the LCD controller and do not read from it ). As the number of pins in a microcontroller are limited (and thus a scarce resource), using only 4 data lines saves 4 microcontroller pins which can be used for interfacing other devices to the microcontroller. How do we configure the LCD controller for 4-bit or 8-bit operation? The Function Set command is used for this purpose. As can be seen from the commands listed in an earlier section, the format for the Function Set command is as follows RS 0 DB7 0 DB6 0 DB5 1 DB4 DL DB3 N DB2 F DB1 * DB0 *

The DL bit sets the interface data length. If DL=1, data is sent or received in 8-bit lengths (DB7 to DB0). If DL=0, data is sent or received in 4-bit lengths (DB7 to DB4) and the data will need to be sent or received twice. In our case we will use 4-bit lengths. Thus we will set the DL bit will be set to 0.

The N bit sets the number of display lines. If N=1, 2 display lines will be used. If N=0, 1 display line will be used. In our case we will use 2 display lines. Thus we will set the N bit will be set to 1. The F bit sets the character font. If F=1, the 5x10 dots character font is selected. If F=0, the 5x8 dots character font is selected. In out case we will use the 5x8 dot character font. Thus we will set the F bit to be equal to 0. Thus to configure the LCD controller for 4 bit data length, 2 display lines and 5x8 dots character font, the Function Set command should be 0x28. The binary value for 0x28 is 00101000. As can be seen, in the above binary number, DL is set to 0, N is set to 1, and F is set to 0. However, when the power is turned on, 8-bit operation is automatically selected and the first write is performed as an 8-bit operation. Since DB0 to DB3 is not connected, a rewrite is then required. Thus, following are the steps that should be followed to configure the LCD controller for 4-bit operation 1. The Function Set command that should be sent is 0x28. As we have only 4 data line, the high order 4 bits will be sent followed by the low order 4 bits. Thus, at first 0x2 will be sent. So set DB4 to DB7 to 0x2. 2. Set EN to 1 (high). 3. After a delay of few microseconds, set EN to 0 (low). When EN changes from 1 to 0 (from high to low), the LCD controller will latch to the values present in the data lines. When power is turned on, 8-bit operation is automatically selected. Thus, the LCD controller will latch to the values available in the lines DB0 to DB7. But we have valid values in lines DB4 to DB7 only. Lines DB0 to DB3 are not connected. DB4 to DB7 is being set to 0x2. This will result in DB7 being set to 0, DB6 being set to 0, DB5 being set to 1 and DB4 being set to 0. Thus the LCD controller will interpret the command as a Function Set command (as DB7 is set to 0, DB6 DB5 bit is set to 1). As DB4 is equal to 0, the LCD controller will be configured for 4-bit operation. However, as DB0 to DB3 are not connected, valid values were not received in these lines. Thus the Function Set command needs to be sent again. 4. Set DB4 to DB7 equal to 0x2 (to send the high order 4 bits of the command). 5. Set EN to 1 (high). 6. After a delay of few microseconds, set EN to 0 (low). 7. As the LCD controller is now set for 4-bit operation (from step 3 above), it will latch to the values present in the four data line. It will use the four bits as the high order 4 bits of the command. The LCD controller will then wait to receive the low order 4 bits. 8. Set DB4 to DB7 to 0x8 (to send the low order 4 bits of the command). 9. Set EN to 1 (high). 10. After a delay of few microseconds, set EN to 0 (low). 11. The LCD controller will latch to the four bits in the four data lines. As it already received the high order 4 bits in step 7 above, the LCD controller will use the 4 bits to be the low order 4 bits of the command.

12. The LCD controller has thus received the high order 4 bits (0x2) in step 7 above and the low order 4 bits (0x8) in step 11. Thus the complete command 0x28 has been received. The LCD controller will now execute the command. Upon completing of the execution, the LCD controller will be configured for 4-bit operation, with number of lines set to 2 and character font set to 5x8 dots font. The LCD controller takes about 40 microseconds to execute the Function Set command. When then LCD controller is executing a command, the microcontroller should not send the next command. If microcontroller send the next command before LCD controller is done executing the current command, the new command will get ignored by the LCD controller. So a delay needs to be added. The steps mentioned above are being performed by the LcdInit function. Lines 2.1 to 2.5 perform the steps 1 to 3. Line 2.6 performs the steps 4 to 12 by invoking LcdCmd function with 0x28 and 0 as the parameters. Line 2.1 set pins P0.8 to P0.13 to 0. Pins P0.8 to P0.13 are already configured as GPIO output pins. So by writing a 1 in bit 8 to bit 13, the value at the corresponding pin can be set to 0. 0x3F00 corresponds to the binary value 0011111100000000. Thus bits 8 to 13 in IO0CLR are being set to 1. Line 2.2 sets IO0SET to 0x1200. 0x1200 corresponds to the binary value 000100100000. When this value is put to IO0SET, P0.13 (RS) remains set to 0, P0.12 (EN) is set to 1, P0.11 (DB7) is set to 0, P0.10 (DB6) is set to 0, P0.9 (DB5) is set to 1, and P0.8 (DB6) is set to 0. This operation is being performed so that 0x2 can be sent over DB7 to DB4. Line 2.3 is to introduce a delay of few milliseconds. The delay is required to allow the values in DB7 to DB4 to settle before EN is changed back to 0. Line 2.4 sets IO0CLR to 0x1000. 0x1000 corresponds to the binary value 0001000000000000. When this value is put to IO0CLR, P0.12 (EN) gets set to 0. This operation is being performed so that EN changes from 1 to 0. When EN changes from 1 to 0, the LCD controller will latch to the values available in the data lines. Line 2.5 introduces a delay of about 40 microseconds. Upon power on, the LCD controller is configured to operate in 8-bit mode. So when EN is changed from 1 to 0, the LCD controller latches to the values present in the data lines and executes the command. In this case the Function Set command is being sent. The LCD controller takes about 40 microseconds to execute the Function Set command. So the microcontroller should wait for about 40 microseconds before sending the next command. Line 2.5 introduces this delay by invoking the Delay function. Line 2.6 sends the Function Set command again. This is required as mentioned in steps 4 to 12 above. The function Set command is set by invoking the LcdCmd function with 0x28 and 0 as the parameters. Upon execution of this statement, the LCD controller will be configured for 4-bit operation, with number of lines set to 2 and character font set to 5x8 dots.

Explanation of the function LcdCmd This function is invoked to send a command to the LCD controller. It has two arguments. The first argument is cmd. It represents the command that needs to be sent. The second argument is rs. It represents the value for the Register Select signal. The value of rs will be 0 or 1. If rs=0, the Instruction register will be selected (by making RS = 0). If rs=1, the Data register will be selected (by making RS = 1). Before invoking this function, the LCD controller should already be set to operate in 4-bit mode. As the LCD controller is already configured to be operate in 4-bit mode, the function does the following Line 3.1 left shifts rs by 13 bits. This is done so that bit number 13 in rs contain the value to be used for the RS signal. Line 3.2 to line 3.9 is sending the high order four bits of the command to the LCD controller. Lets see how this happens. Line 3.2 sets IO0CLR to the value 0x3F00. 0x3F00 corresponds to the binary value 0011111100000000. Thus when this value is put to IO0CLR register, P0.8 to P0.13 gets set to 0. Line 3.3 is performing a bitwise AND operation of the variable cmd with 0xF0. 0xF0 corresponds to the binary number 00000000000000000000000011110000 (showing all the 32 bits here). We are performing the operation, temp = cmd & 0xF0. After this operation is performed, bits 4 to 7 of temp will be equal to bits 4 to 7 of cmd. All other bits in temp will be equal to 0. Bits 0 to 7 in variable cmd contain the 8 bits of the command. Thus, this statement is basically selecting the high order four bits of the command sent in variable cmd. Line 3.4 left shift temp by four bits. From the explanation of line 3.3, we know that bits 4 to 7 of temp holds the high order four bits of the command that needs to be sent to the LCD controller. After we left shift by 4 bits, the high order four bits of the command will be present in bits 8 to 11 of the variable temp. Line 3.5 is performing a bitwise OR operation of the variable temp with rs. From the explanation of line 3.1, we know that bit 13 of rs holds the value for the RS signal. Also from the explanation for line 3.4, we know that bits 8 to 11 of temp holds the high order four bits of the command. Now, we are performing the operation, temp = rs | temp. After the completing of this operation, bit 13 of temp will have the value for the RS signal and bits 8 to 11 will have the high order four bits of the command. All the other bits in temp will be set to 0.

Line 3.6 is performing a bitwise OR operation of the variable temp with 0x1000. In the binary representation of 0x1000, bit number 12 will be set to 1. Thus, after the bitwise OR operation is performed, bit 12 in temp gets set to 1. Line 3.7 sets IO0SET to temp. As a result of this operation, P0.8 to P0.13 will be set to the value present in bits 8 to 13 of temp. Thus, the following happens P0.13 gets set to the value in bit 13 of temp. Bit 13 of temp holds the value for the RS signal. And P0.13 is connected to the RS signal in the LCD controller. P0.12 gets set to the value in bit 12 of temp. From the explanation of line 3.6, we know that bit 12 is equal to 1. Thus EN signal is basically being set to 1. P0.11 to P0.8 gets set to the value in bits 11 to 8 of temp. From the explanation of line 3.3 and 3.4, we know that bits 11 to 8 contain the high order four bits of the command. Thus P0.11 to P0.8 is getting set to the high order four bits of the command. And P0.11 to P0.8 is connected to the data lines DB7 to DB4 of the LCD controller. Line 3.8 adds a delay of few microseconds. This delay is required to let the values in the DB7 to DB4 signal to settle before EN signal is changed from 1 to 0. Line 3.9 sets IO0CLR to 0x1000. In the binary representation of 0x1000, bit number 12 is set to 1. Thus, setting IO0CLR to 0x1000 will clear P0.12. And P0.12 is connected to the EN signal. Thus EN signal will be changed from 1 to 0. When this happens, the LCD controller will latch to the values available in the data lines. The LCD controller will thus receive the high order four bits of the command. As it has been configured to operate in the 4-bit mode, the LDC controller will then wait for the low order four bits of the command to be sent. Line 3.10 to 3.16 sends the low order four bits of the command. Line 3.10 is performing a bitwise AND operation of the variable cmd with 0x0F. 0x0F corresponds to the binary number 00000000000000000000000000001111 (showing all the 32 bits here). We are performing the operation, temp = cmd & 0x0F. After this operation is performed, bits 3 to 0 of temp will be equal to bits 3 to 0 of cmd. All other bits in temp will be equal to 0. Bits 0 to 7 in variable cmd contain the 8 bits of the command. Thus, this statement is basically selecting the low order four bits of the command sent in variable cmd. Line 3.11 left shift temp by 8 bits. From the explanation of line 3.10, we know that bits 3 to 0 of temp holds the low order four bits of the command that needs to be sent to the LCD controller. After we left shift by 8 bits, the low order four bits of the command will be present in bits 8 to 11 of the variable temp. Line 3.12 is performing a bitwise OR operation of the variable temp with rs. The explanation of this line is the same as that of line 3.5.

Line 3.13 is performing a bitwise OR operation of the variable temp with 0x1000. The explanation of this line is the same as that of line 3.6. Line 3.14 sets IO0CLR to 0x3F00. The explanation of this line is same as that of line 3.2. Line 3.15 sets IO0SET to temp. The explanation of this line is the same as that of line 3.7. Only difference is that bits 8 to 11 of temp now holds the low order 4 bits of the command that needs to be sent to the LCD controller. Line 3.16 adds a delay for few microseconds. The explanation is the same as that of line 3.8. Line 3.17 sets IO0CLR to 0x1000. The explanation of this line is the same as that of line 3.9. The only difference is that the LCD controller is now receiving the low order four bits of the command. The high order four bits has already been received at line 3.9. So execution of this line results in the LCD controller receiving all the 8 bits of the command. The LCD controller will now execute the command received. The LCD controller will take some amount of time to execute the command. So the microcontroller will have to wait for some time before sending the next command. If the next command is sent before the LCD controller finishes executing the current command, the new command will be ignored by the LCD controller. Line 3.18 checks if the command set to the LCD controller is a Clear Display or a Return Home command. If equal to 0x01, the command is a Clear Display command. If equal to 0x02 or 0x03, the command is a Return Home command. Line 3.19 will be executed if the command is a Clear Display or Return Home command. The LCD controller takes about 1.60 milliseconds to execute these two commands. So this line adds the delay for about 1.60 milliseconds. Line 3.20 will be executed if the command is neither a Clear Display nor a Return Home command. In this case the LCD controller takes about 40 microseconds to execute the command. So this line adds the delay for about 40 microseconds. Explanation of the function LcdDisplayString This function displays the string passed to it. Line 4.1 determines the length of the string. Line 4.3 gets each character from the string and displays it by invoking the LcdCmd function. The character that needs to be displayed and 1 are passed as the arguments. As can be seen from the commands listed in an earlier section, the format for the command to Write to CG or DDRAM is as follows RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0

RS is set to 1 so that the Data register in the LCD controller is selected. DB7 to DB0 contains the value that needs to be written to the Data register. As RS needs to be set to 1, 1 is passed as the value for the rs parameter. The ASCII value of the character that needs to be printed is passed as the value of the cmd parameter. As explained above, LcdCmd function will convert the 8-bit value into two 4-bit numbers and send it to the LCD controller. Explanation of the function Delay This function adds some delay. The function executes a while loop. The number of time the while loop is executed depends on the value of the ms parameter. Thus based on the value of the ms parameter, this function adds some delay.

You might also like