0% found this document useful (0 votes)
16 views12 pages

Data Transfer Programs in 8051 Microcontroller

The document discusses various programming examples based on data transfer, arithmetic, logical, and branching instructions for the 8051 microcontroller. It illustrates how to use instructions like MOV, ADD, and logical operations to manipulate data in registers and memory locations. Additionally, it covers the input/output state of ports and provides examples for transferring data between ports.

Uploaded by

Bibidh Prasad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views12 pages

Data Transfer Programs in 8051 Microcontroller

The document discusses various programming examples based on data transfer, arithmetic, logical, and branching instructions for the 8051 microcontroller. It illustrates how to use instructions like MOV, ADD, and logical operations to manipulate data in registers and memory locations. Additionally, it covers the input/output state of ports and provides examples for transferring data between ports.

Uploaded by

Bibidh Prasad
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

3.6.

1 Programs Based on Data Transfer Instructions


As studied in earlier sections, data can be copied to either register or memory location. Sometimes, the data
also needs to be transferred from external memory to internal memory and vice-versa with the help of
MOVX instruction. Another point worth mentioning is that although the instruction says move, the
contents are not actually moved, they are only copied. This means that the source is not affected with the
54 | Microcontroller Applications

execution of mov instruction, only the destination is affected. The following examples illustrate the various
applications of data transfer instructions.
Example 3.1 Write a program to transfer data 63H into register R0 and then transfer the contents to
register A.
Solution: This is a simple program, which makes use of MOV(move) instruction. The program is
given below:
ORG 0000 ; Start the program at address 0
MOV R0, #63H ; Move immediate data 63H to R0
MOV A, R0 ; Move data from register R0 to accumulator A
END ; End of program
Explanation: The program begins with ORG instruction, which sets the location of program memory to
0000. MOV R0, #63H is used to copy immediate data value 63H into register R0. Instruction MOV A, R0
data from register R0 to accumulator A. The END instruction marks the end of the program.
Example 3.2 Write a program to move data from memory location 63H into register R0 and then
transfer the contents to register A.
Solution: The program is given below:
ORG 0000 ; Start the program at address 0
MOV R0, 63H ; Move the data contained in memory location 63H to R0
MOV A, R0 ; Move data from register R0 to accumulator A
END ; End of program
Explanation: The program begins with ORG instruction, which sets the location of program memory to
0000. MOV R0, #63H is used to copy immediate data value 63H into register R0. Instruction MOV A, R0
data from register R0 to accumulator A. The END instruction marks the end of the program.
Example 3.3 Write a program to move data from internal memory location 25H to another RAM
location 52H
Solution: This is a simple program to move data within internal RAM to another RAM location.
ORG 0000 ; Start the program at address 0
MOV 52H, 25H ; Move contents of RAM location 25H to RAM location 52H
END ; End of program
Explanation: The program begins with ORG instruction, which sets the location of program memory to
0000. Instruction MOV 52H, 25H copies the contents of RAM location 25H to RAM location 52H.
Example 3.4 Write a program to move data from memory location pointed by register R1 to register
R2 in 8051. Use the DPTR register.
Microcontroller Application | 55

Solution:
ORG 0000 ; Start the program at address 0
MOV DPTR, R1 ; Load the address pointed by R1 into DPTR
MOVX A, @DPTR ; Move data from the memory location pointed by DPTR to Accumulator
MOV R2, A ; Move the data from Accumulator to R2
END ; End of program
Explanation: To move data from the memory location pointed by register R1 to register R2 in the 8051
microcontroller, the address pointed by R1 is to be loaded into the Data Pointer (DPTR). Then the data
from the memory location pointed by DPTR is to be moved to the Accumulator (A). and finally the data
from the Accumulator (A) is to be moved to register R2.
Example 3.5 Write a program to copy data from external source memory location (5000 H) to
destination memory location (6000 H).
Solution: Since the data cannot be copied directly from one memory location to another, it has to be
first copied to register A with the help of DPTR register. The program is given below:
ORG 0000 ; Start of program memory
MOV DPTR, #5000H ; Load DPTR with the source memory address 5000H
MOVX A, @DPTR ; Move data from source memory to accumulator
MOV DPTR, #6000H ; Load DPTR with the destination memory address 6000H
MOV @DPTR, A ; Move data from accumulator to destination memory
END ; End of program
Explanation: The program begins with ORG instruction, which sets the location of program memory to
0000. The instruction MOV DPTR, #5000H copies values 5000H into the DPTR register. Please note the
# sign, which indicates that it is a value. Thus DPTR now points to source memory location 5000H. Then
using MOVX A, @DPTR, the data is copied from source memory (5000H) to the accumulator. Next, the
instruction MOV DPTR, #6000H loads DPTR with the destination memory address 6000H and finally
MOV @DPTR, A copies the data from accumulator to destination memory. The END instruction marks
the end of the program.
Notice the use of MOVX and DPTR for copying contents from external memory source to internal memory.
3.6.2 Programs Based on Arithmetic Instructions
As discussed in earlier sections, 8051 has a variety of arithmetic instructions for performing arithmetic
operations. Let us now study some programs, which utilize these instructions.
An important point to be remembered is that all arithmetic operations are performed on the accumulator i.e
the destination for all arithmetic operations has to be accumulator only and no other general-purpose
register.
56 | Microcontroller Applications

