LCD Backgorund

download LCD Backgorund

of 40

Transcript of LCD Backgorund

  • 8/6/2019 LCD Backgorund

    1/40

    LCD Backgorund

    Frequently, an 8051 program must interact with the outside world using input and outputdevices that communicate directly with a human being. One of the most common devicesattached to an 8051 is an LCD display. Some of the most common LCDs connected to

    the 8051 are 16x2 and 20x2 displays. This means 16 characters per line by 2 lines and 20characters per line by 2 lines, respectively.

    Fortunately, a very popular standard exists which allows us to communicate with the vastmajority of LCDs regardless of their manufacturer. The standard is referred to asHD44780U, which refers to the controller chip which receives data from an externalsource (in this case, the 8051) and communicates directly with the LCD.

    44780 BACKGROUND

    The 44780 standard requires 3 control lines as well as either 4 or 8 I/O lines for the data

    bus. The user may select whether the LCD is to operate with a 4-bit data bus or an 8-bitdata bus. If a 4-bit data bus is used the LCD will require a total of 7 data lines (3 controllines plus the 4 lines for the data bus). If an 8-bit data bus is used the LCD will require atotal of 11 data lines (3 control lines plus the 8 lines for the data bus).

    The three control lines are referred to as EN, RS, and RW.

    The EN line is called "Enable." This control line is used to tell the LCD that you aresending it data. To send data to the LCD, your program should make sure this line is low(0) and then set the other two control lines and/or put data on the data bus. When theother lines are completely ready, bring EN high (1) and wait for the minimum amount of

    time required by the LCD datasheet (this varies from LCD to LCD), and end by bringingit low (0) again.

    The RS line is the "Register Select" line. When RS is low (0), the data is to be treated asa command or special instruction (such as clear screen, position cursor, etc.). When RS ishigh (1), the data being sent is text data which sould be displayed on the screen. Forexample, to display the letter "T" on the screen you would set RS high.

    The RW line is the "Read/Write" control line. When RW is low (0), the information onthe data bus is being written to the LCD. When RW is high (1), the program is effectivelyquerying (or reading) the LCD. Only one instruction ("Get LCD status") is a read

    command. All others are write commands--so RW will almost always be low.

    Finally, the data bus consists of 4 or 8 lines (depending on the mode of operation selectedby the user). In the case of an 8-bit data bus, the lines are referred to as DB0, DB1, DB2,DB3, DB4, DB5, DB6, and DB7.

    AN EXAMPLE HARDWARE CONFIGURATION

  • 8/6/2019 LCD Backgorund

    2/40

    As we've mentioned, the LCD requires either 8 or 11 I/O lines to communicate with. Forthe sake of this tutorial, we are going to use an 8-bit data bus--so we'll be using 11 of the8051's I/O pins to interface with the LCD.

    Let's draw a sample psuedo-schematic of how the LCD will be connected to the 8051.

    As you can see, we've established a 1-to-1 relation between a pin on the 8051 and a lineon the 44780 LCD. Thus as we write our assembly program to access the LCD, we aregoing to equate constants to the 8051 ports so that we can refer to the lines by their 44780name as opposed to P0.1, P0.2, etc. Let's go ahead and write our initial equates:

    DB0 EQU P1.0

    DB1 EQU P1.1

    DB2 EQU P1.2

    DB3 EQU P1.3DB4 EQU P1.4

    DB5 EQU P1.5

    DB6 EQU P1.6

    DB7 EQU P1.7

    EN EQU P3.7

    RS EQU P3.6

    RW EQU P3.5

    DATA EQU P1

    Having established the above equates, we may now refer to our I/O lines by their 44780name. For example, to set the RW line high (1), we can execute the following insutrction:

    SETB RWHANDLING THE EN CONTROL LINE

    As we mentioned above, the EN line is used to tell the LCD that you are ready for it toexecute an instruction that you've prepared on the data bus and on the other control lines.Note that the EN line must be raised/lowered before/after each instruction sent to theLCD regardless of whether that instruction is read or write, text or instruction. In short,you must always manipulate EN when communicating with the LCD. EN is the LCD's

  • 8/6/2019 LCD Backgorund

    3/40

    way of knowing that you are talking to it. If you don't raise/lower EN, the LCD doesn'tknow you're talking to it on the other lines.

    Thus, before we interact in any way with the LCD we will always bring the EN line lowwith the following instruction:

    CLR EN

    And once we've finished setting up our instruction with the other control lines and databus lines, we'll always bring this line high:

    SETB EN

    The line must be left high for the amount of time required by the LCD as specified in itsdatasheet. This is normally on the order of about 250 nanoseconds, but check thedatasheet. In the case of a typical 8051 running at 12 MHz, an instruction requires 1.08microseconds to execute so the EN line can be brought low the very next instruction.However, faster microcontrollers (such as the DS89C420 which executes an instructionin 90 nanoseconds given an 11.0592 Mhz crystal) will require a number of NOPs to

    create a delay while EN is held high. The number of NOPs that must be inserted dependson the microcontroller you are using and the crystal you have selected.

    The instruction is executed by the LCD at the moment the EN line is brought low with afinal CLR EN instruction.

    Programming Tip: The LCD interprets and executes our command at the instantthe EN line is brought low. If you never bring EN low, your instruction will neverbe executed. Additionally, when you bring EN low and the LCD executes yourinstruction, it requires a certain amount of time to execute the command. The timeit requires to execute an instruction depends on the instruction and the speed of

    the crystal which is attached to the 44780's oscillator input.

    CHECKING THE BUSY STATUS OF THE LCD

    As previously mentioned, it takes a certain amount of time for each instruction to beexecuted by the LCD. The delay varies depending on the frequency of the crystalattached to the oscillator input of the 44780 as well as the instruction which is beingexecuted.

    While it is possible to write code that waits for a specific amount of time to allow theLCD to execute instructions, this method of "waiting" is not very flexible. If the crystal

    frequency is changed, the software will need to be modified. Additionally, if the LCDitself is changed for another LCD which, although 44780 compatible, requires more timeto perform its operations, the program will not work until it is properly modified.

    A more robust method of programming is to use the "Get LCD Status" command todetermine whether the LCD is still busy executing the last instruction received.

  • 8/6/2019 LCD Backgorund

    4/40

    The "Get LCD Status" command will return to us two tidbits of information; theinformation that is useful to us right now is found in DB7. In summary, when we issuethe "Get LCD Status" command the LCD will immediately raise DB7 if it's still busyexecuting a command or lower DB7 to indicate that the LCD is no longer occupied. Thusour program can query the LCD until DB7 goes low, indicating the LCD is no longer

    busy. At that point we are free to continue and send the next command.

    Since we will use this code every time we send an instruction to the LCD, it is useful tomake it a subroutine. Let's write the code:

    WAIT_LCD:

    CLR EN;Start LCD commandCLR RS;It's a commandSETB RW;It's a read commandMOV DATA,#0FFh;Set all pins to FF initiallySETB EN;Clock out command to LCD

    MOV A,DATA;Read the return valueJB ACC.7,WAIT_LCD;If bit 7 high, LCD still busyCLR EN;Finish the commandCLR RW;Turn off RW for future commandsRET

    Thus, our standard practice will be to send an instruction to the LCD and then call ourWAIT_LCD routine to wait until the instruction is completely executed by the LCD.This will assure that our program gives the LCD the time it needs to execute instructionsand also makes our program compatible with any LCD, regardless of how fast or slow itis.

    Programming Tip: The above routine does the job of waiting for the LCD, but were it tobe used in a real application a very definite improvement would need to be made: aswritten, if the LCD never becomes "not busy" the program will effectively "hang,"waiting for DB7 to go low. If this never happens, the program will freeze. Of course, thisshould never happen and won't happen when the hardware is working properly. But in areal application it would be wise to put some kind of time limit on the delay--forexample, a maximum of 256 attempts to wait for the busy signal to go low. This wouldguarantee that even if the LCD hardware fails, the program would not lock up.

    INITIALIZING THE LCD

    Before you may really use the LCD, you must initialize and configure it. This isaccomplished by sending a number of initialization instructions to the LCD.

    The first instruction we send must tell the LCD whether we'll be communicating with itwith an 8-bit or 4-bit data bus. We also select a 5x8 dot character font. These two optionsare selected by sending the command 38h to the LCD as a command. As you will recallfrom the last section, we mentioned that the RS line must be low if we are sending a

  • 8/6/2019 LCD Backgorund

    5/40

    command to the LCD. Thus, to send this 38h command to the LCD we must execute thefollowing 8051 instructions:

    CLR RS

    MOV DATA,#38h

    SETB ENCLR EN

    LCALL WAIT_LCD

    Programming Tip: The LCD command 38h is really the sum of a number of option bits.The instruction itself is the instruction 20h ("Function set"). However, to this we add thevalues 10h to indicate an 8-bit data bus plus 08h to indicate that the display is a two-linedisplay.

    We've now sent the first byte of the initialization sequence. The second byte of theinitialization sequence is the instruction 0Eh. Thus we must repeat the initialization code

    from above, but now with the instruction. Thus the the next code segment is:CLR RSMOV DATA,#0Eh

    SETB EN

    CLR EN

    LCALL WAIT_LCD

    Programming Tip: The command 0Eh is really the instruction 08h plus 04h to turn theLCD on. To that an additional 02h is added in order to turn the cursor on.

    The last byte we need to send is used to configure additional operational parameters of

    the LCD. We must send the value 06h.CLR RSMOV DATA,#06h

    SETB EN

    CLR EN

    LCALL WAIT_LCD

    Programming Tip: The command 06h is really the instruction 04h plus 02h to configurethe LCD such that every time we send it a character, the cursor position automaticallymoves to the right.

    So, in all, our initialization code is as follows:INIT_LCD:CLR RS

    MOV DATA,#38h

    SETB EN

    CLR EN

    LCALL WAIT_LCD

    CLR RS

  • 8/6/2019 LCD Backgorund

    6/40

  • 8/6/2019 LCD Backgorund

    7/40

    SETB RS

    MOV DATA,A

    SETB EN

    CLR EN

    LCALL WAIT_LCD

    RETThe WRITE_TEXT routine that we just wrote will send the character in the accumulatorto the LCD which will, in turn, display it. Thus to display text on the LCD all we need todo is load the accumulator with the byte to display and make a call to this routine. Prettyeasy, huh?

    A "HELLO WORLD" PROGRAM

    Now that we have all the component subroutines written, writing the classic "HelloWorld" program--which displays the text "Hello World" on the LCD is a relatively trivialmatter. Consider:

    LCALL INIT_LCD

    LCALL CLEAR_LCD

    MOV A,#'H'

    LCALL WRITE_TEXT

    MOV A,#'E'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'O'LCALL WRITE_TEXT

    MOV A,#' '

    LCALL WRITE_TEXT

    MOV A,#'W'

    LCALL WRITE_TEXT

    MOV A,#'O'

    LCALL WRITE_TEXT

    MOV A,#'R'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'D'

    LCALL WRITE_TEXT

    The above "Hello World" program should, when executed, initialize the LCD, clear theLCD screen, and display "Hello World" in the upper left-hand corner of the display.

    CURSOR POSITIONING

  • 8/6/2019 LCD Backgorund

    8/40

    The above "Hello World" program is simplistic in the sense that it prints its text in theupper left-hand corner of the screen. However, what if we wanted to display the word"Hello" in the upper left-hand corner but wanted to display the word "World" on thesecond line at the tenth character? This sounds simple--and actually, it is simple.However, it requires a little more understanding of the design of the LCD.

    The 44780 contains a certain amount of memory which is assigned to the display. All thetext we write to the 44780 is stored in this memory, and the 44780 subsequently readsthis memory to display the text on the LCD itself. This memory can be represented withthe following "memory map":

    In the above memory map, the area shaded in blue is the visible display. As you can see,it measures 16 characters per line by 2 lines. The numbers in each box is the memory

    address that corresponds to that screen position.

    Thus, the first character in the upper left-hanad corner is at address 00h. The followingcharacter position (character #2 on the first line) is address 01h, etc. This continues untilwe reach the 16th character of the first line which is at address 0Fh.

    However, the first character of line 2, as shown in the memory map, is at address 40h.This means if we write a character to the last position of the first line and then write asecond character, the second character will not appear on the second line. That is becausethe second character will effectively be written to address 10h--but the second line beginsat address 40h.

    Thus we need to send a command to the LCD that tells it to position the cursor on thesecond line. The "Set Cursor Position" instruction is 80h. To this we must add the addressof the location where we wish to position the cursor. In our example, we said we wantedto display "World" on the second line on the tenth character position.

    Referring again to the memory map, we see that the tenth character position of the secondline is address 4Ah. Thus, before writing the word "World" to the LCD, we must send a"Set Cursor Position" instruction--the value of this command will be 80h (the instructioncode to position the cursor) plus the address 4Ah. 80h + 4Ah = CAh. Thus sending thecommand CAh to the LCD will position the cursor on the second line at the tenth

    character position:

    CLR RS

    MOV DATA,#0CAh

    SETB EN

    CLR EN

    LCALL WAIT_LCD

  • 8/6/2019 LCD Backgorund

    9/40

    The above code will position the cursor on line 2, character 10. To display "Hello" in theupper left-hand corner with the word "World" on the second line at character position 10just requires us to insert the above code into our existing "Hello World" program. Thisresults in the following:

    LCALL INIT_LCD

    LCALL CLEAR_LCDMOV A,#'H'

    LCALL WRITE_TEXT

    MOV A,#'E'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'O'

    LCALL WRITE_TEXT

    CLR RSMOV DATA,#0CAh

    SETB EN

    CLR EN

    LCALL WAIT_LCD

    MOV A,#'W'

    LCALL WRITE_TEXT

    MOV A,#'O'

    LCALL WRITE_TEXT

    MOV A,#'R'

    LCALL WRITE_TEXT

    MOV A,#'L'

    LCALL WRITE_TEXT

    MOV A,#'D'

    LCALL WRITE_TEXT

    SUMMARY

    This tutorial has presented the underlying concepts of programming an LCD display.Obviously it has not addresses all issues. The 44780 LCD controller offers many otherfunctions which are accessed using other commands, and some of the commands alreadypresented include other options that were not discussed here. However, this tutorialshould get you going in the right direction.

  • 8/6/2019 LCD Backgorund

    10/40

    Interfacing to 8051I/O ports.

    SWITCH ON I/O PORTS

    Good CircuitIt is always best connecting the switch to ground with a pull-up resistor as shown in the

    "Good" circuit. When the switch is open, the 10k resistor supplies very small current needed

    for logic 1. When it is closed, the port pin is short to ground. The voltage is 0V and all thesinking current requirement is met, so it is logic 0. The 10k resistor will pass 0.5 mA (5

    Volt/10k ohm). Thus the circuits waste very little current in either state. The drawback is that

    the closure of switch gives logic 0 and people like to think of a switch closure gives logic 1. But

    this is not a matter because it is easy to handle in software.

    Fair circuitThe "Fair" circuit requires that the pull-down resistor be very small. Otherwise, the pin will rise

    above 0.9V when the resistor passes the 1.6mA sinking current. When the switch is closed,

    the circuit waste a large current since virtually no current flows into the pin. The only

    advantage is that a switch closure gives logic 1.

    Poor circuitIn the "Poor" circuit, the logic 1 is stable when the switch is closed. But when the switch is

    open, the input floats to a noise-sensitive high rather than a low. An open TTL pin is usually

    read as logic 1 but the pin may picks up noise like an antenna.

    To conclude, driving a TTL input should always consider current sinking (pulling input to 0V).

    LED ON I/O PORTS

    Since TTL outputs is designed to feed multiple TTL inputs, they are good at current sinking but

    poor at current sourcing. The Standard TTL can sink up to 16mA and source 250uA. The LS

    logic family can sink 8mA and source 100uA. The 8051 port pin can sink 1.6mA (3.2mA for

  • 8/6/2019 LCD Backgorund

    11/40

    port 0) and source 60uA. Therefore, if you drive significant current, try to arrange your circuits

    to use current sinking.

    Unlike diodes, Light-emitting diodes have a forward voltage drop from 1.7 to 2.5 volts and

    most of them flow a forward current 20mA.

    Poor circuitsince the TTL output can't source above 1mA so the LED will be very dim.

    Fair circuitThe LED will conduct heavily at about 2V and the extra 3V has to be dropped in the TTL

    circuitry. This causes high power dissipation in the TTL or the LED fails.

    Good circuitThe resistor limits the current. The resistance can be calculated by assuming its voltage is

    about 2.5V and the TTL output is 0.9V. For 2.2V LED, 1.9V is across the resistor so the

    220ohm would limit the current to 8.6mA (1.9/220). For 1.7V LED, 2.4V is across the resistor

    so it would limit the current to 10.9mA (2.4/220). The resistor should not less than 100ohm or

    the LED would fail.

    CODE EXAMPLE

    Connection -Switch -P1.0 , LED - P2.0Condition - Turn on LED when switch is pressed.

    ASSEMBLY LANGUAGE C LANGUAG

    SETB P1.0 ; input pin.LOOP:JB P2.0, LOOP ; not grounded then stay in loopCLR P0.0 ;To clear pin P0.0 when P1.0 is at 0 v

    BIT button p1.0 / * Using BIBIT LED p2.0void main ( ){while (1) {

    LED = button ; /* Note LED=}}

    RELAY ON I/O PORT (2CO Relay)

  • 8/6/2019 LCD Backgorund

    12/40

    In A, NPN transistor (say a BC337 or BC338) is being used to control a relay with a 5 V coil.

    Series base resistor R1 is used to set the base current for Q1, so that the transistor is driven

    into saturation (fully turned on) when the relay is to be energized. That way, the transistor will

    have minimal voltage drop, and hence dissipate very little power as well as delivering most of

    the 5V to the relay coil.

    How do work out the value of R1?.

    Let us say RLY1 needs 50mA of coil current to pull in and hold reliably, and has a resistance of

    24 Ohms so it draws this current from 5V. Our BC337/338 transistor will need enough base

    current to make sure it remains saturated at this collector current level. To work this out, we

    simply make sure that the base current is greater than this collector current divided by the

    transistors minimum DC current gain hFE. So as the BC337/338 has a minimum hFE of 100

    (at 100mA), we'll need to provide it with at least 50mA/100 = 0.5mA of base current.

    In practice, you give it roughly double this value, say 1mA of base current, just to make sure

    it does saturate. So if your resistance will be

    TTL Logic High Voltage (Min) /1ma ( 1K approx)

    EXAMPLE

  • 8/6/2019 LCD Backgorund

    13/40

    Connection -Port 0 is connected to eight LEDs, each of them is connected to 5V through a

    330ohm resistor. Port 1 is connected to a DIP switch and a 10Kohm resistor

    Condition - Corresponding led should light up when switch pressed , i.e. if Switch at 1.0 is

    pressed -> LED at P0.0 should light up.

    CODE EXAMPLE

    ASSEMBLY LANGUAGE C LANGUAGE

    LOOP:mov p1,#0ffh ; To configure port for input.mov a,p1mov p0 ,asjmp LOOP ; Stay in infinite loop

    . 1.

    void main() {while (1) {

    P0 = P1; /* Note P1=P0 wi

    }

  • 8/6/2019 LCD Backgorund

    14/40

    }

    2.

    voided main() {char port_value;while (1) {

    port_value = P1;P0 = port_value;

    }}

    USING ULN

    Another option for driving relays would be to use a high-voltage, high-current, Darlingtonarray driver IC such as the ULN2803. The ULN2803 can directly interface to the data outputs

    of the 8051 pins, and provides much higher drive-current. The ULN2803 also has internal

    diode protection that eliminates the need for the fly-back diode as shown in the above relay

    driver schematics. You can connect 8 relay using this IC.

    So I think ULN is better choice if you have more than 3 relay. ( Simple design of circuit & PCB

    as well ! )

    Keypad Interfacing.................................................................................................................

    ..................

  • 8/6/2019 LCD Backgorund

    15/40

  • 8/6/2019 LCD Backgorund

    16/40

    JNC MATCH ;if zero, get the ASCIIcode

    INC DPTR ;point to next col. addressSJMP FIND ;keep searching

    MATCH: CLR A ;set A=0 (match is found)

    MOVC A,@A+DPTR ;get ASCII code from tableMOV P0,A ;display pressed keyLJMP K1

    ;ASCII LOOK-UP TABLE FOR EACH ROW

    ORG 300HKCODE0: DB '0','1','2','3' ;ROW 0KCODE1: DB '4','5','6','7' ;ROW 1KCODE2: DB '8','9','A','B' ;ROW 2KCODE3: DB 'C','D','E','F' ;ROW 3

    END

    assembly language.

  • 8/6/2019 LCD Backgorund

    17/40

    The 4x4 Keypad has 16 keys and requires a single PORT or 8 I/O lines. Port 3 has beendesigned to handle keypad, LCD Data Bus D7-D0 is connected to PORT 1, while

    (Enable) EN is connected to P2.0

    (Register Select Command or Data Register) RS is connected to P2.1

    (Read/Write) RW is connected to P2.2

    The LCD is based on Hitachi HD44780 Controller and datasheet is present online.

    Working:

    To check for the keystroke, a polling method has been used.

    PORT 3.0 Key 1 Key 2 Key 3 Key 4

    PORT3.1 Key 5 Key 6 Key 7 Key 8

    PORT3.2 Key 9 Key 10 Key 11 Key 12

    PORT3.3 Key 13 Key 14 Key 15 Key 16

    PORT3.4 PORT3.5 PORT3.6 PORT3.7

    The connections are similar as shown over here. Now consider this, if I select the firstcolumn only, it has 4 keys, 1, 5,9,13. If a change of value (i.e. Binary 1 or 0) is made anyone of these keys, it can be decoded and suitable message is displayed on the LCD. Thisis exactly what happens. Initially all the I/O lines are pulled high, then during Key Scan,

  • 8/6/2019 LCD Backgorund

    18/40

    every column linked is held low for a little time. If during that time a Key is pressed inthat column a row I/O lines is also held low, thus the keystroke can be captured.

    The obvious question would be what if we press the key on a particular column and atthat particular moment that column has not been pulled low, thus making no signal

    changes?

    The answer is simple, the microcontroller runs quite fast, even a convention 89c51 inwhich the internal frequency= external frequency clock/12 can achieve 2 MIPS at24MHz. That is 2 Million instructions Per Second. This method is not foolproof, it has adrawback, while the Key Scan, It cannot perform other cumbersome operations whichmay take time and a Key Stroke could be missed. The program will work very well forsmall operations like activating a small relay or LED when a Key is pressed, but forpeople who want their systems to be near to perfect they may utilize other method.

    Circuit Diagram

  • 8/6/2019 LCD Backgorund

    19/40

    Each I/O line on PORT 1 should be pulled high with 4.7K Resistors

    Program:

    EN equ P2.0

    RS equ P2.1

    RW equ P2.2

    mov A,#38H ; Setting Up the LCD

    lcall command

    mov A,#0EH ; Display On

    lcall command

    mov A,#06H ; Entry Mode

    lcall command

    mov a,#82H

    lcall command

    lcall disp ; Function Disp Called

    mov a,#02H ; Setting DDRAM Address to Home position

    lcall command

    lcall delay1

    ; Displays BOTSKOOL SHOBHIT ON FIRST LINE OF LCD

    mov a,#'B'

    lcall datw

    NOP

  • 8/6/2019 LCD Backgorund

    20/40

    mov a,#'0'

    lcall datw

    NOP

    mov a,#'T'

    lcall datw

    mov a,#'S'

    lcall datw

    NOP

    mov a,#'K'

    lcall datw

    NOP

    mov a,#'0'

    lcall datw

    NOP

    mov a,#'0'

    lcall datw

    NOP

    mov a,#'L'

    lcall datw

    NOP

    mov a,#' '

    lcall datw

    NOP

  • 8/6/2019 LCD Backgorund

    21/40

    mov a,#'S'

    lcall datw

    NOP

    mov a,#'H'

    lcall datw

    NOP

    mov a,#'O'

    lcall datw

    NOP

    mov a,#'B'

    lcall datw

    NOP

    mov a,#'H'

    lcall datw

    NOP

    mov a,#'I'

    lcall datw

    NOP

    mov a,#'T'

    lcall datw

    MOV A,#255 ; Moving Value 255 to PORT 3

    MOV P3,A

    ; Keypad Scan Begins

  • 8/6/2019 LCD Backgorund

    22/40

    sd:

    lcall delay1

    lcall key1

    lcall delay

    lcall key2

    lcall delay

    lcall key3

    lcall delay

    lcall key4

    lcall delay

    lcall sd

    ; Function to Send Commands to LCD

    command:

    clr RW

    clr RS

    setB EN

    MOV P1,A

    lcall delay

    clr EN

  • 8/6/2019 LCD Backgorund

    23/40

    RET

    ; Function to Clear the DDRAM Content

    clear:

    mov A,#01H

    lcall command

    lcall delay

    mov A,#02H ; Set The DDRAM Address to Home Position

    lcall command

    lcall delay

    RET

    ; Function to Display Data on LCD Screen

    datw:

    SETB RS

    clr RW

    SETB EN

    MOV P1,A

    lcall delay

    clr EN

    RET

    ;Function to Display The Key Pressed

    datw1:

  • 8/6/2019 LCD Backgorund

    24/40

    lcall delay1

    lcall disp

    lcall delay1

    MOV A,R7

    lcall datw

    RET

    ; Generating Small Delay

    delay:

    mov r0,#255

    loop: DJNZ r0,loop;

    RET

    ; Generating a Bigger Delay

    delay1:

    mov r1,#255

    loop1: mov r3,#120

    loop2: djnz r3,loop2

    djnz r1,loop1

    RET

    ; Checking for Key Press on The First Column of 4x4 Matrix

  • 8/6/2019 LCD Backgorund

    25/40

    KEY1:

    MOV A,r5

    MOV r6,A

    clr p3.4

    MOV A,p3

    ANL A,#0FH

    MOV r2,A

    cjne r2,#14,n1

    MOV r7,#'1'

    lcall datw1

    lcall delay1

    n1: cjne r2,#13,n2

    mov r7,#'5'

    lcall datw1

    lcall delay1

    n2: cjne r2,#11,n3

    mov r7,#'9'

    lcall datw1

    lcall delay1

    n3: cjne r2,#7,n4

    mov r7,#'D'

  • 8/6/2019 LCD Backgorund

    26/40

    lcall datw1

    lcall delay1

    n4: lcall delay1

    SETB P3.4

    RET

    ; Checking for Key Press on the Second Column of 4x4 Matrix

    KEY2:

    clr p3.5

    MOV A,p3

    ANL A,#0FH

    MOV r2,A

    cjne r2,#14,q1

    mov r7,#'2'

    lcall datw1

    lcall delay1

    q1: cjne r2,#13,q2

    mov r7,#'6'

    lcall datw1

    lcall delay1

    q2: cjne r2,#11,q3

    mov r7,#65; A=65

  • 8/6/2019 LCD Backgorund

    27/40

    lcall datw1

    lcall delay1

    q3: cjne r2,#7,q4

    mov r7,#'E'

    lcall datw1

    lcall delay1

    q4: lcall delay

    SETB p3.5

    RET

    ; Checking for Key Press On The Third Column of 4x4 Matrix

    KEY3:

    clr p3.6

    MOV A,p3

    ANL A,#0FH

    MOV r2,A

    cjne r2,#14,w1

    mov r7,#'3'

    lcall datw1

    lcall delay1

    w1: cjne r2,#13,w2

  • 8/6/2019 LCD Backgorund

    28/40

    mov r7,#'7'

    lcall datw1

    lcall delay1

    w2: cjne r2,#11,w3

    mov r7,#'B'

    lcall datw1

    lcall delay1

    w3: cjne r2,#7,w4

    mov r7,#'F'

    lcall datw1

    lcall delay1

    w4: lcall delay1

    SETB p3.6

    RET

    ; Checking for Key Press on the Fourth Column of 4x4 Matrix

    KEY4:

    clr p3.7

    MOV A,p3

    ANL A,#0FH

    MOV r2,A

    cjne r2,#14,e1

    mov r7,#'4'

  • 8/6/2019 LCD Backgorund

    29/40

    lcall datw1

    lcall delay1

    e1: cjne r2,#13,e2

    mov r7,#'8'

    lcall datw1

    lcall delay1

    e2: cjne r2,#11,e3

    mov r7,#'C'

    lcall datw1

    lcall delay1

    e3: cjne r2,#7,e4

    mov r7,#'G'

    lcall datw1

    lcall delay1

    e4: lcall delay1

    SETB p3.7

    RET

    disp:

    mov a,#0c0H ; Setting DDRAM Address on Second Line

    lcall command

    ; Clearing the Previous Key Pressed Information from Screen

  • 8/6/2019 LCD Backgorund

    30/40

    mov a,#' '

    lcall datw

    mov a,#' '

    lcall datw

    mov a,#' '

    lcall datw

    mov a,#' '

    lcall datw

    mov a,#' '

    lcall datw

    mov a,#' '

    lcall datw

    mov a,#0c0H ; Setting DDRAM Address on Second Line To Display Key Pressed

    lcall command

    ; Display "KEY" and Pressed Information

    mov a,#' '

    lcall datw

    mov a,#'K'

    lcall datw

    mov a,#'E'

    lcall datw

  • 8/6/2019 LCD Backgorund

    31/40

    mov a,#'Y'

    lcall datw

    mov a,#' '

    lcall datw

    RET

    END

    The code was written when I was learning assembly language myself and therefore thecode is not optimized, but it is easy to understand if someone is willing to check the

    instruction set.

    People who want to optimize the code may wish to look into the DPTR Register andAddressing Modes Theory.

    A View of the Simulation

  • 8/6/2019 LCD Backgorund

    32/40

    The 7-12V DC Input had to be removed in this diagram, because that cannot be acceptedas the Power Source in the Simulation, so do not get confused.

  • 8/6/2019 LCD Backgorund

    33/40

    First Program, Flash an LED at P1.0; www.8051projects.info;; Hardware Notes:; AT89C51 Running at 12 MHz; P1.0 is the LED (to light, it is pulled down)

    ORG 00H ; Execution Starts HereFLASH: CPL P1.0 ; Turn on/off the LED

    ACALL DELAY ; call one second delayAJMP FLASH ; repeat forever

    DELAY: MOV R1,#0FFHREPEAT: MOV R2,#0FFH

    DJNZ R2,$DJNZ R1,REPEATRETEND

    KEYLEFT BIT P1.0KEYRIGHT BIT P1.1LEDLEFT BIT P1.2LEDRIGHT BIT P1.3 ;Bit Definition

    ORG 00HSETB KEYLEFTSETB KEYRIGHT ;For reading, the first to write a

    LOOP: MOV C,KEYLEFTMOV LEDLEFT,CMOV C,KEYRIGHTMOV LEDRIGHT,CLJMP LOOPEND

    ; Running leds at P1; www.8051projects.info;; Hardware Notes:; AT89C51 Running at 12 MHz; Connect 8 leds on the port P1

    ORG 00HLOOP: MOV A, #0FEH ;Initial value

    MOV R2, #8 ;Design valueOUTPUT: MOV P1, A ;P1 port output to send

    RL A ;Data shiftACALL DELAYDJNZ R2, OUTPUTLJMP LOOP

    DELAY: MOV R6, #0 ;Delay subroutineMOV R7, #0

    DELAYLOOP:

  • 8/6/2019 LCD Backgorund

    34/40

    DJNZ R6, DELAYLOOPDJNZ R7, DELAYLOOPRETEND

    Assembly Language program for LCD code

    In this post some routine in Assembly language are written to interface lcd with

    microcontroller 8051.Most projects you create with the 8051 CPU or any othermicrocontroller require some form of display. The display may be LED or LCD. Butnow use of LCD is increasing/ The most common way to accomplish this is with theLCD (Liquid Crystal Display). LCDs have become a cheap and easy way to get textdisplay for an embedded system Common displays are set up as 16 to 20 characters by 1to 4 lines. variate of LCD are available and most of them can work on thees waysdescribes in the sub routines.

    Data to be Displayed on LCD using micro controller requires following set ofinstructions in the form of code as follows.

    lcd_datadisplay: // this is a part of main program call sub routine, thefunction of this sub routine is to display //data on lcd.SETB RS //Telling the LCD that the data which is being send is to be displayedMOV P1,A //Character to be displayed is in AccSETB EN // the enable pin of lcd is set to logic oneCLR EN //High to Low pulse on EN to latch the dataCALL DELAY //Delay so that LCD finishes its internal operationsret // return from this routine is called

    Command or Special Instruction.lcd_command: // in this sub-routine of lcd program, how different commands are sent to

    lcd is shownCLR RS //Telling the LCD that the data which is being send is a commandMOV P1,A //Character to be displayed is in AccSETB ENCLR EN //High to Low pulse on EN to latch the dataCALL DELAY //Delay so that LCD finishes its internal operationsret // returning to the main code from where this sub-routine was called

    http://microcontroller51.blogspot.com/2010/12/assembly-language-program-for-lcd-code.htmlhttp://microcontroller51.blogspot.com/2010/12/assembly-language-program-for-lcd-code.html
  • 8/6/2019 LCD Backgorund

    35/40

    Busy flag checkingready: // In this sub-routine the busy flag is checkedsetb P1.7 ;D7 as inputclr P3.6 ;RS=0 cmd

    setb P3.5 ;RW=1 for readagain:setb P3.7 ;H->L pulse on Eclr P3.7jb P1.7, againret // returning back to main program where this function is called

    Data write Routinedata: // in this sub-routine how data will be written on lcd is shownmov P1, A ;//move acc. data to portsetb P3.6 ;RS=1 data

    clr P3.5 ;RW=0 for writesetb P3.7 ;H->L pulse on Eclr P3.7lcall readyret // end of this sub-routine

    Command write Routinecommand: // this is another sub-routine showing how to write commands on lcd, you canuse any of these //cammand subroutinemov P1, A ;move acc. data to portclr P3.6 ;RS=0 for cmdclr P3.5 ;RW=0 for writesetb P3.7 ;H->L pulse on Eclr P3.7lcall readyret

    Initialization of LCDinitialization: // in this sub-routine initialization of LCD is described

    mov A, #38H ; Initialize, 2-lines, 5X7 matrix.lcall Commandmov A, #0EH ; LCD on, cursor onlcall Commandmov A, #01H ; Clear LCD Screenlcall Commandmov A, #06H ; Shift cursor rightlcall Command

    Display clear

  • 8/6/2019 LCD Backgorund

    36/40

    clear: // this is sub-routine to clear the display of LCDsetb p3.7 ;enable ENclr 3.6 ;RS=0 for cmd.mov DATA,#01hclr p3.7 ;disable EN

    lcall readyRET

    Note- As we need to clear the LCD frequently and not the whole initialisation , it is betterto use this routine separately.

    Displaying "HI Friends"

    lcall initializationlcall clear

    mov A,#'H'acall datamov A,#'I'lcall datamov A,#'F'lcall datamov A,#'r'lcall datalcall datamov A,#'i'lcall datamov A,#'e'lcall datamov A,#'n'lcall datamov A,#'d'lcall datamov A,#'s'ret

    Now following is complete ASSEMBLY LANGUAGEcode to show something on LCDlcall Initializationlcall clearmov a,#'H'lcall datamov a,#'I'lcall datamov a,#8ahlcall command

  • 8/6/2019 LCD Backgorund

    37/40

    mov a,#'8'lcall datamov a,#'0'lcall datamov a,#'5'

    lcall datamov a,#'1'lcall datamov a,#'M'lcall datamov a,#'C'lcall dataend

    Assembly Language Code

    ; Interfacing LCD 16x2 in 4-bit mode.; Port0 to higher nibble data pins of LCD; Crystal 3.579545 MHz

    ; AT89C51

    ;P2.0 to RS pin

    ;P2.1 to Enable Pin

    ORG 0000HAJMP MAINORG 0030HMAIN:

    MOV SP,#60H ;STACK POINTERACALL LCD_INIT ;Initialize lcdMOV DPTR,#MESSAGE1

    CALL LCD_STRING ;Display message on LCDCALL NEXT_LINE ;Place cursor to;second LineMOV DPTR,#MESSAGE2CALL LCD_STRING ;Display message on LCDHERE: AJMP HERE

    LCD_INIT: ;initialize LCD in 4-bit modeANL P0,#0F0H

  • 8/6/2019 LCD Backgorund

    38/40

    CALL LOOPMOV DPTR,#LCDCODEMOV A,#0HMOV R6,#0HMOV R7,#0H

    CLR P2.0 ;RS COMMANDNEXT: ;8-bit code is split into two 4-bit nibbles.INC R6MOVC A,@A+DPTRMOV R7,AANL A,#0F0HSWAP AANL P0,#0F0HORL P0,AACALL ENABLE ;PULSE E sending first nibbleMOV A,R7

    ANL A,#0FHANL P0,#0F0HORL P0,AACALL ENABLE ;PULSE E sending second nibbleMOV A,R6CJNE R6,#09H,NEXTRET

    LCD_STRING:

    MOV P0,#00HSETB P2.0 ;RS DATAMOV A,#00HMOV R6,#00HNC: ;checks the end of message stringMOVC A,@A+DPTRCJNE A,#2FH,NC1RETNC1:

    LCALL LCD_WRITEINC R6MOV A,R6AJMP NC

    LCD_WRITE:

    SETB P2.0 ;RS DATACALL LORET

    NEXT_LINE:

    MOV P0,#00H

  • 8/6/2019 LCD Backgorund

    39/40

    CLR P2.0 ;RS COMMANDMOV A,#0C0HCALL LORET

    LCD_CLEAR: ;This Subroutine is used to clear LCDCALL DELAYLANL P0,#00HMOV A,#01HCLR P2.0 ; RS commandLO: ;8-bit code is split into two 4-bit nibbles.MOV R7,AANL A,#0F0HSWAP AANL P0,#0F0HORL P0,A

    CALL ENABLEMOV A,R7ANL A,#0FHANL P0,#0F0HORL P0,ACALL ENABLERET

    ENABLE: ;Give High-to-low pulse at enable pinSETB P2.1CALL DELAYLCLR P2.1CALL DELAYLRET

    ;With respect to crystal frequency 3.579 MHzDELAYL: ; 5ms DELAYSETB PSW.4 ; SELECT BANK 2MOV R7,#25HDH:

    MOV R6,#60DJNZ R6,$DJNZ R7,HDHCLR PSW.4 ;DEFAULT BANKRET

    LOOP: ;1 SEC DELAYMOV R7,#100

  • 8/6/2019 LCD Backgorund

    40/40

    LOOP1:

    CALL DELAYLCALL DELAYLDJNZ R7,LOOP1RET

    ;LCD INITIALIZING CODE (DO NOT DISTURB THIS)

    LCDCODE:

    DB 02HDB 02HDB 02HDB 28HDB 28HDB 28HDB 0CHDB 06HDB 01H

    ;DATA TO BE DISPLAYED

    ;Maximum message length = 16 characters.

    ;To notify end of message place '/' at the end.

    MESSAGE1: DB "LCD INTERFACING /" ;Change Message1

    MESSAGE2: DB " IT IS EASY /" ;Change Message2

    END