8051 CODE

download 8051 CODE

of 28

Transcript of 8051 CODE

  • 8/12/2019 8051 CODE

    1/28

    8051 CODE

    Delay using 8051 timer.

    The 8051 microcontroller has two independent 16 bit up counting timers named Timer 0 and Timer 1 and this article is about

    generating time delays using the 8051 timers. Generating delay using pure software loops have been already discussed here but such

    delays are poor in accuracy and cannot be used in sensitive applications. Delay using timer is the most accurate and surely the best

    method.

    A timer can be generalized as a multi-bit counter which increments/decrements itself on receiving a clock signal and produces an

    interrupt signal up on roll over. When the counter is running on the processors clock , it is called a Timer, which counts a

    predefined number of processor clock pulses and generates a programmable delay. When the counter is running on an external

    clock source (may be a periodic or aperiodic external signal) it is called a Counter itself and it can be used for counting external

    events.

    In 8051, the oscillator output is divided by 12 using a divide by 12 network and then fed to the Timer as the clock signal. That means

    for an 8051 running at 12MHz, the timer clock input will be 1MHz. That means the the timer advances once in every 1uS and the

    maximum time delay possible using a single 8051 timer is ( 2^16) x (1S) = 65536S. Delays longer than this can be implemented by

    writing up a basic delay program using timer and then looping it for a required number of time. We will see all these in detail in next

    sections of this article.

    Designing a delay program using 8051 timers.

    While designing delay programs in 8051, calculating the initial value that has to be loaded inot TH and TL registers forms a very

    important thing. Let us see how it is done.

    Assume the processor is clocked by a 12MHz crystal. That means, the timer clock input will be 12MHz/12 = 1MHz That means, the time taken for the timer to make one increment = 1/1MHz = 1uS For a time delay of X uS the timer has to make X increments. 2^16 = 65536 is the maximim number of counts possible for a 16 bit timer. Let TH be the value value that has to be loaded to TH registed and TL be the value that has to be loaded to TL register. Then, THTL = Hexadecimal equivalent of (65536-X) where (65536-X) is considered in decimal.Example.

    Let the required delay be 1000uS (ie; 1mS).

    That means X = 1000

    65536 X = 65536 1000 = 64536.

    64536 is considered in decimal and converting it t0 hexadecimal gives FC18

    That means THTL = FC18

    Therefore TH=FC and TL=18

    Program for generating 1mS delay using 8051 timer.

    The program shown below can be used for generating 1mS delay and it is written as a subroutine so that you can call it anywhere in

    the program. Also you can put this in a loop for creating longer time delays (multiples of 1mS). Here Timer 0 of 8051 is used and it is

    operating in MODE1 (16 bit timer).

    DELAY: MOV TMOD,#00000001B // Sets Timer 0 to MODE1 (16 bit timer). Timer 1 is not used

  • 8/12/2019 8051 CODE

    2/28

    MOV TH0,#0FCH // Loads TH0 register with FCH

    MOV TL0,#018H // LOads TL0 register with 18H

    SETB TR0 // Starts the Timer 0

    HERE: JNB TF0,HERE // Loops here until TF0 is set (ie;until roll over)

    CLR TR0 // Stops Timer 0

    CLR TF0 // Clears TF0 flag

    RET

    The above delay routine can be looped twice in order to get a 2mS delay and it is shown in the program below.

    MAIN: MOV R6,#2D

    LOOP: ACALL DELAY

    DJNZ R6,LOOP

    SJMP MAIN

    DELAY: MOV TMOD,#00000001B

    MOV TH0,#0FCH

    MOV TL0,#018H

    SETB TR0

    HERE: JNB TF0,HERE

    CLR TR0

    CLR TF0

    RET

    Few points to remember while using timers.

    Once timer flag (TF) is set, the programmer must clear it before it can be set again. The timer does not stop after the timer flag is set. The programmer must clear the TR bit in order to stop the timer. Once the timer overflows, the programmer must reload the initial start values to the TH and TL registers to begin counting up

    from.

    We can configure the desired timer to create an interrupt when the TF flag is set. If interrupt is not used, then we have to check the timer flag (TF) is set using some conditional branching instruction. Maximum delay possible using a single 8051 timer is 65536S and minimum is 1S provided that you are using a 12MHz crystal

    for clocking the microcontroller.

    Square wave generation using 8051 timer.

    Square waves of any frequency (limited by the controller specifications) can be generated using the 8051 timer. The technique is very

    simple. Write up a delay subroutine with delay equal to half the time period of the square wave. Make any port pin high and call the

    delay subroutine. After the delay subroutine is finished, make the corresponding port pin low and call the delay subroutine gain.

    After the subroutine is finished , repeat the cycle again. The result will be a square wave of the desired frequency at the selected port

    pin. The circuit diagram is shown below and it can be used for any square wave, but the program has to be accordingly. Programs for

    different square waves are shown below the circuit diagram.

  • 8/12/2019 8051 CODE

    3/28

    Square wave generation using 8051 timer

    1KHz Square wave using 8051 timer.

    MOV P1,#00000000B

    MOV TMOD,#00000001B

    MAIN: SETB P1.0

    ACALL DELAY

    CLR P1.0

    ACALL DELAY

    SJMP MAIN

    DELAY: MOV TH0,#0FEH

    MOV TL0,#00CH

    SETB TR0

    HERE: JNB TF0,HERE

    CLR TR0

    CLR TF0

    SETB P1.0

    RET

    END

    2 KHz Square wave using 8051 timer.

    MOV P1,#00000000B

    MOV TMOD,#00000001B

    MAIN: SETB P1.0

    http://www.circuitstoday.com/wp-content/uploads/2012/11/square-wave-generation-using-8051-timer.png
  • 8/12/2019 8051 CODE

    4/28

    ACALL DELAY

    CLR P1.0

    ACALL DELAY

    SJMP MAIN

    DELAY: MOV TH0,#0FCH

    MOV TL0,#018H

    SETB TR0

    HERE:JNB TF0,HERE

    CLR TR0

    CLR TF0

    SETB P1.0

    RET

    END

    10 KHz square wave using 8051 timer.

    MOV P1,#00000000B

    MOV TMOD,#00000001B

    MAIN: SETB P1.0

    ACALL DELAY

    CLR P1.0

    ACALL DELAY

    SJMP MAIN

    DELAY: MOV TH0,#0FFH

    MOV TL0,#0CEH

    SETB TR0

    HERE:JNB TF0,HERE

    CLR TR0

    CLR TF0

    SETB P1.0

    RET

    END

    Object counter using 8051 microcontroller.

    This article is about a simple object counter/visitor counter using 8051 microcontroller . AT89S51 belonging to the 8051 family is the

    microcontroller used here. This circuit can count the number of objects passing across a line , number of persons passing through a

    gate/door and so on. The can be simply divided into two sections i.e. the sensor section and the display section.

    Sensor.

    The sensor part consists of a ultra bright led (with focus), and LDR, opamp LM324 and the associated passive components. The LED

    is placed on one side of the door and the LDR is placed on the other side so that the light from the LED falls directly on the LDR.As

    you know, the resistance of the LDR has an inverse relationship with the intensity of the light falling on it. The preset resistor R14 is

  • 8/12/2019 8051 CODE

    5/28

    so adjusted that the voltage across the LDR is below 1.5V when it is illuminated. This voltage (labelled A in the circuit diagram) is

    connected to the inverting input of the opamp which is wired as a comparator with reference voltage 1.5V (set using R15 and

    R16).Capacitor C1 is meant for bypassing noise or anything like that which may cause false triggering.Resistor R13 is meant to

    control the current through the LED.

    When the light is falling on the LDR the voltage across it will be less than the reference voltage and so the output of the opamp

    remains high. When the light beam is interrupted, the voltage across the LDR goes above the reference voltage and so the opamp

    output goes low and it indicates a pass.

    Display section.

    The output of the opamp is fed to the INTO (interrupt 0) pin of the microcontroller. The microcontroller is programmed to count the

    number of negative edge pulses received at the INT0 pin and displays it on the three digit seven segment display.

    Circuit diagram.

    Object counter using 8051

    Program.

    ORG 000H

    SJMP INIT

    ORG 003H // starting address of interrupt service routine (ISR)

    ACALL ISR // calls interrupt service routine

    RETI

    INIT: MOV P0,#00000000B

    MOV P3,#11111111B

    MOV P1,#00000000B

    http://www.circuitstoday.com/wp-content/uploads/2013/10/object-counter-8051.png
  • 8/12/2019 8051 CODE

    6/28

    MOV R6,#00000000B

    MOV DPTR,#LUT

    SETB IP.0 // sets highest priority for the interrupt INT0

    SETB TCON.0 // interrupt generated by a falling edge signal at INT0 pin

    SETB IE.0 //enables the external interrupt

    SETB IE.7 //enables the global interrupt control

    MAIN: MOV A,R6

    MOV B,#100D

    DIV AB

    ACALL DISPLAY

    SETB P1.0

    ACALL DELAY

    ACALL DELAY

    MOV A,B

    MOV B,#10D

    DIV AB

    ACALL DISPLAY

    CLR P1.0

    SETB P1.1

    ACALL DELAY

    ACALL DELAY

    MOV A,B

    ACALL DISPLAY

    CLR P1.1

    SETB P1.2

    ACALL DELAY

    ACALL DELAY

    CLR P1.2

    SJMP MAIN

    ISR: INC R6 //interrupt service routine

    RET

    DISPLAY: MOVC A,@A+DPTR // display sub routine

    CPL A

    MOV P0,A

    RET

  • 8/12/2019 8051 CODE

    7/28

    DELAY: MOV R3,#255D // 1mS delay

    LABEL: DJNZ R3,LABEL

    RET

    LUT: DB 3FH

    DB 06H

    DB 5BH

    DB 4FH

    DB 66H

    DB 6DH

    DB 7DH

    DB 07H

    DB 7FH

    DB 6FH

    END

    About the program.

    The program is written so that, it keeps displaying the current value in register R6 on the three digit seven segment display. When

    ever there is a valid negative going pulse (interrupt) at the INT0 pin, the program branches to the interrupt service routine (sub

    routine ISR). Subroutine ISR increments the value in register R6, then jumps back to the MAIN loop and the display gets updated by

    the new value.

    Notes.

    Entire circuit can be powered from a 5V DC supply.

    LDR must be placed in an enclosure so that the light from LED alone falls on it.

    This article is about interfacing a hex key pad to 8051 microcontroller. A clear knowledge on interfacing hex key pad to 8051 is very

    essential while designing embedded system projects which requires character or numeric input or both. For example projects like

    digital code lock, numeric calculator etc. Before going to the interfacing in detail, lets have a look at the hex keypad.

    Hex keypad.

    Hex key pad is essentially a collection of 16 keys arranged in the form of a 44 matrix. Hex key pad usually have keys representing

    numerics 0 to 9 and characters A to F. The simplified diagram of a typical hex key pad is shown in the figure below.

  • 8/12/2019 8051 CODE

    8/28

    Hex keypad

    The hex keypad has 8 communication lines namely R1, R2, R3, R4, C1, C2, C3 and C4. R1 to R4 represents the four rows and C1 to

    C4 represents the four columns. When a particular key is pressed the corresponding row and column to which the terminals of the

    key are connected gets shorted. For example if key 1 is pressed row R1 and column C1 gets shorted and so on. The program identifies

    which key is pressed by a method known as column scanning. In this method a particular row is kept low (other rows are kept high)

    and the columns are checked for low. If a particular column is found low then that means that the key connected between that

    column and the corresponding row (the row that is kept low) is been pressed. For example if row R1 is initially kept low and column

    C1 is found low during scanning, that means key 1 is pressed.

    Interfacing hex keypad to 8051.

    The circuit diagram for demonstrating interfacing hex keypad to 8051 is shown below.Like previous 8051 projects, AT89S51 is the

    microcontroller used here. The circuit will display the character/numeric pressed on a seven segment LED display. The circuit is

    very simple and it uses only two ports of the microcontroller, one for the hex keypad and the other for the seven segment LED

    display.

    http://www.circuitstoday.com/wp-content/uploads/2013/03/hex-keypad.png
  • 8/12/2019 8051 CODE

    9/28

    Interfacing hex keypad to 8051

    The hex keypad is interfaced to port 1 and seven segment LED display is interfaced to port 0 of the microcontroller. Resistors R1 to

    R8 limits the current through the corresponding segments of the LED display. Capacitors C1, C2 and crystal X1 completes the clock

    circuitry for the microcontroller. Capacitor C3, resistor R9 and push button switch S1 forms a debouncing reset mechanism.

    Program.

    ORG 00H

    MOV DPTR,#LUT // moves starting address of LUT to DPTR

    MOV A,#11111111B // loads A with all 1's

    MOV P0,#00000000B // initializes P0 as output port

    BACK:MOV P1,#11111111B // loads P1 with all 1's

    CLR P1.0 // makes row 1 low

    JB P1.4,NEXT1 // checks whether column 1 is low and jumps to NEXT1 if not low

    MOV A,#0D // loads a with 0D if column is low (that means key 1 is pressed)

    ACALL DISPLAY // calls DISPLAY subroutine

    NEXT1:JB P1.5,NEXT2 // checks whether column 2 is low and so on...

    MOV A,#1D

    ACALL DISPLAY

    NEXT2:JB P1.6,NEXT3

    MOV A,#2D

    ACALL DISPLAY

    http://www.circuitstoday.com/wp-content/uploads/2013/03/interfacing-hex-keypad-to-8051.png
  • 8/12/2019 8051 CODE

    10/28

    NEXT3:JB P1.7,NEXT4

    MOV A,#3D

    ACALL DISPLAY

    NEXT4:SETB P1.0

    CLR P1.1

    JB P1.4,NEXT5

    MOV A,#4D

    ACALL DISPLAY

    NEXT5:JB P1.5,NEXT6

    MOV A,#5D

    ACALL DISPLAY

    NEXT6:JB P1.6,NEXT7

    MOV A,#6D

    ACALL DISPLAY

    NEXT7:JB P1.7,NEXT8

    MOV A,#7D

    ACALL DISPLAY

    NEXT8:SETB P1.1

    CLR P1.2

    JB P1.4,NEXT9

    MOV A,#8D

    ACALL DISPLAY

    NEXT9:JB P1.5,NEXT10

    MOV A,#9D

    ACALL DISPLAY

    NEXT10:JB P1.6,NEXT11

    MOV A,#10D

    ACALL DISPLAY

    NEXT11:JB P1.7,NEXT12

    MOV A,#11D

    ACALL DISPLAY

    NEXT12:SETB P1.2

    CLR P1.3

    JB P1.4,NEXT13

    MOV A,#12D

    ACALL DISPLAY

    NEXT13:JB P1.5,NEXT14

    MOV A,#13D

  • 8/12/2019 8051 CODE

    11/28

    ACALL DISPLAY

    NEXT14:JB P1.6,NEXT15

    MOV A,#14D

    ACALL DISPLAY

    NEXT15:JB P1.7,BACK

    MOV A,#15D

    ACALL DISPLAY

    LJMP BACK

    DISPLAY:MOVC A,@A+DPTR // gets digit drive pattern for the current key from LUT

    MOV P0,A // puts corresponding digit drive pattern into P0

    RET

    LUT: DB 01100000B // Look up table starts here

    DB 11011010B

    DB 11110010B

    DB 11101110B

    DB 01100110B

    DB 10110110B

    DB 10111110B

    DB 00111110B

    DB 11100000B

    DB 11111110B

    DB 11110110B

    DB 10011100B

    DB 10011110B

    DB 11111100B

    DB 10001110B

    DB 01111010B

    END

    About the program.

    Firstly the program initializes port 0 as an output port by writing all 0s to it and port 1 as an input port by writing all 1s to it. Then

    the program makes row 1 low by clearing P1.0 and scans the columns one by one for low using JB instruction.If column C1 is found

    low, that means 1 is pressed and accumulator is loaded by zero and DISPLAY subroutine is called. The display subroutine adds the

    content in A with the starting address of LUT stored in DPTR and loads A with the data to which the resultant address points (using

    instruction MOVC A,@A+DPTR). The present data in A will be the digit drive pattern for the current key press and this pattern is

    put to Port 0 for display. This way the program scans for each key one by one and puts it on the display if it is found to be pressed.

    Notes.

  • 8/12/2019 8051 CODE

    12/28

    The 5V DC power supply must be well regulated and filtered. Column scanning is not the only method to identify the key press. You can use row scanning also. In row scanning a particular

    column is kept low (other columns are kept high) and the rows are tested for low using a suitable branching instruction. If a

    particular row is observed low then that means that the key connected between that row and the corresponding column (the

    column that is kept low) is been pressed. For example if column C1 is initially kept low and row R1 is observed low during

    scanning, that means key 1 is pressed.

    A membrane type hex keypad was used during the testing. Push button switch type and dome switch type will also work. Ihavent checked other types.

    The display used was a common cathode seven segment LED display with type number ELK5613A. This is just for informationand any general purpose common cathode 7 segment LED display will work here.

    A Note about 7 segment LED display.

    This article is about how to interface a seven segment LED display to an 8051 microcontroller. 7 segment LED display is very

    popular and it can display digits from 0 to 9 and quite a few characters like A, b, C, ., H, E, e, F, n, o,t,u,y, etc. Knowledge about how

    to interface a seven segment display to a micro controller is very essential in designing embedded systems. A seven segment display

    consists of seven LEDs arranged in the form of a squarish8slightly inclined to the right and a single LED as the dot character.

    Different characters can be displayed by selectively glowing the required LED segments. Seven segment displays are of two

    types,common cathode and common anode.In common cathode type , the cathode of all LEDs are tied together to a single

    terminal which is usually labeled as com and the anode of all LEDs are left alone as individual pins labeled as a, b, c, d, e, f, g & h

    (or dot) . In common anode type, the anode of all LEDs are tied together as a single terminal and cathodes are left alone as

    individual pins. The pin out scheme and picture of a typical 7 segment LED display is shown in the image below.

    7 segment LED display

    Digit drive pattern.

    http://www.circuitstoday.com/wp-content/uploads/2012/06/7-segment-LED-display-pinout-image.png
  • 8/12/2019 8051 CODE

    13/28

    Digit drive pattern of a seven segment LED display is simply the different logic combinations of its terminalsa to h in order to

    display different digits and characters. The common digit drive patterns (0 to 9) of a seven segment display are shown in the table

    below.

    Digit a b c d e f g

    0 1 1 1 1 1 1 0

    1 0 1 1 0 0 0 0

    2 1 1 0 1 1 0 1

    3 1 1 1 1 0 0 1

    4 0 1 1 0 0 1 1

    5 1 0 1 1 0 1 1

    6 1 0 1 1 1 1 1

    7 1 1 1 0 0 0 0

    8 1 1 1 1 1 1 1

    9 1 1 1 1 0 1 1

    Interfacing seven segment display to 8051.

  • 8/12/2019 8051 CODE

    14/28

    Interfacing 7 segment display to 8051

    The circuit diagram shown above is of an AT89S51 microcontroller based 0 to 9 counter which has a 7 segment LED display

    interfaced to it in order to display the count. This simple circuit illustrates two things. How to setup simple 0 to 9 up counter using

    8051 and more importantly how to interface a seven segment LED display to 8051 in order to display a particular result. The

    common cathode seven segment display D1 is connected to the Port 1 of the microcontroller (AT89S51) as shown in the circuit

    diagram. R3 to R10 are current limiting resistors. S3 is the reset switch and R2,C3 forms a debouncing circuitry. C1, C2 and X1 are

    related to the clock circuit. The software part of the project has to do the following tasks.

    Form a 0 to 9 counter with a predetermined delay (around 1/2 second here). Convert the current count into digit drive pattern. Put the current digit drive pattern into a port for displaying.All the above said tasks are accomplished by the program given below.

    Program.

    ORG 000H //initial starting address

    START: MOV A,#00001001B // initial value of accumulator

    http://www.circuitstoday.com/wp-content/uploads/2012/06/interfacing-7-segement-display-to-8051.png
  • 8/12/2019 8051 CODE

    15/28

    MOV B,A

    MOV R0,#0AH //Register R0 initialized as counter which counts from 10 to 0

    LABEL: MOV A,B

    INC A

    MOV B,A

    MOVC A,@A+PC // adds the byte in A to the program counters address

    MOV P1,A

    ACALL DELAY // calls the delay of the timer

    DEC R0//Counter R0 decremented by 1

    MOV A,R0 // R0 moved to accumulator to check if it is zero in next instruction.

    JZ START //Checks accumulator for zero and jumps to START. Done to check if counting has been

    finished.

    SJMP LABEL

    DB 3FH // digit drive pattern for 0

    DB 06H // digit drive pattern for 1

    DB 5BH // digit drive pattern for 2

    DB 4FH // digit drive pattern for 3

    DB 66H // digit drive pattern for 4

    DB 6DH // digit drive pattern for 5

    DB 7DH // digit drive pattern for 6

    DB 07H // digit drive pattern for 7

    DB 7FH // digit drive pattern for 8

    DB 6FH // digit drive pattern for 9

    DELAY: MOV R4,#05H // subroutine for delay

    WAIT1: MOV R3,#00H

    WAIT2: MOV R2,#00H

    WAIT3: DJNZ R2,WAIT3

    DJNZ R3,WAIT2

    DJNZ R4,WAIT1

    RET

    END

    About the program.

    Instruction MOVC A,@A+PC is the instruction that produces the required digit drive pattern for the display. Execution of this

    instruction will add the value in the accumulator A with the content of the program counter(address of the next instruction) and will

    move the data present in the resultant address to A. After this the program resumes from the line after MOVC A,@A+PC.

    In the program, initial value in A is 00001001B. Execution of MOVC A,@A+PC will add oooo1001B to the content in PC ( address

    of next instruction). The result will be the address of label DB 3FH (line15) and the data present in this address ie 3FH (digit drive

  • 8/12/2019 8051 CODE

    16/28

    pattern for 0) gets moved into the accumulator. Moving this pattern in the accumulator to Port 1 will display 0 which is the first

    count.

    At the next count, value in A will advance to 00001010 and after the execution of MOVC A,@+PC ,the value in A will be 06H which

    is the digit drive pattern for 1 and this will display 1 which is the next count and this cycle gets repeated for subsequent counts.

    The reason why accumulator is loaded with 00001001B (9 in decimal) initially is that the instructions from line 9 to line 15

    consumes 9 bytes in total.

    The lines 15 to 24 in the program which starts with label DB can be called as a Look Up Table (LUT). label DB is known as Define

    Byte which defines a byte. This table defines the digit drive patterns for 7 segment display as bytes (in hex format). MOVC operator

    fetches the byte from this table based on the result of adding PC and contents in the accumulator.

    Register B is used as a temporary storage of the initial value of the accumulator and the subsequent increments made to accumulator

    to fetch each digit drive pattern one by one from the look up table(LUT).

    Note:-In line 6, Accumulator is incremented by 1 each time (each loop iteration) to select the next digit drive pattern. Since MOVC

    operator uses the value in A to fetch the digit drive pattern from LUT, value in ACC has to be incremented/manipulated accordingly.

    The digit drive patterns are arranged consecutively in LUT.

    Register R0 is used as a counter which counts from 10 down to 0. This ensures that digits from o to 9 are continuously displayed in

    the 7 segment LED. You may note lines 4, 11, 12, and 13 in the above program. Line 4 initializes R0 to 10 (OAh). When the program

    counter reaches line 11 for the first time, 7 segment LED has already displayed 0. So we can reduce one count and that is why we

    have written DEC Ro. We need to continuously check if R0 has reached full count (that is 0). In order to do that lines 12 and 13 are

    used. We move R0 to accumulator and then use the Jump if Zero (JZ) instruction to check if accumulator has reached zero. If Acc=0,

    then we makes the program to jump to START (initial state) and hence we restart the 7 segment LED to display from 0 to 9 again. If

    Acc not equal to zero, we continue the program to display the next digit (check line 14).

    Multiplexing 7 segment display to 8051.

    Suppose you need a three digit display connected to the 8051. Each 7 segment display have 8 pins and so a total amount of 24 pins

    are to the connected to the microcontroller and there will be only 8 pins left with the microcontroller for other input output

    applications. Also the maximum number of displays that can be connected to the 8051 is limited to 4 because 8051 has only 4 ports.

    More over three 3 displays will be ON always and this consumes a considerable amount of power. All these problems associated with

    the straight forward method can be solved by multiplexing .

    In multiplexing all displays are connected in parallel to one port and only one display is allowed to turn ON at a time, for a short

    period. This cycle is repeated for at a fast rate and due to the persistence of vision of human eye, all digits seems to glow. The main

    advantages of this method are

    Fewer number of port pins are required .

    Consumes less power.

    More number of display units can be interfaced (maximum 24).The circuit diagram for multiplexing 2 seven segment displays to the 8051 is shown below.

  • 8/12/2019 8051 CODE

    17/28

    Multiplexing 7 segement display to 8051

    When assembled and powered on, the circuit will display the number 16 and let us see how it is done. Initially the first display is

    activated by making P3.0 high and then digit drive pattern for 1 is loaded to the Port 1. This will make the first display to show

    1. In the mean time P3.1 will be low and so do the second display will be OFF. This condition is maintained for around 1ms and

    then P3.0 is made low. Now both displays will be OFF. Then the second display is activated by making P3.1 high and then the digit

    drive pattern for 6 is loaded to the port 1. This will make the second display to show 6. In the mean time P3.0 will be l ow and so

    the second display will be OFF. This condition is maintained for another 1ms and then port 3.1 is made low. This cycle is repeated

    and due to the persistence of vision you will feel it as 16.

    Transistor Q1 drives the first display (D1) and transistor Q2 drives the second display (D2). R11 and R12 are the base current limiting

    resistors of Q1 and Q2. The purpose of other components are explained in the first circuit.

    Program.

    ORG 000H // initial starting address

    MOV P1,#00000000B // clears port 1

    MOV R6,#1H // stores "1"

    MOV R7,#6H // stores "6"

    MOV P3,#00000000B // clears port 3

    MOV DPTR,#LABEL1 // loads the adress of line 29 to DPTR

    MAIN: MOV A,R6 // "1" is moved to accumulator

    SETB P3.0 // activates 1st display

    ACALL DISPLAY // calls the display sub routine for getting the pattern for "1"

    http://www.circuitstoday.com/wp-content/uploads/2012/06/multiplexing-7-segement-display-to-8051.png
  • 8/12/2019 8051 CODE

    18/28

    MOV P1,A // moves the pattern for "1" into port 1

    ACALL DELAY // calls the 1ms delay

    CLR P3.0 // deactivates the 1st display

    MOV A,R7 // "2" is moved to accumulator

    SETB P3.1 // activates 2nd display

    ACALL DISPLAY // calls the display sub routine for getting the pattern for "2"

    MOV P1,A // moves the pattern for "2" into port 1

    ACALL DELAY // calls the 1ms delay

    CLR P3.1 // deactivates the 2nd display

    SJMP MAIN // jumps back to main and cycle is repeated

    DELAY: MOV R3,#02H

    DEL1: MOV R2,#0FAH

    DEL2: DJNZ R2,DEL2

    DJNZ R3,DEL1

    RET

    DISPLAY: MOVC A,@A+DPTR // adds the byte in A to the address in DPTR and loads A with data

    present in the resultant address

    RET

    LABEL1:DB 3FH

    DB 06H

    DB 5BH

    DB 4FH

    DB 66H

    DB 6DH

    DB 7DH

    DB 07H

    DB 7FH

    DB 6FH

    END

    Interrupt sources

    In an 8051 micro controller there are 2 external interrupts, 2 timer interrupts, and 1 serial interrupt. External interrupts are

    external interrupt 0(INT0) and external interrupt 1 (INT1). Timer interrupts are Timer 0 interrupt and Timer 1 interrupt. A serial

    interrupt is given for serial communication with the micro controller (transmit and receive) .

    All these four interrupts, when evoked serves or executes a particular set of predefined activities known asInterrupt Service

    Routines. Its way of functioning is similar to the subroutineswe write while developing a complete program. In the case of

  • 8/12/2019 8051 CODE

    19/28

    8051, the interrupt service routines(ISR) of each interrupt must begin from a corresponding address in the program memory. This

    address from which an ISR begins is called the vector address of the interrupt.

    Interrupt Source Vector address Interrupt priority

    External Interrupt 0 INT0 0003H 1

    Timer 0 Interrupt 000BH 2

    External Interrupt 1 INT1 0013H 3

    Timer 1 Interrupt 001BH 4

    Serial Interrupt 0023H 5

    Interrupt Priority

    All the 5 interrupts of 8051 has got different priorities. Interrupts are serviced according to itspriority order. From the table above,

    you can see that INT0 has the highest priority of 1 and Timer 0 comes next with priority value 2. The order of priority works like this

    consider a case where two interrupts are raised at the same time one from INT0 and another from Timer 1 interrupt. Now which

    one would be served first? In such a case, processor would serve the interrupt according to its priority. In our case INT0 i s of high

    priority (priority order 1)and Timer 1 interrupt is of low priority (priority order 4). So processor will execute ISR of INTO first and

    then later,after finishing ISR of INT0, processor will begin executing ISR of Timer 1 interrupt.

  • 8/12/2019 8051 CODE

    20/28

    From the figure above, you may note that INTO is an alternate function P3.2 and INT1 is an alternate function of P3.3. A signal

    received at these pins will evoke the interrupts accordingly. But not all signals will evoke the interrupt! The signal received at pins

    should be either a low level one or it should be a falling edge signal to evoke the corresponding interrupt. However to serve the

    interrupt upon receiving the signal at pins, the man who programs 8051 should preprocess a few bits 3 SFRs namely TCON, IE a nd

    IP. Lets examine them.

    TCON

  • 8/12/2019 8051 CODE

    21/28

    TCON is a bit addressable SFR. Out of the 8 bits, only the lower 4 bits are concerned with external interrupts. The upper 4 bits deals

    with interrupts from Timers. The lower four bits are TCON.0 (IT0), TCON.1 (IE0), TCON.2 (IT1) and TCON.3 (IE1). You can refer

    the figure given below for a better understanding. Out of these 4 bits, bits 0 and 1 that means TCON.0 and TCON.1 are

    concerned with external interrupt 0 (INT0), where as bits 2 and 3 TCON.2 and TCON.3 are concerned with external interrupt 1

    (INT1). Out of these bits only TCON.0 and TCON.2 are directly manipulated by the programmer while dealing with an external

    interrupt. Bits TCON.1 (IE0) and TCON.3 (IE1) are manipulated by the processor itself. An external signal received at INTO would

    set the bit TCON.1 (also known as IE0) and will be cleared by the processor itself, after it branches to the corresponding ISR located

    at 0003H. Similarly TCON.3 is set when an interrupt signal is received at INT1 and would be cleared by processor after

    branching. The other 2 bits TCON.0 and TCON.2 are used for selecting type of signal received.

    TCON.0 (or IT0) is set to 0 if the interrupt at INT0 is to be evoked by a low level signal. If TCON.0 is set to high, then the interrupt

    at INT0 would be evoked by a falling edge signal (high to low transition). Same is the case with TCON.1 if set to 0 then low level

    signal would raise an interrupt at INT1 and if set to high, then a falling edge signal would do the job.

    IE (Interrupt Enable)

    http://www.circuitstoday.com/wp-content/uploads/2012/06/tcon-register-8051.png
  • 8/12/2019 8051 CODE

    22/28

    There are 3 bits associated with external interrupts in IE they are bits 0,2 and 7. The main purpose of this SFR is to enable/disable

    different interrupts based on whether its corresponding bits are set or not. Refer the figure below.

    IE.7 is known as global interrupt bit which when set to 0 disables all kinds of interrupts in 8051. Only if this bit is set to 1,

    any kind of interrupt would be enabled in 8051. If this bit is set to 1, programmer can then individually enable or disable all other

    interrupts INT0, INT1, Timer interrupts (0 and 1) and serial interrupt.

    IE.0 If set to 1 it enables INT0 and if set to 0 INT0 would be disabled. So in order to enable external interrupt 0 (INT0)

    IE.7 and IE.0 should be set to 1.

    IE.2 Similar to IE.0 IE.1 enables/disables external interrupt 1 (INT1).

    Interrupt Priority (IP)

    http://www.circuitstoday.com/wp-content/uploads/2012/06/ip-register.pnghttp://www.circuitstoday.com/wp-content/uploads/2012/06/ie-register-8051.pnghttp://www.circuitstoday.com/wp-content/uploads/2012/06/ip-register.pnghttp://www.circuitstoday.com/wp-content/uploads/2012/06/ie-register-8051.png
  • 8/12/2019 8051 CODE

    23/28

    Basic function of this SFR is to set interrupt priority (IP). By default INT0 is of priority value 1 (which is the highest) and INT1 is of

    priority value 3 (which is lower than INT0). The programmer can alter this priority, if he wants! If IP.0 is set to 0 and then IP.2 is

    set to 0 then the priority order changes. INT1 will change to high priority and INT0 will change to lower priority compared to

    INT1.

    How to write an ISR (Interrupt Service Routine)

    An ISR is just like any other subroutine we write inside a program, except for the difference that an ISR must always end with

    a RETIinstruction and not with a RETinstruction (as in the case of subroutines). An ISR when evoked, executes a certain lines of

    code that does some kind of operations. It can be anything as defined by the programmer. The only condition is that the first line of

    ISR must begin from the corresponding vector address. Vector address of INT0 is 0003H and that of INT1 is 0013H.

    Note:In some cases the ISR will be too long that it wont be practical to write all codes staring from 0003H or the other vector

    address. In such cases, ISR can be placed at any other location in program memory and programmer must provide an unconditional

    jump to the starting address of ISR from the corresponding vector address. Example:-The ISR of INT0 has been written from

    location 2000H. Now programmer must place an instruction LJMP 2000H at the vector address of INT0 0003H.

    Note:-Whenever an evoked interrupt is acknowledged and the processor branches to its corresponding vector address, it

    automatically disables the interrupt in IE register. This disabled interrupt would only be re-enabled upon executing

    the RETI instruction placed inside the ISR. That is the single reason, a programmer must use RETI inside an ISR

    instead of RET instruction.Placing RET will also do the job of returning from interrupt routine to main program (the calling

    program) but the RET instruction will not re-enable the disabled interrupt in IE register. So if an RET is used, the interrupt would be

    permanently disabled after its first serving of ISR (unless it is enabled again by the programmer at some other part of the same

    program).

    So in order to write an ISR for INT0, you have to keep in mind the following things:-

    1)Place the ISR for INT0 beginning from its vector address 0003H. If the ISR is too long, place an unconditional jump from

    0003H to the starting address of ISR (which is placed at some other location of program memory). The ISR must end with a

    RETI instruction.

    2)Select the triggering signal type of interrupt by setting/clearing TCON.0 bit. TCON.0=1 means interrupt would be triggered by a

    falling edge signal. TCON.0 =0 means interrupt would be triggered by a low level signal.

    3)Set IE.0 =1 to enable the external interrupt 0 (INT0)

    4)Set IE.7=1 to enable the global interrupt control bit.

    5)Optionally, programmer can alter the priority of INT0 by setting/clearing IP.0 (Note: This step is optional.)

    Now when it comes to external interrupt 1 INT1 the processes are all same, except for the change in bits that are to be

    programmed.

    1)Place the ISR in vector address of INT1 0013H. Or if the ISR is long, place an LJMP at 0013H to the corresponding starting

    address of ISR for INT1.

    2)Triggering signal type is selected by setting/clearing TCON.2. TCON.2 = 0 triggered by low level signal. TCON.2 = 1 triggered

    by falling edge signal.

    3)Set IE.2 = 1 to enable INT1

    4)Set IE.7 =1 to enable global interrupt control bit.

    5)Interrupt priority can be altered by changing value of IP.2 (optional). Refer the diagram of IP register given above.

  • 8/12/2019 8051 CODE

    24/28

    How to generate Software Interrupts in 8051?

    Software interrupts are nothing but an interrupt generated by a program inside the controller. To generate an external interrupt, we

    need a signal input either at INT0 or INT1 pin of the 8051 micro controller. We have seen that, when an interrupt signal is received

    at the INTo pin, the TCON.1 bit would automatically get set and that is how the processor knows an interrupt signal has been

    received at INT0 pin. When TCON.1 is set, processor would immediately acknowledge the interrupt and branch to the corresponding

    ISR of INT0. While branching to the ISR, processor would also clear the TCON.1 bit. The same happens in the case of INT1 and the

    associated bit is TCON.3.

    Now in order to generate a software interrupt,the programmer can manipulate these bits TCON.1 and TCON.3

    manually inside a program.An instruction like SETB TCON.1will activate the interrupt for INT0 (without any external

    signal at the INT0 pin) inside the controller. Now the processor will acknowledge the interrupt and branch to the corresponding

    location of ISR for INT0 (vector address 0003H). After branching to ISR, the processor would clear the bit TCON.1. An instruction

    likeSETB TCON.3 would activate the interrupt for INT1 and processor would branch to ISR of INT1 located at vector address

    0013H. While branching it would automatically clear the bit TCON.3, so that the programmer can activate the interrupt again inside

    a loop or some other part of the program.

    Example Program:-

    Previously,we have developed a circuit to toggle two LEDs with a single push button switch in 8051. It has been developed for

    educational purpose.

    1)To learn how to interface LEDs to 8051

    2)How to use push button switch to manipulate output status of LEDs

    3)How to use interrupt and develop an ISR for 8051.

    You can see the circuit and article here

    This article is all about how to interface push button switches to an 8051 microcontroller. Push button switches are widely used in

    embedded system projects and the knowledge about interfacing them to 8051 is very essential in designing such projects. A typical

    push button switch has two active terminals that are normally open and these two terminals get internally shorted when the push

    button is depressed. Images of a typical pushbutton switch is shown below.

    http://www.circuitstoday.com/wp-content/uploads/2012/06/interfacing-pushbutton-to-8051.png
  • 8/12/2019 8051 CODE

    25/28

    Pushbutton switch

    Circuit diagram.

    Interfacng 8051 and pushbutton

    The circuit diagram for interfacing push button switch to 8051 is shown above. AT89S51 is the microcontroller used here. The

    circuit is so designed that when push button S1 is depressed the LED D1 goes ON and remains ON until push button switch S2 is

    depressed and this cycle can be repeated. Resistor R3, capacitor C3 and push button S3 forms the reset circuitry for the

    microcontroller. Capacitor C1, C2 and crystal X1 belongs to the clock circuitry. R1 and R2 are pull up resistors for the push buttons.

    R4 is the current limiting resistor for LED.

    Program.

    MOV P0,#83H // Initializing push button switches and initializing LED in OFF state.

    READSW: MOV A,P0 // Moving the port value to Accumulator.

    RRC A // Checking the vale of Port 0 to know if switch 1 is ON or not

    JC NXT // If switch 1 is OFF then jump to NXT to check if switch 2 is ON

    CLR P0.7 // Turn ON LED because Switch 1 is ON

    SJMP READSW // Read switch status again.

    http://www.circuitstoday.com/wp-content/uploads/2012/06/interfacing-pushbutton-to-8051-circuit.png
  • 8/12/2019 8051 CODE

    26/28

    NXT: RRC A // Checking the value of Port 0 to know if switch 2 is ON or not

    JC READSW // Jumping to READSW to check status of switch 1 again (provided switch 2 is OFF)

    SETB P0.7 // Turning OFF LED because Switch 2 is ON

    SJMP READSW // Jumping to READSW to read status of switch 1 again.

    END

    The Logic

    The first instruction MOV P0 #83H - is to turn LED off (Hex 83 in binary = 10000011) and to initialize switches 1 and 2. Switch

    1 is connected to port 0.0 and switch 2 is connected to port 0.1. Also note that LED is connected to port 0.7.

    Note:-Po.0 = 1 means switch 1 is OFF and Po.1 = 1 means switch 2 is OFF. P0.0 = o means switch 1 is ON and p0.1 = o means

    switch 2 is ON. LED turns ON when P0.7 = 0 and turns OFF when P0.7 = 1

    The program has two labels READSW and NXT. Its all about reading switch val ues that is P0.0 and P0.1. We are using RRC

    instruction to read switch values. The values of port 0 is moved to accumulator. Since port 0 and 1 are used to interface switches 1

    and 2, we can get the values of both port bits in LSBs 0 and 1 of accumulator by using MOV A,P0 instruction. RRC means rotate

    right through carry. You can learn more about this instruction here 8051 programming tutorial 1.What RRC do is simple it

    will move value of port 0.0 to the carry bit. Now we can check the carry bit using instruction JC which means jump if carry is set.

    If carry is SET then it means port0.0 =1 and this means switch 1 is OFF. If switch 1 is OFF then we have to check status of switch 2

    and that is why we jump to label NXT.

    In the mean time if switch 1 is pressed then value of port 0.0 will be equal to zero. This will get moved to accumulator and hence

    an RRC will result in carry bit = o. If carry bit = 0 then result of executing JC instruction is negative and it will not jump. The next

    instruction will get executed that is CLR P0.7. This clears port 0.7 to zero and hence LED will turn ON. Once turned On- LED will

    be kept On until switch 2 is pressed.

    The status of switch 2 is checked in NXT label. When NXT is executed, we are using RRC for the second time consecutively. This

    means, the carry bit now holds the value of P0.1 which is status of switch 2. If carry bit = 1 then switch 2 is OFF. This means LED

    should not be turned OFF. If carry bit = 0 then LED should be turned OFF (The instruction SETB P0.7 turns LED OFF)

    Toggling 2 LED with a pushbutton using interrupt.

    This circuit demonstrates how to toggle two LEDs with a single push button using the external interrupts. Interrupt is an

    asynchronous signal (either hardware or software) which indicates the processor to make a change in current execution. When the

    processor receives a valid interrupt signal it saves the current state and then goes to execute a set of predefined steps called

    interrupt service routine (ISR). After executing ISR, the processor goes back to the point where it deviated and continues from

    there. To learn more about interrupts check this link.External interrupt handling in 8051.

    Circuit diagram.

    http://www.circuitstoday.com/8051-programming-tutorial-chapter-1http://www.circuitstoday.com/8051-programming-tutorial-chapter-1http://www.circuitstoday.com/8051-programming-tutorial-chapter-1http://www.circuitstoday.com/external-interrupts-handling-in-8051http://www.circuitstoday.com/external-interrupts-handling-in-8051http://www.circuitstoday.com/external-interrupts-handling-in-8051http://www.circuitstoday.com/external-interrupts-handling-in-8051http://www.circuitstoday.com/8051-programming-tutorial-chapter-1
  • 8/12/2019 8051 CODE

    27/28

    Toggling LED using 8051 with interrupt

    In the circuit shown above D1, D2 (the LEDs to be toggled) are connected to P1.0 and P1.1 respectively. R2 and R4 limits the

    current through the LEDs. The push button switch S2 is connected to the INT0 pin where R1 is a pull up resistor and C4 is the

    debouncing capacitor. C3, R3 and S3 forms the reset circuitry. Capacitors C2, C2 and crystal X1 are related to the clock

    circuitry. When powered ON LED D1 will be OFF and and LED D2 will be ON. Whenever push button switch S2 is pressed it creates

    an interrupt and the software makes the status of P1.o and P1.1 to toggle which gets reflected in the LEDs.

    Program.

    ORG 000H // starting address

    SJMP LABEL //jumps to the LABEL

    ORG 003H // starting address for the ISR(INT0)

    ACALL ISR // calls the ISR (interrupt service routine)

    RETI // returns from the interrupt

    LABEL: MOV A,#10000000B // sets the initial stage of the LEDs (D1 OFF & D2 ON)

    MAIN: // main function that sets the interrupt parameters

    SETB IP.0 // sets highest priority for the interrupt INT0

    http://www.circuitstoday.com/wp-content/uploads/2012/06/interrupt-toggling-LED.png
  • 8/12/2019 8051 CODE

    28/28

    SETB TCON.0 // interrupt generated by a falling edge signal at INT0 (pin12)

    SETB IE.0 // enables the external interrupt

    SETB IE.7 // enables the global interrupt control

    SJMP MAIN // jumps back to the MAIN subroutine

    ISR: // interrupt service routine

    CPL A // complements the current value in accumulator A

    MOV P1,A // moves the current accumulator value to port 1

    RET // jumps to RETI

    END

    If you come across any doubts/errors while implementing this circuit, please feel free to ask in our comments section.