Example 3.6 Write a program to add immediate data 34H to accumulator.


Solution: This is a simple program, which adds the accumulator (A) with the operand specified in the
source. The program is given below:
ORG 0000 ; Start of program memory
ADD A, #34H ; adds 34H data to accumulator
END ; End of program
Example 3.7 Write a program to add the value stored in register R0 to the accumulator.
Solution:
ORG 0000 ; Start of program memory
MOV A, #10 ; Move10 value to accumulator
MOV R0, #20 ; Move 20 value to register R0
ADD A, R0 ; Adds the value in register R0 to accumulator A
END ; End of program
After the execution of this program, the value contained in R0 register i.e. 10 will be added to that in the
accumulator, which contains 20. And hence, finally the accumulator will contain 10+20 i.e. 30.
Example 3.8 Write a program to add the value stored at the address pointed by the R0 register to the
accumulator (A).
Solution: Since this program involves the address pointed by register R0, pointer@ will be used.
ORG 0000 ; Start of program memory
MOV R0, #30H ; Copy value 30H to register R0
ADD A, @R0 ; Adds the value at address 30H to accumulator A
END ; End of program
Explanation: This program is an example of indirect addressing mode. Here the address is not directly
mentioned but indirectly using a pointer. Initially, 30H is added as an immediate value to R0. However,
when a pointer is used with Ro, the value contained in R0 becomes an address (30H) and CPU automatically
points to 30H memory location. Whatever value is stored in that address will be added to the accumulator
using ADD A,@R0.
Note how the usage of pointer@ before R0 changes the whole operation of the program. Now instead of
adding the value contained in R0, it will add the value contained in the address pointed by R0.
Example 3.9 Write a program to increment accumulator, register R1 and then add their contents.
Solution: This is a simple program, which makes use of INC instruction.
ORG 0000 ; Start of program memory
MOV A, #20 ; Copy value 20 to accumulator
Microcontroller Application | 57

MOV R1, #30 ; Copy value 30 to register R1


INC A ; Increment accumulator by 1
INC R1 ; Increment register R1 by 1
ADD A, R1 ; Adds the value at R1 to accumulator A
END ; End of program
Explanation: After the execution of INC instruction the values in accumulator and register R1 are
incremented by 1 and become 21 and 31 respectively. At the end of the program, these values are added
and the accumulator finally contains 21+31 i.e. 52.
Example 3.10 Write a program to multiply the contents of accumulator with register B and store the
results in memory location 56H.
Solution:
ORG 0000 ; Start of program memory
MOV A, #5 ; Copy value 5 to accumulator
MOV R1, #30 ; Copy value 30H to register R1
MUL A,B ; Multiply contents of B with A
MOV 56H, A ; Copy the contents of A to memory location 56H
END ; End of program

3.6.3 Programs Based on Logical Instructions


Logical operations in the 8051 microcontroller perform bitwise operations between the accumulator and
data stored in a memory location, register, or data given by the programmer. The result of a logical operation
is stored in the accumulator itself.
Example 3.11 Write a program to perform the logical AND operation between FFH and 0FH and
store the result in port P1.
Solution:
ORG 0000 ; Start of program memory
MOV A, #0FFH ; Load value FFH into accumulator
ANL A, #0FH ; Perform logical AND operation on FFH with 0FH
MOV P1, A ; Store result in Port 1
END ; End of program
Explanation: After execution of AND operation, the accumulator will contain 0FH and then the result is
stored in Port P1. Notice the use of 0 before immediate value FH as it will indicate data.
Example 3.12 Write a program to perform the logical AND operation between FFH and 0FH and
store the result in port P1.
58 | Microcontroller Applications

