Lcd

download Lcd

of 32

description

abc

Transcript of Lcd

  • 5/28/2018 Lcd

    1/32

    1

    CHARACTER LCD INTERFACE

    Liquid Crystal Display Module 24-202 is an optional accessory for the APPLICATIONS

    BOARD. The module is ready to connect to P4 of the

    APPS-BD. the 2 line by 20 digits LCD Module issupplied mounted in an acrylic frame for ease of

    handling. This option is invaluable for demonstrating

    the display of messages, warnings or instructions, asused on small instruments or on large public

    information boards such as those found at stations,airports, etc. The techniques for rolling, flashing andalternating messages can be shown.

    The LCD supports an 8-bit data interface and 4-bit data interface to implement data transfers.

    In the lab sessions 8-bit data interface will be implemented.

    All components in th LCD interface are fitted and a standard LCD module & cable supplied.The LCD module is attached to the applications board via P4. When an LCD module is

    connected, preset pot VR2 should be adjusted to obtain the required contrast. Control of the LCDdisplay is achieved by port 2 bits D0 D7 and port 1 bits D0 D2, this is summarized in table

    2.4 of the manual1.

    Port Pin name Pin Function P4 pin no

    GND Vss 1

    5 V Vdd 2

    Pot VR2 Vee (contrast) 3

    Port 1 D0 (PORTB for HC11) RS (Instruction / Data) 4

    Port 1 D1 R/W (Read / Write) 5

    Port 1 D2 E (Enable) 6

    Port 2 D0 (PORTC for HC11) DB0 (Data Bus) 7

    Port 2 D1 DB1 8

    Port 2 D2 DB2 9

    Port 2 D3 DB3 10

    Port 2 D4 DB4 11

    Port 2 D5 DB5 12

    Port 2 D6 DB6 13

    Port 2 D7 DB7 14

    1FEEDBACK Microprocessor Applications Board Reference Manual 24-200

    Anadolu University

    Department of Electrical & Electronics

    Engineering

    EEM 336Microprocessors 1

  • 5/28/2018 Lcd

    2/32

    2

    This document is a tutorial on generic character LCD programming techniques. The web

    version tutorial is edited2as a printable document to help students who attend embedded systems

    classes and is aimed to be a comprehensive resource on controlling character LCD displays.

    Eventhough ASM and C codes given in this document are based upon ATMELs 8051

    microcontroller family, once you understand the general principles; you can easily adapt them toany microprocessor family including Motorolas 68HC1X and 68K families. Pin conversions are

    given on the previous page. You can use those pins to configure your LCD display attached to the

    applications board. A demonstration code segment is given below.

    For HC11, you can easily define functions to set and clear LCD pins as following;

    #include// HC11 Ports are defined in this header

    #defineLCD_data PORTC // P2#defineLCD_rs 0x01 // P1_0

    voidset_LCD_rs(void){PORTB |= LCD_rs; // RS bit of PORTB is set

    }voidclear_LCD_rs(void){

    PORTB &= ~LCD_rs; // RS bit of PORTB is cleared}

    You should also define similar functions for setting and clearing other LCD pins (rw, en). After

    defining set and clear functions, you can replace the rows LCD_rs = 1;of the c codes given

    in tutorial with set_LCD_rs(); and etc When your modifications are finished, you canrun following sample code and check your LCD display;

    // A sample code for controlling LCD display in HC11// LCD functions should be defined as given in tutorial.

    intmain(void){

    char*mytext = "LCD_test OK!";DDRC = 0xFF;LCD_init();// LCD display should be initialized first of all.LCD_sendstring(mytext); // sends input string to the display.return0;

    }

    Important Note: InLCD_busy() function, you should change direction ofPORTC_Pin7asinput (first row). At the end of function, its direction should be restored as output (append it to

    the code).

    2Edited byResearch AsistantSukru Gorgulu, May, 2010, Anadolu University, Eskisehir, TR

  • 5/28/2018 Lcd

    3/32

    3

    A TUTORIAL ON GENERIC LCD PROGRAMMING

    The most commonly used Character based LCDs are based on Hitachi's HD44780controller or other which are compatible with HD44580. In this tutorial

    3, 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 cangive a new look to your application.

    INTRODUCTION TO LCD .......................................................................................................... 4Pin Description ..................................................................................................................... 4

    BASICS OF LCD ........................................................................................................................... 6DDRAM - Display Data RAM ............................................................................................. 6

    CGROM - Character Generator ROM ................................................................................. 6CGRAM - Character Generator RAM ................................................................................. 9BF - Busy Flag...................................................................................................................... 9Instruction Register (IR) and Data Register (DR) ................................................................ 9

    LCD COMMANDS ...................................................................................................................... 10Commands and Instruction set ........................................................................................... 10

    LCD INITIALIZATION ............................................................................................................. 13Initialization by internal Reset Circuit ............................................................................... 13Initialization by instructions ............................................................................................... 14LCD Entry mode ................................................................................................................ 16Programming example for LCD Initialization ................................................................... 16

    CHECKING BUSY FLAG .......................................................................................................... 18Reading the busy Flag ........................................................................................................ 18

    SENDING COMMAND & DATA TO LCD .............................................................................. 20Sending Commands to LCD ............................................................................................... 20Setting cursor position on LCD .......................................................................................... 21Sending Data to LCD ......................................................................................................... 21

    CREATING CUSTOM CHARACTERS ................................................................................... 24CGRAM and Character Building ....................................................................................... 24

    INTRODUCTION TO USING LCD IN 4-BIT MODE ............................................................ 28LCD connections in 4-bit Mode ......................................................................................... 28Sending data/command in 4-bit Mode ............................................................................... 294-bit Initialization ............................................................................................................... 29Sending Dommand/Data to LCD in 4-bit mode ................................................................. 31

    3Tutorial Web Source: http://www.8051projects.net/lcd-interfacing/introduction.php

  • 5/28/2018 Lcd

    4/32

    4

    INTRODUCTION TO LCD

    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 LCDssupporting 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

    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 everythingelse is same for the double controller too. Lets take a look at the basic information which is there

    in every LCD.

  • 5/28/2018 Lcd

    5/32

    5

    Pin No. Name Description

    Pin no. 1 VSS Power supply (GND)

    Pin no. 2 VCC Power supply (+5V)

    Pin no. 3 VEE Contrast adjust

    Pin no. 4 RS0 = Instruction input

    1 = Data input

    Pin no. 5 R/W0 = Write to LCD module

    1 = Read from LCD module

    Pin no. 6 EN Enable signal

    Pin no. 7 D0 Data bus line 0 (LSB)

    Pin no. 8 D1 Data bus line 1

    Pin no. 9 D2 Data bus line 2Pin no. 10 D3 Data bus line 3

    Pin no. 11 D4 Data bus line 4

    Pin no. 12 D5 Data bus line 5

    Pin no. 13 D6 Data bus line 6

    Pin no. 14 D7 Data bus line 7 (MSB)

    Table 1: Character LCD pins with 1 Controller

    Pin No. Name Description

    Pin no. 1 D7 Data bus line 7 (MSB)

    Pin no. 2 D6 Data bus line 6

    Pin no. 3 D5 Data bus line 5

    Pin no. 4 D4 Data bus line 4

    Pin no. 5 D3 Data bus line 3

    Pin no. 6 D2 Data bus line 2

    Pin no. 7 D1 Data bus line 1

    Pin no. 8 D0 Data bus line 0 (LSB)

    Pin no. 9 EN1 Enable signal for row 0 and 1 (1stcontroller)

    Pin no. 10 R/W0 = Write to LCD module

    1 = Read from LCD module

    Pin no. 11 RS0 = Instruction input

    1 = Data input

    Pin no. 12 VEE Contrast adjust

    Pin no. 13 VSS Power supply (GND)

    Pin no. 14 VCC Power supply (+5V)

    Pin no. 15 EN2 Enable signal for row 2 and 3 (2ndcontroller)

    Pin no. 16 NC Not Connected

    Table 2: Character LCD pins with 2 Controller

  • 5/28/2018 Lcd

    6/32

    6

    BASICS OF 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) thatis 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.

    Figures below will show you the DDRAM addresses of 1 Line, 2 Line and 4 Line LCDs.

    Figure 2: DDRAM Address for 1 Line LCD

    Figure 3: DDRAM Address for 2 Line LCD

    Figure 4: DDRAM Address for 4 Line LCD

    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 moredetails). 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.

  • 5/28/2018 Lcd

    7/32

    7

    Figure 5: LCD characters code map for 5x8 dots

  • 5/28/2018 Lcd

    8/32

    8

    Figure 6: LCD characters code map for 5x10 dots

  • 5/28/2018 Lcd

    9/32

    9

    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 thecharacter 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 forprocessing, 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 LCDprocessing.

    To read Busy Flag, the condition RS = 0 and R/W = 1 must be met and The MSB of the LCDdata 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. Instructionregister 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 tothe 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 addresswhere 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.

  • 5/28/2018 Lcd

    10/32

    10

    LCD COMMANDS

    Commands and Instruction set

    Only the instruction register (IR) and the data register (DR) of the LCD can be controlled by theMCU. 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 signalssent 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

  • 5/28/2018 Lcd

    11/32

    11

    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.

  • 5/28/2018 Lcd

    12/32

    12

    No. Instruction Hex Decimal

    1 Function Set: 8-bit, 1 Line, 5x7 Dots 0x30 48

    2 Function Set: 8-bit, 2 Line, 5x7 Dots 0x38 56

    3 Function Set: 4-bit, 1 Line, 5x7 Dots 0x20 32

    4 Function Set: 4-bit, 2 Line, 5x7 Dots 0x28 40

    5 Entry Mode 0x06 6

    6Display off Cursor off(clearing display without clearing DDRAM

    content)

    0x08 8

    7 Display on Cursor on 0x0E 14

    8 Display on Cursor off 0x0C 12

    9 Display on Cursor blinking 0x0F 1510 Shift entire display left 0x18 24

    12 Shift entire display right 0x1C 30

    13 Move cursor left by one character 0x10 16

    14 Move cursor right by one character 0x14 20

    15 Clear Display (also clear DDRAM content) 0x01 1

    16Set DDRAM address or coursor position on

    display0x80+add* 128+add*

    17Set CGRAM address or set pointer toCGRAM location

    0x40+add**64+add**

    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 testingwith 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.

  • 5/28/2018 Lcd

    13/32

    13

    LCD INITIALIZATION

    Before using the LCD for display purpose, LCD has to be initialized either by the internalreset 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. we will dicussboth ways of initialization one by one.

    Initialization by internal Reset Circuit

    An internal reset circuit automatically initializes the HD44780U when the power is turned on.

    The following instructions are executed during the initialization. The busy flag (BF) is kept in thebusy state until the initialization ends (BF = 1). The busy state lasts for 10 ms after VCC rises to

    4.5 V.

    Display clear Function set:

    DL = 1; 8-bit interface dataN = 0; 1-line display

    F = 0; 5 x 8 dot character font

    Display on/off control:D = 0; Display off

    C = 0; Cursor off

    B = 0; Blinking off

    Entry mode set:I/D = 1; Increment by 1

    S = 0; No shift

    Note: If the electrical characteristics conditions listed under the table Power Supply Conditions

    Using Internal Reset Circuit are not met, the internal reset circuit will not operate normally andwill fail to initialize the HD44780U. For such a case, initial-ization must be performed by the

    MCU as explained in the section, Initializing by Instruction.

    As mentioned in the Note, there are certain condtions that has to be met, if user want to use

    initialization by internal reset circuit. These conditions are shown in the Table 5 below.

    Table 5: Power Supply condition for Internal Reset circuit

    Figure 7 shows the test condition which are to be met for internal reset circuit to be active.

  • 5/28/2018 Lcd

    14/32

    14

    Figure 7: Internal Power Supply reset

    Now the problem with the internal reset circuit is, it is highly dependent on power supply, to meetthis critical power supply conditions is not hard but are difficult to achive when you are making asimple application. So usually the second menthod i.e. Initialization by instruction is used and is

    recommended most of the time.

    Initialization by instructions

    Initializing LCD with instructions is really simple. Given below is a flowchart that describles thestep to follow, to initialize the LCD.

  • 5/28/2018 Lcd

    15/32

    15

    Figure 8: Flow chart for LCD initialization

    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 20ms3) Send command 0x30 - 8-bit interface

    4) Delay 20ms5) Send command 0x30 - 8-bit interface6) Delay 20ms

    7) Send Function set - see Table 4 for more information

    8) Display Clear command

    9) Set entry mode command - explained below

  • 5/28/2018 Lcd

    16/32

    16

    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 interfaceyou are using (see Table 4 in LCD Commandsection).

    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 bitb) 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 Commandsection). 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 totry all the possible entry modes and see the results, I am sure you will be surprised.

    Programming example for LCD Initialization

    CODE: (ASM)LCD_data equP2 ;LCD Data portLCD_D7 equP2.7 ;LCD D7/Busy FlagLCD_rs equP1.0 ;LCD Register SelectLCD_rw equP1.1 ;LCD Read/Write

    LCD_en equP1.2 ;LCD Enable

    LCD_init:mov LCD_data,#38H ;Function set: 2 Line, 8-bit, 5x7 dotsclr LCD_rs ;Selected command registerclr LCD_rw ;We are writing in instruction registersetb LCD_en ;Enable H->Lclr LCD_enacallLCD_busy ;Wait for LCD to process the commandmov LCD_data,#0FH ;Display on, Curson blinking commandclr LCD_rs ;Selected instruction registerclr LCD_rw ;We are writing in instruction registersetb LCD_en ;Enable H->L

    clr LCD_enacallLCD_busy ;Wait for LCD to process the commandmov LCD_data,#01H ;Clear LCDclr LCD_rs ;Selected command registerclr LCD_rw ;We are writing in instruction registersetb LCD_en ;Enable H->Lclr LCD_enacallLCD_busy ;Wait for LCD to process the commandmov LCD_data,#06H ;Entry mode, auto increment with no shiftclr LCD_rs ;Selected command registerclr LCD_rw ;We are writing in instruction registersetb LCD_en ;Enable H->Lclr LCD_en

  • 5/28/2018 Lcd

    17/32

    17

    acallLCD_busy ;Wait for LCD to process the commandret ;Return from routine

    Now we can do the same thing in C, I am giving example using Keil C. Similar code can be

    written for SDCC.

    CODE: (C)#include .#define LCD_data P2#define LCD_D7 P2_7#define LCD_rs P1_0#define LCD_rw P1_1#define LCD_en P1_2

    voidLCD_init(){

    LCD_data =0x38; //Function set: 2 Line, 8-bit, 5x7 dotsLCD_rs =0; //Selected command registerLCD_rw =0; //We are writing in data registerLCD_en =1; //Enable H->LLCD_en =0;LCD_busy(); //Wait for LCD to process the commandLCD_data =0x0F; //Display on, Curson blinking commandLCD_rs =0; //Selected command registerLCD_rw =0; //We are writing in data registerLCD_en =1; //Enable H->LLCD_en =0;LCD_busy(); //Wait for LCD to process the commandLCD_data =0x01; //Clear LCDLCD_rs =0; //Selected command registerLCD_rw =0; //We are writing in data registerLCD_en =1; //Enable H->LLCD_en =0;LCD_busy(); //Wait for LCD to process the commandLCD_data =0x06; //Entry mode, auto increment with no shiftLCD_rs =0; //Selected command registerLCD_rw =0; //We are writing in data registerLCD_en =1; //Enable H->LLCD_busy();

    }

    With the help of the above code, you are able to initialize the LCD. Now there is a

    function/subroutine coming in the code i.e. LCD_busy, which is used to put delay for LCD sothat there should not be any command or data sent to the LCD untill it finish executing thecommand. More on this delay routine is explained in the next section.

  • 5/28/2018 Lcd

    18/32

    18

    CHECKING BUSY FLAG

    Reading the busy Flag

    As discussed in the previous section, there must be some delay which is needed to be there forLCD to successfully process the command or data. So this delay can be made either with a delay

    loop of specified time more than that of LCD process time or we can read the busy flag, which is

    recomended. The reason to use busy flag is that delay produced is almost for the exact amount oftime for which LCD need to process the time. So is best suited for every application.

    Steps to read busy flag

    When we send the command, the BF or D7th bit of the LCD becomes 1 and as soon as the

    command is processed the BF = 0. Following are the steps to be kept in mind while reading theBusy flag.

    Select command register Select read operation Send enable signal Read the flag

    So following the above steps we can write the code in assembly as below...

    CODE:;Ports used are same as the previous example

    LCD_busy:setb LCD_D7 ;Make D7th bit of LCD data port as i/psetb LCD_en ;Make port pin as o/pclr LCD_rs ;Select command registersetb LCD_rw ;we are reading

    check:clr LCD_en ;Enable H->Lsetb LCD_enjb LCD_D7,check ;read busy flag again and again till it becomes

    0ret ;Return from busy routine

    The equivalent C code Keil C compiler. Similar code can be written for SDCC.

    CODE:voidLCD_busy(){

    LCD_D7 =1; //Make D7th bit of LCD as i/pLCD_en =1; //Make port pin as o/pLCD_rs =0; //Selected command registerLCD_rw =1; //We are readingwhile(LCD_D7){ //read busy flag again and again till it becomes

  • 5/28/2018 Lcd

    19/32

    19

    0LCD_en =0; //Enable H->LLCD_en =1;

    }}

    The above routine will provide the necessary delay for the instructions to complete. If you dontwant to read the busy flag you can simply use a delay routine to provide a specific amount of

    delay. A simple delay routine for the LCD is given below.

    CODE:LCD_busy_delay:

    mov r7,#50Hback:

    mov r6,#FFHdjnzr6,$

    djnzr7,backret ;Return from busy routine

    CODE:voidLCD_busy_delay(){

    unsignedchari,j;for(i=0;i

  • 5/28/2018 Lcd

    20/32

    20

    SENDING COMMAND & DATA TO LCD

    Sending Commands to LCD

    To send commands we simply need to select the command register. Everything is same as wehave 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

    Keeping these steps in mind we can write LCD command routine as.

    CODE:;Ports used are same as the previous example;Routine to send command to LCD

    LCD_command:mov LCD_data,A ;Move the command to LCD portclr LCD_rs ;Selected command registerclr LCD_rw ;We are writing in instruction registersetb LCD_en ;Enable H->Lclr LCD_en

    acallLCD_busy ;Wait for LCD to process the commandret ;Return from busy routine

    ; Usage of the above routine; A will carry the command for LCD; e.g. we want to send clear LCD command;; mov a,#01H ;01H is command for clearing LCD; acall LCD_command ;Send the command

    The equivalent C code Keil C compiler. Similar code can be written for SDCC.

    CODE:voidLCD_command(unsignedcharvar){

    LCD_data =var; //Function set: 2 Line, 8-bit, 5x7 dotsLCD_rs =0; //Selected command registerLCD_rw =0; //We are writing in instruction registerLCD_en =1; //Enable H->LLCD_en =0;LCD_busy(); //Wait for LCD to process the command

    }// Using the above function is really simple// var will carry the command for LCD// e.g.

  • 5/28/2018 Lcd

    21/32

    21

    //// LCD_command(0x01);

    Setting cursor position on LCD

    To set the cursor position on LCD, we need to send the DDRAM address...

    CODE:Bit7 6 5 4 3 2 1 01 AD6 AD5 AD4 AD3 AD2 AD1 AD0

    The seventh bit is always 1, and bit 0 to 7 are DDRAM address (See the introduction sectionof

    LCD). so if you want to put the cursor on first position the address will be '0000000B' in binary

    and 7th bit is 1. so address will be 0x80, so for DDRAM all address starts from 0x80.

    For 2 line and 16 character LCD. The adress from 0x80 to 0x8F are visible on first line and 0xC0to 0xCF is visible on second line, rest of the DDRAM area is still available but is not visible on

    the LCD, if you want to check this thing, then simply put a long sting greater than 16 character

    and shift the entire display, you will see all the missing character coming from the back.. this wayyou can make scrolling line on LCD (see more on shifting display in commands section).

    Below is an example for setting cursor position on LCD.

    CODE:

    ;We are placing the cursor on the 4th position;so the DDRAM address will be 0x03;and the command will be 0x80+0x03 = 0x83mova,#83H ;load the commandacallLCD_command ;send command to LCD

    CODE:// to do the same thing is C// as we done beforeLCD_command(0x83);

    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

  • 5/28/2018 Lcd

    22/32

    22

    wait for LCD to process the dataKeeping these steps in mind we can write LCD command routine as.

    CODE:;Ports used are same as the previous example;Routine to send data (single character) to LCD

    LCD_senddata:mov LCD_data,A ;Move the command to LCD portsetb LCD_rs ;Selected data registerclr LCD_rw ;We are writingsetb LCD_en ;Enable H->Lclr LCD_enacallLCD_busy ;Wait for LCD to process the dataret ;Return from busy routine

    ; Usage of the above routine; A will carry the character to display on LCD; e.g. we want to print A on LCD;; mov a,#'A' ;Ascii value of 'A' will be loaded in accumulator; acall LCD_senddata ;Send data

    The equivalent C code Keil C compiler. Similar code can be written for SDCC.

    CODE:voidLCD_senddata(unsignedcharvar)

    {LCD_data =var; //Function set: 2 Line, 8-bit, 5x7 dotsLCD_rs =1; //Selected data registerLCD_rw =0; //We are writingLCD_en =1; //Enable H->LLCD_en =0;LCD_busy(); //Wait for LCD to process the command

    }// Using the above function is really simple// we will pass the character to display as argument to function// e.g.//// LCD_senddata('A');

    Now you have seen that its really easy to send command and data to LCD. Now what if we have

    a string to send to LCD? how we are going to do that?

    Is simple, we will store the LCD string in the ROM of controller and call the string character by

    character. A simple exmple is shown below.

    CODE:

  • 5/28/2018 Lcd

    23/32

    23

    ;Sending string to LCD Example

    LCD_sendstring:clr

    a ;clear Accumulator for any previous datamovc a,@a+dptr ;load the first character in accumulatorjz exit ;go to exit if zeroacalllcd_senddata ;send first charinc dptr ;increment data pointersjmp LCD_sendstring ;jump back to send the next character

    exit:ret ;End of routine

    ; Usage of the above routine; DPTR(data pointer) will carry the address; of string to send to LCD.; e.g. we want to print "LCD Tutorial" on LCD then;

    ; mov dptr,#my_string ;my_string is the label where the string is stored; acall LCD_sendstring ;Send string;; To store a string..; my_string:; DB "LCD Tutorial", 00H; 00H indicate that string is finished.

    The equivalent C code Keil C compiler. Similar code can be written for SDCC.

    CODE:voidLCD_sendstring(unsignedchar*var)

    {while(*var) //till string endsLCD_senddata(*var++); //send characters one by one

    }// Using the above function is really simple// we will pass the string directly to the function// e.g.//// LCD_sendstring("LCD Tutorial");

    Now we are ready with sending data and sending command to LCD. Now the last and final

    section which is creating custom characters or patterns to display on LCD. Please proceed to thenext section to read more.

  • 5/28/2018 Lcd

    24/32

    24

    CREATING CUSTOM CHARACTERS

    CGRAM and Character Building

    As already explained, all character based LCD of type HD44780 has CGRAM area to create userdefined 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, youcan 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 getthe 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 usingcursor 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.

  • 5/28/2018 Lcd

    25/32

    25

    Now we get the values for each row as shown.

    Bit: 4 3 2 1 0 - HexRow1: 0 0 1 0 0 - 0x04Row2: 0 1 1 1 0 - 0x0E

    Row3: 0 1 1 1 0 - 0x0E

    Row4: 0 1 1 1 0 - 0x0ERow5: 1 1 1 1 1 - 0x1F

    Row6: 0 0 0 0 0 - 0x00

    Row7: 0 0 1 0 0 - 0x04Row8: 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 thesevalues 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)

    1 0x00 - 0x07

    2 0x08 - 0x0F

    3 0x10 - 0x17

    4 0x18 - 0x1F

    5 0x20 - 0x27

    6 0x28 - 0x2F

    7 0x30 - 0x37

    8 0x38 - 0x3F

    We can point the cursor to CGRAM address by sending command, which is 0x40 + CGRAMaddress (For more information please see Table 4 in commands section). Lets say we want to

    write the Bell pattern at second pattern location. So we send the command as 0x48 (0x40 +

    0x08), and then we send the pattern data. Below is a small programming example to do this.

    CODE:;LCD Ports are same as discussed in previous sections

    LCD_Build:mov A,#48H ;Load the location where we want to storeacallLCD_command ;Send the commandmov A,#04H ;Load row 1 dataacallLCD_senddata ;Send the datamov A,#0EH ;Load row 2 dataacallLCD_senddata ;Send the datamov A,#0EH ;Load row 3 dataacallLCD_senddata ;Send the datamov A,#0EH ;Load row 4 data

  • 5/28/2018 Lcd

    26/32

    26

    acallLCD_senddata ;Send the datamov A,#1FH ;Load row 5 dataacallLCD_senddata ;Send the datamov

    A,#00H ;Load row 6 dataacallLCD_senddata ;Send the datamov A,#04H ;Load row 7 dataacallLCD_senddata ;Send the datamov A,#00H ;Load row 8 dataacallLCD_senddata ;Send the dataret ;Return from routine

    The above routine will create bell character at pattern location 2. To display the above generatedpattern on LCD, simply load the pattern location (0,1,2,...7) and call the LCD_senddata

    subroutine. Now we can also write the above routine in C as...

    CODE://LCD Ports are same as discussed inprevious sectionsvoid LCD_Build(){

    LCD_command(0x48); //Load the location where we want to storeLCD_senddata(0x04); //Load row 1 dataLCD_senddata(0x0E); //Load row 2 dataLCD_senddata(0x0E); //Load row 3 dataLCD_senddata(0x0E); //Load row 4 dataLCD_senddata(0x1F); //Load row 5 dataLCD_senddata(0x00); //Load row 6 dataLCD_senddata(0x04); //Load row 7 dataLCD_senddata(0x00); //Load row 8 data

    }

    I think now most of you find programing in C more simple than assembly. We can alsosummarize the above in a simple small routine so that you can simply call the build routineproviding a pointer to array containing the build data. Below example shows how to do it.

    CODE://Input:// location:location where you want to store// 0,1,2,....7// ptr:Pointer to pattern data////Usage:// pattern[8]={0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x04,0x00};

    // LCD_build(1,pattern);////LCD Ports are same as discussed inprevious sections

    void LCD_build(unsigned char location,unsigned char *ptr){unsigned char i;if(location

  • 5/28/2018 Lcd

    27/32

    27

    So the above example shows how to simpify most of your work. To make easy for you to find the

    values for custom patterns, you can make use of Custom Character Calculator given on web page.

    This part of the tutorial ends here. For programming help please post in the forum. Have a nicetime with your LCD.

  • 5/28/2018 Lcd

    28/32

    28

    INTRODUCTION TO USING LCD IN 4-BIT MODE

    Till now whatever we discussed in the previous part of ths LCD tutorial, we were dealing with 8-bit mode. Now we are going to learn how to use LCD in 4-bit mode. There are many reasons why

    sometime we prefer to use LCD in 4-bit mode instead of 8-bit. One basic reason is lesser numberof pins are needed to interface LCD.

    In 4-bit mode the data is sent in nibbles, first we send the higher nibble and then the lower nibble.To enable the 4-bit mode of LCD, we need to follow special sequence of initialization that tells

    the LCD controller that user has selected 4-bit mode of operation. We call this special sequence

    as resetting the LCD. Following is the reset sequence of LCD.

    Wait for abour 20mS Send the first init value (0x30) Wait for about 10mS Send second init value (0x30) Wait for about 1mS Send third init value (0x30) Wait for 1mS Select bus width (0x30 - for 8-bit and 0x20 for 4-bit) Wait for 1mS

    The busy flag will only be valid after the above reset sequence. Usually we do not use busy flagin 4-bit mode as we have to write code for reading two nibbles from the LCD. Instead we simply

    put a certain ammount of delay usually 300 to 600uS. This delay might vary depending on theLCD you are using, as you might have a different crystal frequency on which LCD controller isrunning. So it actually depends on the LCD module you are using. So if you feel any problem

    running the LCD, simply try to increase the delay. This usually works. For me about 400uS

    works perfect.

    LCD connections in 4-bit Mode

    Below is the connection diagram of LCD in 4-bit mode, where we only need 6 pins to interface

    an LCD. D4-D7 are the data pins connection and Enable and Register select are for LCD control

    pins. We are not using Read/Write (RW) Pin of the LCD, as we are only writing on the LCD sowe have made it grounded permanently. If you want to use it.. then you may connect it on your

    controller but that will only increase another pin and does not make any big difference.Potentiometer RV1 is used to control the LCD contrast. The unwanted data pins of LCD i.e. D0-

    D3 are connected to ground.

  • 5/28/2018 Lcd

    29/32

    29

    Sending data/command in 4-bit Mode

    We will now look into the common steps to send data/command to LCD when working in 4-bitmode. As i already explained in 4-bit mode data is sent nibble by nibble, first we send higher

    nibble and then lower nibble. This means in both command and data sending function we need to

    saperate the higher 4-bits and lower 4-bits.

    The common steps are:

    Mask lower 4-bits Send to the LCD port

    Send enable signal Mask higher 4-bits Send to LCD port Send enable signal

    We are done with the theory part now, In the next section we will take a look at the programming

    microcontroller to control LCD in 4-bit mode.

    4-bit Initialization

    Initialization of LCD is completed only after the reset sequence and basic initialization

  • 5/28/2018 Lcd

    30/32

    30

    commands. We have already discussed about the reset sequence of the lcd in the previous section.

    So lets look at the programming now...

    Assembly Program

    CODE:;In this whole 4-bit tutorial LCD is connected to;my controller in following way...;D4 - P3.0;D5 - P3.1;D6 - P3.2;D7 - P3.3;EN - P3.7;RS - P3.5

    lcd_port equP3 ;LCD connected to Port3

    en equP3.7 ;Enable connected to P3.7rs equP3.5 ;Register select to P3.5

    lcd_reset: ;LCD reset sequencemovlcd_port,#0FFHmovdelay,#20 ;20mS delayacalldelaymsmovlcd_port,#83H ;Data = 30H, EN = 1, First Initmovlcd_port,#03H ;Data = 30H, EN = 0movdelay,#15 ;Delay 15mSacalldelaymsmovlcd_port,#83H ;Second Init, Data = 30H, EN = 1movlcd_port,#03H ;Data = 30H, EN = 0mov

    delay,#5 ;Delay 5mSacalldelaymsmovlcd_port,#83H ;Third Initmovlcd_port,#03Hmovdelay,#5 ;Delay 5mSacalldelaymsmovlcd_port,#82H ;Select Data width (20H for 4bit)movlcd_port,#02H ;Data = 20H, EN = 0movdelay,#5 ;Delay 5mSacalldelaymsret

    lcd_init:acalllcd_reset ;Call LCD Reset sequence

    mova,#28H ;4-bit, 2 line, 5x7 dotsacalllcd_cmd ;Call LCD commandmova,#0CH ;Display ON cursor OFFacalllcd_cmd ;Call LCD commandmova,#06H ;Set entry mode (Auto increment)acalllcd_cmd ;Call LCD commandmova,#80H ;Bring cursor to line 1acalllcd_cmd ;Call LCD commandret

    C Program

  • 5/28/2018 Lcd

    31/32

    31

    CODE://The pins used are same as explained earlier#define lcd_port P3

    //LCD Registers addresses#define LCD_EN 0x80#define LCD_RS 0x20

    voidlcd_reset(){

    lcd_port =0xFF;delayms(20);lcd_port =0x03+LCD_EN;lcd_port =0x03;delayms(10);lcd_port =0x03+LCD_EN;lcd_port =0x03;

    delayms(1);lcd_port =0x03+LCD_EN;lcd_port =0x03;delayms(1);lcd_port =0x02+LCD_EN;lcd_port =0x02;delayms(1);

    }

    voidlcd_init (){

    lcd_reset(); // Call LCD resetlcd_cmd(0x28); // 4-bit mode - 2 line - 5x7 font.

    lcd_cmd(0x0C); // Display no cursor - no blink.lcd_cmd(0x06); // Automatic Increment - No Display shift.lcd_cmd(0x80); // Address DDRAM with 0 offset 80h.

    }

    Sending Dommand/Data to LCD in 4-bit mode

    Assembly Program

    CODE:lcd_cmd: ;LCD command Routine

    movtemp,a ;Save a copy of command to tempswapa ;Swap to use higher nibbleanla,#0FH ;Mask the first four bitsadda,#80H ;Enable = 1, RS = 0movlcd_port,a ;Move it to lcd portanla,#0FH ;Enable = 0, RS = 0movlcd_port,a ;Move to lcd port

    mova,temp ;Reload the command from tempanla,#0FH ;Mask first four bitsadda,#80H ;Enable = 1

  • 5/28/2018 Lcd

    32/32

    32

    movlcd_port,a ;Move to portanla,#0FH ;Enable = 0movlcd_port,a ;Move to lcd port

    movdelay,#1 ;delay 1 msacalldelaymsret

    lcd_dat: ;LCD data Routinemovtemp,a ;Keep copy of data in tempswapa ;We need higher nibbleanla,#0FH ;Mask first four bitsadda,#0A0H ;Enable = 1, RS = 1movlcd_port,a ;Move to lcd portnopclren ;Enable = 0

    mova,temp ;Reload the data from tempanla,#0FH ;we need lower nibble nowadda,#0A0H ;Enable = 1, RS = 1movlcd_port,a ;Move to lcd portnopclren ;Enable = 0

    movdelay,#1 ;Delay 1mSacalldelaymsret

    C Program

    CODE:voidlcd_cmd (charcmd){

    lcd_port =((cmd >>4)&0x0F)|LCD_EN;lcd_port =((cmd >>4)&0x0F);

    lcd_port =(cmd &0x0F)|LCD_EN;lcd_port =(cmd &0x0F);

    delayus(200);delayus(200);

    }

    voidlcd_data (unsignedchardat){

    lcd_port =(((dat >>4)&0x0F)|LCD_EN|LCD_RS);lcd_port =(((dat >>4)&0x0F)|LCD_RS);

    lcd_port =((dat &0x0F)|LCD_EN|LCD_RS);lcd_port =((dat &0x0F)|LCD_RS);

    delayus(200);delayus(200);

    }