Solution:
ORG 0000 ; Start of program memory
MOV A, #0FH ; Load value 0FH into accumulator
ANL A, #0F0H ; Perform logical OR operation on 0FH with F0H
MOV P1, A ; Store result in Port 1
END ; End of program
Explanation: After execution of OR operation, the accumulator will contain FFH and then the result is
stored in Port P1. Notice the use of 0 before immediate value FH as it will indicate data.
Similar programs can be written for performing XOR, NOT operations and it is worthwhile mentioning
here that similar to Arithmetic operations, all logical operations are also performed on accumulator and the
final result is stored in the accumulator itself.

3.6.4 Programs Based on Branching Instructions


Branching instructions in 8051 assembly enable the program to jump to specific parts of the code depending
on conditions. These control the program flow with both conditional and unconditional jumps. As seen
earlier, these instructions check the contents of the accumulator/ Flag bits and accordingly change the
sequence of the program to some other location, whose address is given by Label.
Example 3.13 Write a program to check if the contents of R1 is 0. If yes, send the contents to R2, else
send FFH to R0.
Solution:
ORG 0000 ; Start of program memory
MOV A, R1 ; Copy the contents of R1 into A
JZ HERE ; if A=0, jump to location HERE
MOV R0, #0FF ; if A is not 0, send FFH to R0
HERE: MOV R2, A ; Copy the contents of A to R2
END ; End of program
Explanation: This program makes use of JZ conditional instruction. The instruction MOV A, R1 first
copies the contents of R1 into A. Then the condition of A is checked using JZ HERE. If it is zero, the
program is transferred to the label HERE using JZ HERE. If it is not zero, the contents of the accumulator
are copied into R2.
Example 3.14 Write a program to add two numbers FFH and 0AH. If a carry is generated, send 0000
to R1, else send FFH to R4.
Solution:
The same program can be executed using either JC or JNC. Both programs are given below and there is a
slight change in the logic.
(i) Using JC Instruction
ORG 0000H ; Start address
Microcontroller Application | 59

MOV A, #0FFH ; Load accumulator A with FFH


MOV B, #0AH ; Load register B with 0AH
ADD A, B ; Add contents of B to A
JC NEXT ; Jump to NEXT if there is a carry
MOV R4, FFH ; If there is no carry, continue execution here
NEXT: MOV R1, 00H ; If there is a carry, execution jumps here
END ; End of program
Explanation: In this program, the carry flag (CY) in the flag register (PSW) is utilized to determine if a
jump to label NEXT is to be made or not. First the two numbers FFH and 0AH are copied to registers A
and B respectively using MOV instructions. Then these are added using instruction ADD A, B. After the
addition, the condition of the CY flag is checked and the decision to jump to label NEXT is made using JC
instruction. If a carry is generated, the program control is transferred to Label NEXT using JC, else the next
instruction is executed.
(ii) Using JNC Instruction
ORG 0000H ; Start address
MOV A, #0FFH ; Load accumulator A with FFH
MOV B, #0AH ; Load register B with 0AH
ADD A, B ; Add contents of B to A
JNC NEXT ; Jump to NEXT if there is no carry
MOV R1, 00H ; If there is carry, continue execution here
NEXT: MOV R4, FFH ; If there is no carry, execution jumps here
END ; End of program
Explanation: In this program, there is a slight change from the earlier one. Here, the decision to transfer
control to label NEXT is made using JNC. If a carry is not generated, the program control is transferred to
Label NEXT using JNC, else the next instruction is executed.
Example 3.15 Write a program to add 2 to register A 100 times using looping.
Solution:
ORG 0000H ; Start address
MOV A, #0 ; Initialize register A to 0, clear Accumulator
MOV R1, #100 ; add multiplier 100 to R1
LOOP: ADD A, #02 ; Add 2 to register A
DJNZ R1, LOOP ; Decrement R1 and jump to LOOP if R1 is not zero
END ; End of program
60 | Microcontroller Applications

Explanation: This program makes use of the concept of looping using DJNZ instruction. Initially, the
accumulator is initialized to 0 using MOV A, #0. Then, the multiplier 100 is moved to R1, thus making it
a counter. The loop begins with label LOOP, which adds 02 to accumulator, decrements R1 and is repeated
100 times till the register R1 reaches 0. Once this condition is reached, the loop ends and the next instruction
is executed.
Input/Output State of Ports
In 8051 architecture, the pull-up resistors are enabled by default upon reset. This means that when you
configure a port pin as an input and do not drive it explicitly to a logic low state, it will be internally pulled
up to Vcc (logic high). Any port can be made an input by sending FFH i.e 11111111 to it, while it can be
made output by sensing 0000 to its bits.
Example 3.16 Suppose a real byte of data is being received at Port P1. Write a program to send this
data to P2.
Solution:
ORG 0000H ; Start address
MOV P1,#0FFH ; Make port P1 an input port
MOV A,P1 ; Send the data received at P1 to accumulator
MOV P2, A ; Send data at accumulator to P2
END
Explanation:
In this Program, first the port 1 is made an input port by sending data 11111111 to all its bits and making
them high. Now, it may be remembered that data cannot be sent directly from one port to another, it is first
sent to the accumulator by instruction MOV A,P1 and then using instruction MOV P2, A, it is sent to port
P2.
Machine Cycle in 8051
Each Instruction takes some time to be executed in terms of clock cycles known as machine cycles in 8051.
Depending upon the frequency of quartz crystal connected on pin 18 and 19 as well as chip manufacturer,
the length of clock cycle varies. Normally a clock frequency of 11.0592 MHz is used for 8051
microcontrollers as the baud rate compatibility is best at this clock frequency. Also, a prescaler or divider
of 12 is used in some architectures, which means one machine takes 12 Oscillator periods). Thus, the
frequency is first divided by 12 and then its reverse is calculated to obtain the machine cycle.
Delay Subroutine
Since each instruction has its own machine cycles, the time taken to execute the instructions can be used to
generate the time delay. Normally, DJNZ instruction is used for creating a delay subroutine. We have
already seen the use of DJNZ for creating a loop earlier. This can be understood further with the help of
an example program.
Microcontroller Application | 61

Example 3.17 Write a program to blink alternate LEDs connected to port P2 with some delay.
Solution:
ORG 0000H ; Start address
MOV P2, #0000 ; Make P2 an output port
MOV P2, #55H ; Make alternate LEDs connected to
P2 ON
ACALL DELAY ; give delay by going to DELAY subroutine
MOV P2, #0AAH ; Toggle the LEDs connected to P2
ACALL DELAY
END
DELAY: MOV R1,#200 ; Load R1 with 200 counter value
HERE: DJNZ R1, HERE ; Stay here till R1 becomes 0
RET ; Return to main program
Explanation:
In this program, 8 LEDs are connected to port P2 and hence, it is made an output port by making all bits
high. Then alternate LEDs connected to P2 are turned on by sending 55H (01010101B) to P2. A delay
subroutine is called ACALL DELAY instruction, which changes the control of the program to the
subroutine. A delay is generated by first moving a counter value 200 into R1. DJNZ instruction decrements
R1 and keeps on repeating till R1 becomes 0. Once this condition is fulfilled, it moves to next instruction
RET, which takes the control back to main program. Then instruction MOV P2, #0AAH (10101010B)
toggles the LEDs. Again Delay subroutine is called, executed and the program ends.

3.6.5 Programs Based on Bit Manipulation Instructions


As discussed earlier, bit manipulation instructions in 8051 allow us to manipulate individual bits within
registers and memory locations. The single bit addressability of 8051 is an advantage over microprocessors,
where the whole byte is to be changed instead of a single bit. Also, the ports can be addressed individually,
if need be. In assembly language, each port pin is written as P0.0, P0.1 and so on. Before understanding the
programs based on bit manipulation instructions, it is important to understand some points regarding the
port structure of 8051.
Pull up Resistors in 8051 Port Structure
The 8051 microcontroller typically supports an internal pull-up resistor feature for its I/O ports, allowing
for convenient interfacing with external devices, particularly switches and other digital input devices. The
62 | Microcontroller Applications

pull-up feature ensures that when an input pin is not actively driven to a logic high state (i.e., when no
external signal is applied), the pin is internally pulled up to a logic high level (Vcc). However, Port 0 is an
exception to this and requires external pull up resistors as it does not have internal pull up resistors. This is
called open-drain and is shown in Fig. 3.1.

Fig 3.1 Open Drain in 8051 Requiring External Pull-up Resistors

So when a bit is set high by SETB instruction, it is connected to Vcc, while when it is cleared by CLR
instruction, it is connected to ground.
Let us now learn assembly language programming based on bit manipulation instructions.
Example 3.18 Write a program to set bit P1.0 high and then clear it.
Solution:
ORG 0000H ; Start address
SETB P1.0 ; Turn on bit P1.0
CLR P1.0 ; Clear bit P1.0
END ; end the program
Explanation:
This program makes use of the single bit instructions SETB and CLR, where SETB P1.0 makes the bit P1.0
high, while CLR instruction turns it off.
Microcontroller Application | 63

Example 3.19 Write a program to make bit P1.0 high and then complement it.
Solution:
ORG 0000H ; Start address
SETB P1.0 ; make bit P1.0 high
CPL P1.0 ; complement bit P1.0
END ; end the program
Explanation:
This program makes use of the single bit instruction CPL, which changes the state of the bit. In this program
since the state of bit P1.0 is made high by STB P1.0, the CPL will change its state to 0.
Example 3.20 Write a program that sends a high-to-low pulse to pin P1.5 whenever a sensor
connected to pin P2.3 detects an input.
Solution:
ORG 0000H ; Start address
SENSOR_PIN EQU P2.3 ; Define P2.3 as SENSOR_PIN
OUTPUT_PIN EQU P1.5 ; Define P1.5 as OUTPUT_PIN
SETB SENSOR_PIN ; Enable P2.3 as input pin
CLR OUTPUT_PIN ; Make P1.5 as output pin
HERE: JNB SENSOR_PIN HERE ; Wait here till P2.3 is low
SETB OUTPUT_PIN ; Set P1.5 high
ACALL DELAY ; Give a small delay
CLR OUTPUT_PIN ; Set P1.5 low
ACALL DELAY ; Give a small delay
SJMP HERE ; Repeat indefinitely
DELAY: MOV R1,#200 ; Load R1 with 200 counter value
HERE: DJNZ R1, HERE ; Stay here till R1 becomes 0
RET ; Return to main program
Explanation: This program uses EQU directive for defining pin numbers and assigning them names. The
advantage of using this directive is that if at some point , the programmer wants to change the pin numbers,
it has to be done only initially while defining, because in the rest of the program, only names will be used.
So, initially EQU defines Pin 2.3 and Pin 1.5 as SENSOR_PIN and OUTPUT_PIN respectively. Then
these pins are made input and output by using SETB SENSOR_PIN and CLR OUTPUT_PIN respectively.
JNB SENSOR_PIN HERE instruction keeps checking for P2.3; till it remains low, the program remains
there itself. The moment this condition becomes false, i.e it detects an input and becomes high, the next
instruction SETB OUTPUT_PIN sets P1.5 high, ACALL DELAY gives a small delay followed by CLR
OUTPUT_PIN, which sets P1.5 low.

3.6.6 Programs Based on Stack, Subroutine and Interrupt Related Instructions


Let us now discuss some programs related to stack, subroutines and interrupt related instructions.
64 | Microcontroller Applications

Example 3.20 Write a program to load FFH on R0, push its content on stack, load AAH on R1, push
its content on stack, retrieve contents of R1 to R2 and those of R0 to R3.
Solution:
ORG 0H ; Start address of the program
MOV R0, #0FFH ; Load a value into R0
PUSH R0 ; Push R0 onto the stack
MOV R1, #0AAH ; Load another value into R1
PUSH R1 ; Push R1 onto the stack
POP R2 ; Pop the top value of the stack into R2
POP R3 ; Pop the next value of the stack into R3
END
Explanation: This program demonstrates basic stack operations in assembly language for the 8051
microcontroller. It loads values into registers R0 and R1, then pushes them onto the stack. It then pops the
values from the stack into registers R2 and R3, respectively.
Example 3.21 Write a program to add 10H to accumulator, call a subroutine to save contents of
accumulator on stack, add contents of memory location pointed by register R0 to accumulator,
retrieve contents from stack back to accumulator.
Solution:
ORG 0000H ; Start of program memory
MOV A, #10H ; Load accumulator with value 10H
CALL SUB_ROUTE ; Call subroutine
END
SUB_ROUTE:
PUSH ACC ; Save accumulator on the stack
MOV A, #05H ; Load accumulator with value 05H
ADD A, @R0 ; Add value at address pointed by R0 to accumulator
POP ACC ; Restore accumulator from the stack
RET ; Return from subroutine

UNIT SUMMARY
In this chapter, we delved into the instruction set of the 8051 microcontroller, understanding various
addressing modes. We gained insight into how instructions are classified. With a thorough understanding
of the instruction set, we can learn to write programs for 8051 microcontroller effectively. Through this
chapter, we have laid a solid foundation in assembly language programming of the 8051 microcontroller,
equipping ourselves with essential knowledge and skills to embark on more advanced projects and
applications.

You might also like