MPMC Programs
Collection of Assembly and C programs for 8051 microcontroller
Assembly Language Programs
MPMC GTU Paper Programs Solutions
Multiply Two Bytes
Write a program using MUL instruction to multiply two bytes 05h and 03h. (3)
Assembly
Explanation:
- ORG 0000H: This directive tells the assembler that the code should be placed starting from memory address 0000H.
- MOV A, #05H: This instruction loads the immediate value 05H (the first number) into the accumulator register (A).
- MOV B, #03H: This instruction loads the immediate value 03H (the second number) into register B.
- MUL AB: This is the core multiplication instruction. It multiplies the contents of the accumulator (A) with the contents of register B. The 16-bit result is stored across the accumulator (lower byte) and register B (higher byte).
- MOV 40H, A / MOV 41H, B: These instructions are an example of how you would store the result in memory. Here, the lower byte of the result is stored at address 40H and the higher byte at 41H.
Important Notes:
- The 8051 can only multiply 8-bit numbers. The result of 05H * 03H = 0FH (15), fits within a single byte so there's no overflow in this case.
- If the result was larger than 255 (FFh), the overflow flag (OV) in the program status word (PSW) would be set.
RAM Multiplication
Write an ALP to multiply two numbers stored at 30h and 31h in RAM. Store answer at HSB 51H and LSB 52H. (4)
Assembly
Explanation:
- ORG 0000H: Indicates the starting memory address for the program.
- MOV A, 30H: Loads the memory address 30H into the accumulator (A).
- MOV B, @A: Indirect addressing. Moves the contents of the memory location pointed to by A (which contains the first number) into register B.
- INC A: Increments A to point to location 31H, where the second number is stored.
- MOV A, @A: Loads the second number (from location 31H) into the accumulator.
- MUL AB: Multiplies the number in the accumulator (A) with the number in register B.
- MOV 52H, A: Stores the lower byte (LSB) of the result in memory location 52H.
- MOV 51H, B: Stores the higher byte (MSB) of the result in memory location 51H.
Divide Two Bytes
Write a program using DIV instruction to divide two bytes 09h and 02h. (3)
Assembly
Explanation:
- ORG 0000H: Sets the starting address of the program.
- MOV A, #09H: Loads the dividend (the number to be divided) into the accumulator.
- MOV B, #02H: Loads the divisor into register B.
- DIV AB: Performs the division. The result (quotient) is stored in the accumulator (A), and the remainder is stored in register B.
- MOV 60H, A / MOV 61H, B: These are example instructions to store the quotient and remainder in memory locations 60H and 61H, respectively.
Important Notes:
- Integer Division: The 8051 DIV instruction performs integer division, meaning any fractional part of the result will be discarded.
- Overflow: If the result of the division is too large to fit in the accumulator, the overflow flag (OV) will be set in the program status word (PSW). You'll need to add code to handle this potential overflow situation if it's relevant to your application.
Result:
In this case, 09h / 02h = 4 (quotient) with a remainder of 1.
Number Division
Write a program to divide two numbers stored at 20h and 21h. Store quotient on 40h and reminder at 41h. (4)
Assembly
Explanation:
- ORG 0000H: Indicates the program starts at memory address 0000H.
- MOV A, 20H: Loads the memory address 20H (where the dividend is stored) into the accumulator.
- MOV B, @A: Indirect addressing. Loads the value at the memory location pointed to by A (the dividend) into register B.
- INC A: Increments the accumulator to point to address 21H, where the divisor is stored.
- MOV A, @A: Loads the value at the memory location pointed to by A (the divisor) into the accumulator.
- DIV AB: Performs the division. The quotient is left in the accumulator (A) and the remainder in register B.
- MOV 40H, A: Stores the quotient (from A) into memory location 40H.
- MOV 41H, B: Stores the remainder (from B) into memory location 41H.
Square Wave Generation P1.3 50% DC
Write a program to create square wave of 50 % duty cycle on P1.3 pin using timer. (4)
Code (Assuming Timer 0, Mode 1):
Assembly
Explanation:
-
ORG 0000H: Sets the program starting address.
-
MOV TMOD, #01H: Configures Timer 0 to operate in Mode 1 (16-bit mode).
-
Timer Reload Value Calculation:
- You'll need to adjust the calculation based on your crystal frequency and desired square wave period. The example assumes a 12 MHz crystal and aims for a 1 ms HIGH time (and 1 ms LOW time).
-
MOV TH0, #0xFC / MOV TL0, #0x18: Load the calculated reload value into Timer 0's high and low registers.
-
SETB P1.3: Initially set the output pin P1.3 to HIGH.
-
SETB TR0: Start running Timer 0.
-
HERE / JNB TF0, HERE: Create a loop waiting for the Timer 0 overflow flag (TF0) to be set.
-
CLR TF0: Clear the Timer 0 overflow flag.
-
CPL P1.3: Complement (toggle) the logic level of the P1.3 pin.
-
SJMP HERE: Jump back to the beginning of the loop, creating an infinite square wave generation.
Important Considerations:
- Crystal Frequency: Make sure to adjust the reload value calculation based on your specific crystal frequency.
- Timer Mode: Mode 1 is a common choice for square wave generation.
- Output Pin: Ensure that P1.3 is configured as an output pin.
- Desired Period/Frequency: Adjust the calculation to achieve your specific square wave timing requirements.
Square Wave Generation P1.1
Write an ALP to generate square wave on P1.1 using timer0 and mode 1. (4)
Assembly
Explanation:
- ORG 0000H: Sets the starting address of your program.
- MOV TMOD, #01H: Configures Timer 0 to operate in Mode 1, which is a 16-bit timer mode.
- Timer Reload Calculation:
- You need to adjust this calculation based on your crystal frequency and the desired frequency of the square wave.
- The example aims for a 1 kHz square wave with a 11.0592 MHz crystal.
- MOV TH0, #0xFC / MOV TL0, #0x18: Loads the calculated reload value into Timer 0's registers.
- SETB P1.1: Sets the P1.1 pin HIGH initially.
- SETB TR0: Starts Timer 0.
- HERE / JNB TF0, HERE: Creates a loop that waits for the Timer 0 overflow flag (TF0).
- CLR TF0: Clears the overflow flag.
- CPL P1.1: Toggles the state of the P1.1 pin, changing it from HIGH to LOW or vice versa.
- SJMP HERE: Jumps back to the label "HERE," creating a continuous square wave.
Key Points:
- Crystal Frequency: Replace the crystal frequency in the calculation with the actual value for your 8051 system.
- Desired Frequency: Modify the calculation to get the square wave frequency you need.
- Pin Configuration: Ensure that P1.1 is configured as an output pin.
Software Delay
Write software delay loop using two registers and explain in brief. (4)
Assembly
Explanation:
-
DELAY: This label marks the beginning of your delay subroutine.
-
MOV R0, #50D / MOV R1, #250D: These instructions load initial values into two registers, R0 and R1. The larger the values, the longer the delay. You'll need to adjust these based on your crystal frequency and the desired delay length.
-
DJNZ_R1 / DJNZ_R0: These are "Decrement and Jump if Not Zero" instructions. They form two nested loops:
- Outer Loop (R0): The outer loop decrements R0 and repeats until R0 reaches zero.
- Inner Loop (R1): The inner loop decrements R1 and repeats until R1 reaches zero. Each time the inner loop runs, it reloads R1 with its initial value.
How it Works:
The nested loops create a series of decrement operations. The combination of instructions and the initial values in R0 and R1 determine the overall time the delay takes to execute.
Important Considerations:
- Accuracy: Software delays are not perfectly precise. Their timing depends on your crystal frequency and the number of instructions within the loop.
- Crystal Frequency: For more accurate delays, you'll need to calibrate the initial values (in R0 and R1) based on your crystal frequency.
- Timer Alternatives: For very precise delays, consider using the 8051's built-in timers instead of software delay loops.
Bit Masking
Write sequence of instructions for masking 4 lower bits of content of R2. (3)
Assembly
Explanation:
-
MOV A, R2: This instruction copies the current value stored in register R2 into the accumulator (A).
-
ANL A, #0F0H: This performs a logical AND operation between the value in the accumulator (which now contains the original value of R2) and the hexadecimal value 0F0H. The result will be that:
- Bits 4-7 of the accumulator will remain unchanged.
- Bits 0-3 of the accumulator will become 0 (masked).
-
MOV R2, A: This instruction moves the modified contents of the accumulator (with the lower bits masked) back into register R2.
Key Points
- Hexadecimal Mask: The value 0F0H (binary: 1111 0000) is used as a mask because it has '1's in the bit positions you want to preserve and '0's in the bit positions you want to clear.
- Masking: Masking is a technique used to isolate or clear specific bits within a byte.
Memory Fill
Write sequence of instructions to fill internal memory location 20H to 2FH by data FFH. (3)
Assembly
Explanation:
-
MOV R0, #20H: Load the starting memory address (20H) into a register (we're using R0).
-
MOV A, #0FFH: Load the value you want to fill (FFH) into the accumulator.
-
FILL_LOOP: This label marks the beginning of the loop.
-
MOV @R0, A: This instruction uses indirect addressing. It stores the contents of the accumulator (FFH) into the memory location pointed to by the register R0.
-
INC R0: Increment the register R0 to point to the next memory location.
-
CJNE R0, #30H, FILL_LOOP: This instruction means "Compare and Jump if Not Equal." It compares the contents of R0 with the value 30H (which is the ending address + 1). If they are not equal, the program jumps back to the
FILL_LOOPlabel, continuing the filling process.
Key Points:
- Indirect Addressing: The
@R0syntax means that the contents of R0 are used as the memory address. - Loop Termination: The CJNE instruction ensures the loop runs until memory location 2FH is filled.
External Memory Addition
Write an ALP to add two 8 bit numbers stored at External memory location 2030h and 2031h. Store result in external memory location 2032h. (4)
Assembly
Explanation:
-
ORG 0000H: Sets the starting memory address for the program.
-
MOV A, #30H / MOVC A, @A+DPTR:
- Loads the lower byte of the first number's address (2030H) into the accumulator (A).
- Uses the DPTR (Data Pointer) register to access external memory. The
MOVCinstruction fetches the byte at the address calculated by adding the contents of A to the value in DPTR.
-
MOV B, A: Stores the fetched first number in register B.
-
MOV A, #31H / MOVC A, @A+DPTR Repeats the process to fetch the second number from address 2031H.
-
ADD A, B: Adds the two numbers together, storing the result in the accumulator (A).
-
MOV A, #32H / MOVX @DPTR, A:
- Loads the lower byte of the result's address (2032H) into A.
- Uses
MOVXfor external memory access, storing the result from A at the address pointed to by DPTR.
Important Notes:
- DPTR Setup: Ensure that your DPTR register is correctly initialized to point to the start of external memory before executing this code.
- MOVC vs. MOVX:
MOVCis used to read from code memory (usually within the 8051), whileMOVXis used for external data memory.
LED Flashing
Draw circuit diagram for interfacing 8 LEDS on port 1. Write a program to flash LEDS in sequence ( on 1 LED at a time) with suitable time delay. (7)
Circuit Diagram
-
8051 Microcontroller: The heart of the circuit. Choose your specific 8051 microcontroller model.
-
LEDs: 8 regular LEDs (choose a suitable color).
-
Current-Limiting Resistors: One resistor for each LED. Calculate the resistor value using this formula:
Resistor Value (Ohms) = (Supply Voltage - LED Forward Voltage) / Desired LED Current- Typical forward voltage for LEDs is around 1.8V - 3.3V (check your LED datasheet)
- Common LED current is around 20mA (0.02A)
-
Connections:
- Connect one leg of each LED to a separate pin on Port 1 of the 8051 (P1.0 - P1.7).
- Connect the other leg of each LED to a current-limiting resistor, and then connect those resistors to ground.
Example Circuit (Schematic would be ideal, but I'll provide a textual description):
- Assume 5V supply and standard red LEDs (2V forward voltage)
- P1.0 ---[330 Ohm Resistor]--- LED --- GND
- P1.1 ---[330 Ohm Resistor]--- LED --- GND
- ... (Repeat connections the same way for P1.2 to P1.7)
8051 Program
Assembly
Explanation
- START: Sets up a counter and initial LED pattern
- LOOP: Outputs pattern to the LEDs, calls delay, rotates the '1' bit for the next LED.
- CJNE: Checks if 8 shifts have occurred, restarts if not.
- DELAY: A basic software delay using nested loops.
Key Points
- Port Output: Ensure Port 1 is configured as output.
- Resistor Calculation: Calculate the correct resistor value for your LEDs and supply voltage.
- Delay Adjustment: Modify values in the DELAY subroutine for your desired LED flashing speed.
Register Separation
Write a program to separate data 71h stored in accumulator , in two registers R3=07h and R4=01h. (4)
We'll use a combination of bit-shifting and masking operations:
Assembly
Explanation:
-
MOV A, #71H: Load the value 71h into the accumulator (A).
-
Extract lower 4 bits:
- MOV R3, A: Store the original value from the accumulator into R3. Now both the accumulator and R3 have the value 71h.
- AND A, #0FH: Perform a logical AND operation with 0Fh (00001111 in binary) to mask off the upper 4 bits in the accumulator. Now, the accumulator only holds 00000111 (which is 7).
-
Extract upper 4 bits
- MOV R4, A: Store the masked value (the upper nibble, now in the lower 4 bits) into R4.
- SHR A: Shift the accumulator right by 4 positions. This moves the upper nibble (01) into the lower 4 bits, and the accumulator now holds 00000001 (which is 1).
At the end of this code:
- R3: Contains 00000111 (7)
- R4: Contains 00000001 (1)
Summation of first 9 numbers
Write a program to add first 9 numbers ( 1 to 9). Store answer at memory location 77h of RAM. (4)
Assembly
Explanation:
- ORG 0000H: Sets the starting address of your code.
- MOV R0, #00H: Initializes register R0 to 0. R0 will store the running sum.
- MOV R1, #09H: Initializes register R1 to 9, which will be our counter.
- LOOP: This label marks the beginning of the loop.
- ADD A, R1: Adds the value in R1 to the accumulator (where the running sum is stored).
- DJNZ R1, LOOP: Decrements R1 and jumps back to the
LOOPlabel if R1 is not zero. This loop continues for 9 iterations. - MOV 77H, A: After the loop, the accumulator (A) holds the sum of the first 9 numbers. This instruction stores that sum in memory location 77H.
- END: Indicates the end of the program.
Key Points
- Registers: We use registers for calculations and as a loop counter.
- DJNZ Instruction: The 'Decrement and Jump if Not Zero' instruction creates the loop.
Register Exchange
Write assembly code to exchange data of R1 and R2 using PUSH & POP. (3)
Assembly
Explanation:
- PUSH R1: Pushes the contents of register R1 onto the system stack.
- PUSH R2: Pushes the contents of register R2 onto the stack (on top of R1's value).
- POP R1: Pops the top value from the stack and stores it into R1. Since we pushed R2 last, this will be R2's original value.
- POP R2: Pops the next value from the stack and stores it into R2. This will be R1's original value.
Result:
After executing this code, the values in R1 and R2 will have been effectively swapped.
Important Note:
The stack in the 8051 microcontroller operates in a LIFO (Last In, First Out) manner. This means the last value pushed onto the stack will be the first value popped off.
RAM Copy
Write assembly code for copying data 99H to RAM memory locations 30H to 50H using counter. (3)
Assembly
Explanation:
-
ORG 0000H: Sets the program's starting memory address in the code space.
-
MOV R0, #30H: Loads the starting RAM address (30H) into register R0.
-
MOV R1, #21: Loads the counter value into register R1. Since there are 21 memory locations from 30H to 50H (inclusive), we initialize our counter with 21.
-
MOV A, #99H: Loads the data (99H) to be copied into the accumulator.
-
COPY_LOOP: This label marks the beginning of the loop.
-
MOV @R0, A: Uses indirect addressing to store the contents of the accumulator (99H) into the memory location currently pointed to by R0.
-
INC R0: Increments R0 to point to the next memory location where the data will be copied.
-
DJNZ R1, COPY_LOOP: Decrements the counter in R1 and jumps back to the
COPY_LOOPlabel if the counter is not zero. The loop continues until the counter reaches zero.
Switch-LED Connection
Draw a diagram to connect 8 switches with port P1 and 8 LEDs with port P2 and write a program to show status of switch on LED. (If switch is ON then LED is ON and if switch is OFF, LED is OFF). (7)
Circuit Diagram
Components:
- 8051 Microcontroller
- 8 Switches (simple push-button or toggle switches)
- 8 LEDs
- 8 Current-limiting resistors (calculate the value based on your specific LEDs)
- Breadboard and connecting wires
Connections:
-
Port P1 (Input):
- Connect one end of each switch to a separate pin on Port P1 (P1.0 - P1.7).
- Connect the other end of each switch to the microcontroller's ground (GND).
-
Port P2 (Output):
- Connect the anode (longer leg) of each LED to a separate pin on Port P2 (P2.0 - P2.7).
- Connect the cathode (shorter leg) of each LED to a current-limiting resistor. Connect the other end of each resistor to ground (GND).
Important:
- Pull-up Resistors: You'll likely need pull-up resistors (around 10k Ohms) connected between each input pin on Port P1 and the supply voltage (VCC). This ensures a defined logic level when the switches are open.
8051 Program
Assembly
Explanation
- ORG 0000H: Sets the program's starting address.
- LOOP: Label for the main program loop.
- MOV A, P1: Reads the entire byte from Port P1 (the status of all 8 switches) and stores it in the accumulator (A).
- MOV P2, A: Directly transfers the value from the accumulator to Port P2, controlling the LEDs to mirror the switch states.
- SJMP LOOP: Short jump back to the beginning of the loop for continuous monitoring.
Key Points
- Switch Logic: Make sure your switch connections result in a logic HIGH when pressed and a logic LOW when released.
- LED Considerations: Ensure Port P2 can handle the current requirements of your LEDs.
External RAM
Write a program to find largest number from 10 numbers starting at external RAM location 2000h. Store the largest number in internal RAM location 20h. (4)
Assembly
Explanation:
- ORG 0000H: Sets the starting address of the program.
- MOV DPTR, #2000H: Initializes the data pointer (DPTR) to point to the start of the numbers in external RAM (2000h).
- MOV R0, #10: Initializes a counter (R0) to keep track of the 10 numbers.
- MOV A, @DPTR / MOV 20H, A: Loads the first number into the accumulator and also stores it in internal RAM location 20H as our initial assumption for the largest number.
- LOOP: Labels the beginning of the loop.
- INC DPTR: Increments DPTR to point to the next number.
- MOVC A, @A+DPTR: Fetches the current number from external RAM using DPTR.
- CJNE A, 20H, NEXT: Compares the current number (in A) with the assumed largest number (at memory location 20H). If they are not equal, it jumps to the
NEXTlabel. - MOV 20H, A: If the current number is larger, replaces the content of memory location 20H (our largest number) with it.
- NEXT: Label for continuing to the next number.
- DJNZ R0, LOOP: Decrements the counter (R0) and jumps back to
LOOPif the counter is not zero.
At the end of this program, the largest number will be stored in internal RAM location 20H.
External RAM Add
Add two nos. given in R0 AND R1. Put the result in external RAM location 1030h (LSB) and 1031h (MSB). (3)
Assembly
Explanation:
- ORG 0000H: Sets the starting address of the program.
- ADD A, R1: Adds the contents of registers R0 and R1, storing the result in the accumulator (A).
- MOV R1, A: Stores the result in R1 as well. This handles the case where the addition results in a carry (overflow), ensuring the MSB is stored correctly.
- MOV DPTR, #1030H: Initializes the DPTR (Data Pointer) with the starting address (1030h) in external RAM.
- MOV A, R1 / MOVX @DPTR, A: Moves the lower byte of the result to the accumulator and then stores it at the location pointed to by DPTR (1030h) using the
MOVXinstruction (for external memory access). - INC DPTR / MOV A, R2 / MOVX @DPTR, A: Increments DPTR to address 1031h, moves the higher byte (if any) of the result into the accumulator, and stores it using
MOVX.
Key Points:
- DPTR Setup: Make sure your DPTR is correctly set up to point to the external memory region you want to use.
- Overflow Handling: This code correctly handles the potential overflow when adding 8-bit numbers.
Register Exchange A & B
Write an ALP to exchange the content of A and B (3)
Method 1: Using a Temporary Register (e.g., R0)
Assembly
Method 2: Using the XCH Instruction
Assembly
Method 3: Using XOR Operations
Assembly
Explanation:
- Method 1: This is the most general approach, using a temporary register to hold one of the values during the swap.
- Method 2: The
XCHinstruction is specifically designed for exchanging values between the accumulator and another register. It's the most efficient way if your 8051 microcontroller supports it. - Method 3: This method uses the XOR (Exclusive OR) operation, which has the interesting property that when you XOR a value with itself, the result is zero. This allows for a clever exchange mechanism.
Register Multiplication A & B
Write an ALP to multiply the content of A and B. (3)
Assembly
Explanation:
- ORG 0000H: Indicates the starting address of the program's code.
- MUL AB: This is the core multiplication instruction. It multiplies the contents of the accumulator and register B. The 16-bit result is stored across both the accumulator (lower 8 bits) and register B (higher 8 bits).
Important Notes:
- 8-bit Limitation: The 8051 can only directly multiply 8-bit numbers. If you need to multiply larger numbers, you'll have to implement a multi-byte multiplication algorithm using a series of additions and shifts.
- Result Location: Remember that the lower byte of the result will be in the accumulator (A) and the higher byte will be in register B after the multiplication.
Example:
If A = 5 (00000101) and B = 3 (00000011), then after MUL AB:
- A (Accumulator) would contain 15 (00001111) - the lower byte
- B would contain 0 (00000000) - the higher byte (in this case, it's zero)
Register Division A & B
Write an ALP to divide the content of A and B. (3)
Assembly
Explanation:
- ORG 0000H: Sets the program's starting address.
- DIV AB: This is the core division instruction. It divides the contents of the accumulator (which should contain the dividend) by the contents of register B (the divisor). After the division:
- Quotient: Stored in the accumulator (A)
- Remainder: Stored in register B
Important Notes
- Integer Division: The 8051's DIV instruction performs integer division, meaning any fractional part of the result will be discarded.
- Zero Division: Ensure that the value in register B is not zero before performing the division. Dividing by zero will cause an overflow flag (OV) to be set in the program status word (PSW).
Example:
If A = 10 (00001010) and B = 3 (00000011), then after DIV AB:
- A (Accumulator) would contain 3 (00000011) – the quotient
- B would contain 1 (00000001) – the remainder
RAM Copy 100h to 200h
Write a program to copy block of 8 data starting from location 100h to 200h.
Here's an assembly program for the 8051 microcontroller to copy a block of 8 bytes of data from starting location 100H to destination location 200H:
Assembly
Explanation
-
ORG 0000H: This directive tells the assembler to place the code starting from memory location 0000H.
-
Initialization:
- We load the Data Pointer (DPTR) with the starting address of the source block (100H).
- Register R0 is loaded with the starting address of the destination block (200H).
- Register R1 is initialized to 8, which is the number of bytes we want to copy.
-
COPY_LOOP:
MOVX A, @DPTR: Reads a byte from external RAM pointed to by DPTR and stores it in the accumulator.MOVX @R0, A: Writes the byte from the accumulator to external RAM pointed to by R0.INC DPTR,INC R0: Increment both DPTR and R0 to move to the next memory locations.DJNZ R1, COPY_LOOP: Decrement R1 and jump back to the 'COPY_LOOP' label if R1 is not zero (meaning we haven't copied all 8 bytes yet).
-
END: Signifies the end of the assembly program.
Key Points
- This assumes you have external RAM where you are storing the data.
- You may need to adapt the addresses (100H and 200H) if your data is stored elsewhere.
RAM Add
Write a program to add two bytes of data and store result in R0 register.
Here's the 8051 assembly code to add two bytes of data and store the result in register R0:
Assembly
Explanation
-
Data Initialization:
MOV A, #56H: Loads the immediate value 56H (hexadecimal) into the accumulator (A register).MOV B, #23H: Loads the immediate value 23H into register B.
-
Addition:
ADD A, B: Adds the value in register B to the value in the accumulator. The result remains in the accumulator.
-
Storing the Result:
MOV R0, A: Moves the value from the accumulator (which holds the sum) into register R0.
Important Points
- You can replace the
MOVinstructions with ways to get data from other sources (memory, user input, etc.). - Make sure that the sum of your two data bytes can fit into 8 bits to avoid overflow.
Mazidi Book Assembly Language Programs
Add Value 3 to ACC Ten Times
This program adds value 3 to the ACC ten times
Assembly
Complement ACC 700 Times
Write a program to (a) load the accumulator with the value 55H, and (b) complement the ACC 700 times
Assembly
Sum of 79H, F5H, E2H
Find the sum of the values 79H, F5H, E2H. Put the sum in registers R0 (low byte) and R5 (high byte).
Assembly
LCALL Example
Assembly
Use PUSH/POP in Subroutine
Assembly
Port 0 Output
The following code will continuously send out to port 0 the alternating value 55H and AAH
Assembly
Port 0 Input
Port 0 is configured first as an input port by writing 1s to it, and then data is received from that port and sent to P1
Assembly
Port 1 Output
The following code will continuously send out to port 0 the alternating value 55H and AAH
Assembly
Port 1 Input
Port 1 is configured first as an input port by writing 1s to it, then data is received from that port and saved in R7 and R5
Assembly
Port 1 Square Wave
Write the following programs. Create a square wave of 50% duty cycle on bit 0 of port 1.
Assembly
Port 1 to Port 0
Write a program to perform the following: (a) Keep monitoring the P1.2 bit until it becomes high. (b) When P1.2 becomes high, write value 45H to port 0. (c) Send a high-to-low (H-to-L) pulse to P2.3
Assembly
Oven Monitor
Assume that bit P2.3 is an input and represents the condition of an oven. If it goes high, it means that the oven is hot. Monitor the bit continuously. Whenever it goes high, send a high-to-low pulse to port P1.5 to turn on a buzzer.
Assembly
Switch to Port 2
A switch is connected to pin P1.7. Write a program to check the status of SW and perform the following(a) If SW=0, send letter 'N' to P2 (b) If SW=1, send letter 'Y' to P2
Assembly
Switch to Port 2 with Carry Flag
A switch is connected to pin P1.7. Write a program to check the status of SW and perform the following: (a) If SW=0, send letter 'N' to P2 (b) If SW=1, send letter 'Y' to P2 Use the carry flag to check the switch status.
Assembly
LED from Switch
Example 4-7 A switch is connected to pin P1.0 and an LED to pin P2.7. Write a program to get the status of the switch and send it to the LED
Assembly
Send 55H to P1 and P2
Example 5-1 Write code to send 55H to ports P1 and P2, using (a) their names (b) their addresses
Solution :
Assembly
Assembly
Push/Pop
Example 5-2 Show the code to push R5 and A onto the stack and then pop them back them into R2 and B, where B = A and R2 = R5
Solution:
Assembly
RAM Copy 40H to 41H
Example 5-3 Write a program to copy the value 55H into RAM memory locations 40H to 41H using (a) direct addressing mode, (b) register indirect addressing mode without a loop, and (c) with a loop
Solution:
Assembly
RAM Clear
Example 5-4 Write a program to clear 16 RAM locations starting at RAM address 60H
Solution:
Assembly
RAM Copy 35H to 60H
Example 5-5 Write a program to copy a block of 10 bytes of data from 35H to 60H
Solution:
Assembly
ROM Copy
Example 5-6 In this program, assume that the word "USA" is burned into ROM locations starting at 200H. And that the program is burned into ROM locations starting at 0. Analyze how the program works and state where "USA" is stored after this program is run.
Solution:
Assembly
Port 1 to Port 2
Example 5-8 Write a program to get the x value from P1 and send x2 to P2, continuously
Solution:
Assembly
Toggle P1
Example 5-10 Write a program to toggle P1 a total of 200 times. Use RAM location 32H to hold your counter value instead of registers R0 - R7
Solution:
Assembly
Switch to Port 2
Example 5-24 A switch is connected to pin P1.7. Write a program to check the status of the switch and make the following decision. (a) If SW = 0, send '0' to P2 (b) If SW = 1, send '1' to P2
Solution:
Assembly
ROM to RAM
Example 5-27 Assume that the on-chip ROM has a message. Write a program to copy it from code space into the upper memory space starting at address 80H. Also, as you place a byte in upper RAM, give a copy to P0.
Solution:
Assembly
RAM Sum
Assume that RAM locations 40 - 44H have the following values. Write a program to find the sum of the values. At the end of the program, register A should contain the low byte and R7 the high byte. 40 = (7D), 41 = (EB), 42 = (C5), 43 = (5B), 44 = (30)
Solution:
Assembly
Add Two 16-bit Numbers
Write a program to add two 16-bit numbers. Place the sum in R7 and R6; R6 should have the lower byte.
Solution:
Assembly
BCD Sum
Assume that 5 BCD data items are stored in RAM locations starting at 40H, as shown below. Write a program to find the sum of all the numbers. The result must be in BCD. 40=(71), 41=(11), 42=(65), 43=(59), 44=(37)
Solution:
Assembly
Packed BCD to ASCII
Assume that register A has packed BCD, write a program to convert packed BCD to two ASCII numbers and place them in R2 and R6.
Assembly
Find Timer 0 Delay
Example 9-7 Find the delay generated by timer 0 in the following code, using both of the Methods of Figure 9-4. Do not include the overhead due to instruction.
Assembly
Solution: (a) (FFFFH - B83E + 1) = 47C2H = 18370 in decimal and 18370 _ 1.085 us = 19.93145 ms (b) Since TH - TL = B83EH = 47166 (in decimal) we have 65536 - 47166 = 18370. This means that the timer counts from B38EH to FFFF. This plus Rolling over to 0 goes through a total of 18370 clock cycles, where each clock is 1.085 us in duration. Therefore, we have 18370 _ 1.085 us = 19.93145 ms as the width of the pulse.
Modify TL and TH
Example 9-8 Modify TL and TH in Example 9-7 to get the largest time delay possible. Find the delay in ms. In your calculation, exclude the overhead due to the instructions in the loop.
Solution: To get the largest delay we make TL and TH both 0. This will count up from 0000 to FFFFH and then roll over to zero.
Assembly
Making TH and TL both zero means that the timer will count from 0000 to FFFF, and then roll over to raise the TF flag. As a result, it goes through a total Of 65536 states. Therefore, we have delay = (65536 - 0) * 1.085 us = 71.1065ms.
Square Wave
Example 9-9 The following program generates a square wave on P1.5 continuously using timer 1 for a time delay. Find the frequency of the square wave if XTAL = 11.0592 MHz. In your calculation do not include the overhead due to Instructions in the loop.
Assembly
Solution: Since FFFFH - 7634H = 89CBH + 1 = 89CCH and 89CCH = 35276 clock count and 35276 * 1.085 us = 38.274 ms for half of the square wave. The frequency = 13.064Hz. Also notice that the high portion and low portion of the square wave pulse are equal. In the above calculation, the overhead due to all the instruction in the loop is not included.
Find Timer 0 Delay
Example 9-10 Assume that XTAL = 11.0592 MHz. What value do we need to load the timer's register if we want to have a time delay of 5 ms (milliseconds)? Show the program for timer 0 to create a pulse width of 5 ms on P2.3.
Solution: Since XTAL = 11.0592 MHz, the counter counts up every 1.085 us. This means that out of many 1.085 us intervals we must make a 5 ms pulse. To get that, we divide one by the other. We need 5 ms / 1.085 us = 4608 clocks. To Achieve that we need to load into TL and TH the value 65536 - 4608 = EE00H. Therefore, we have TH = EE and TL = 00.
Assembly
Generate Square Wave
Example 9-11 Assume that XTAL = 11.0592 MHz, write a program to generate a square wave of 2 kHz frequency on pin P1.5.
Solution: This is similar to Example 9-10, except that we must toggle the bit to generate the square wave. Look at the following steps.
- (a) T = 1 / f = 1 / 2 kHz = 500 us the period of square wave.
- (b) 1 / 2 of it for the high and low portion of the pulse is 250 us.
- (c) 250 us / 1.085 us = 230 and 65536 - 230 = 65306 which in hex is FF1AH.
- (d) TL = 1A and TH = FF, all in hex. The program is as follow.
Assembly
Generate Square Wave 50kHz
Example 9-12 Assume XTAL = 11.0592 MHz, write a program to generate a square wave of 50 kHz frequency on pin P2.3.
Solution: Look at the following steps.
- (a) T = 1 / 50 = 20 ms, the period of square wave.
- (b) 1 / 2 of it for the high and low portion of the pulse is 10 ms.
- (c) 10 ms / 1.085 us = 9216 and 65536 - 9216 = 56320 in decimal, and in hex it is DC00H.
- (d) TL = 00 and TH = DC (hex).
Assembly
Find Square Wave Frequency
Example 9-14 Assume XTAL = 11.0592 MHz, find the frequency of the square wave generated on pin P1.0 in the following program
Assembly
Solution: First notice the target address of SJMP. In mode 2 we do not need to reload TH since it is auto-reload. Now (256 - 05) _ 1.085 us = 251 _ 1.085 us = 272.33 us is the high portion of the pulse. Since it is a 50% duty cycle square wave, the period T is twice that; as a result T = 2 * 272.33 us = 544.67 us and the frequency = 1.83597 kHz
Find Square Wave Frequency
Example 9-15 Find the frequency of a square wave generated on pin P1.0.
Solution:
Assembly
Counter 1
Example 9-18 Assuming that clock pulses are fed into pin T1, write a program for counter 1 in mode 2 to count the pulses and display the state of the TL1 count on P2, which connects to 8 LEDs.
Solution:
Assembly
Serial Transfer
Write a program for the 8051 to transfer letter 'A' serially at 4800 baud, continuously.
Solution:
Assembly
Serial Transfer
Write a program for the 8051 to transfer 'YES' serially at 9600 baud, 8-bit data, 1 stop bit, do this continuously
Solution:
Assembly
Serial Receive
Write a program for the 8051 to receive bytes of data serially, and put them in P1, set the baud rate at 4800, 8-bit data, and 1 stop bit
Solution:
Assembly
Serial Port
Example 10-5 Assume that the 8051 serial port is connected to the COM port of IBM PC, and on the PC, we are using the terminal.exe program to send and receive data serially. P1 and P2 of the 8051 are connected to LEDs and switches, respectively. Write an 8051 program to: (a) send to PC the message "We Are Ready". (b) receive any data send by PC and put it on LEDs connected to P1, and (c) get data on switches connected to P2 and send it to PC serially. The program should perform part (a) once, but parts (b) and (c) continuously, use 4800 baud rate.
Solution:
Assembly
Serial Port
Example 10-6 Assume that XTAL = 11.0592 MHz for the following program, state (a) what this program does, (b) compute the frequency used by timer 1 to set the baud rate, and (c) find the baud rate of the data transfer.
Solution:
- (a) This program transfers ASCII letter B (01000010 binary) continuously
- (b) With XTAL = 11.0592 MHz and SMOD = 1 in the above program,
- we have: 11.0592 / 12 = 921.6 kHz
- machine cycle frequency. 921.6 / 16 = 57,600 Hz
- frequency used by timer 1 to set the baud rate.57600 / 3 = 19,200, the baud rate.
Assembly
Serial Port
Example 10-10 Write a program to send the message "The Earth is but One Country" to serial port. Assume a SW is connected to pin P1.2. Monitor its status and set the baud rate as follows: SW = 0, 4800 baud rate, SW = 1, 9600 baud rate Assume XTAL = 11.0592 MHz, 8-bit data, and 1 stop bit.
Solution:
Assembly
Square Wave
Example 11-2 Write a program that continuously get 8-bit data from P0 and sends it to P1 while simultaneously creating a square wave of 200 us period on pin P2.1. Use timer 0 to create the square wave. Assume that XTAL = 11.0592 MHz.
Solution:
Assembly
Square Wave
Example 11-3 Rewrite Example 11-2 to create a square wave that has a high portion of 1085 us and a low portion of 15 us. Assume XTAL=11.0592MHz. Use timer 1.
Solution: Since 1085 us is 1000 * 1.085 we need to use mode 1 of timer 1. upon wake-up go to main, avoid using memory allocated to Interrupt Vector Table
Assembly
Interrupt
Example 11-5 Assume that the INT1 pin is connected to a switch that is normally high. Whenever it goes low, it should turn on an LED. The LED is connected to P1.3 and is normally off. When it is turned on it should stay on for a fraction of a second. As long as the switch is pressed low, the LED should stay on.
Solution:
Assembly
Interrupt INT1
Assume that pin 3.3 (INT1) is connected to a pulse generator, write a program in which the falling edge of the pulse will send a high to P1.3, which is connected to an LED (or buzzer). In other words, the LED is turned on and off at the same rate as the pulses are applied to the INT1 pin.
Solution:
Assembly
P1 to P2 and Serial Port
Example 11-8 Write a program in which the 8051 reads data from P1 and writes it to P2 continuously while giving a copy of it to the serial COM port to be transferred serially. Assume that XTAL=11.0592. Set the baud rate at 9600.
Solution:
Assembly
P1 to P2 and P0 to Serial Port
Example 11-9 Write a program in which the 8051 gets data from P1 and sends it to P2 continuously while incoming data from the serial port is sent to P0. Assume that XTAL=11.0592. Set the baud rata at 9600.
Solution:
Assembly
P0 to Serial Port and P1 to P2
Example 11-10 Write a program using interrupts to do the following: (a) Receive data serially and sent it to P0, (b) Have P1 port read and transmitted serially, and a copy given to P2, (c) Make timer 0 generate a square wave of 5kHz frequency on P0.1. Assume that XTAL-11,0592. Set the baud rate at 4800.
Solution:
Assembly
LCD
To send any of the commands to the LCD, make pin RS=0. For data, make RS=1. Then send a high-to-low pulse to the E pin to enable the internal latch of the LCD. This is shown in the code below. calls a time delay before sending next data/command. P1.0-P1.7 are connected to LCD data pins D0-D7. P2.0 is connected to RS pin of LCD. P2.1 is connected to R/W pin of LCD. P2.2 is connected to E pin of LCD
Assembly
LCD Busy flag checking
Check busy flag before sending data, command to LCD. p1=data pin, P2.0 connected to RS pin, P2.1 connected to R/W pin, P2.2 connected to E pin
Assembly
LCD commands
To send any of the commands to the LCD, make pin RS=0. For data, make RS=1. Then send a high-to-low pulse to the E pin to enable the internal latch of the LCD. This is shown in the code below. calls a time delay before sending next data/command. P1.0-P1.7 are connected to LCD data pins D0-D7. P2.0 is connected to RS pin of LCD. P2.1 is connected to R/W pin of LCD. P2.2 is connected to E pin of LCD
Assembly
LCD Busy flag checking commands
Check busy flag before sending data, command to LCD, p1=data pin P2.0 connected to RS pin, P2.1 connected to R/W pin, P2.2 connected to E pin
Assembly
LCD Time delay
Call a time delay before sending next data/command: P1.0-P1.7=D0-D7, P2.0=RS, P2.1=R/W, P2.2=E
Assembly
Keyboard
Program 12-4: Keyboard Program keyboard subroutine. This program sends the ASCII code for pressed key to P0.1 P1.0-P1.3 connected to rows, P2.0-P2.3 to column
Assembly
Embedded C Programs
Mazidi Book C Programs
P1
Write an 8051 C program to send values 00 – FF to port P1.
C
P1 to P2
Write an 8051 C program to send hex values for ASCII characters of 0, 1, 2, 3, 4, 5, A, B, C, and D to port P1.
C
P1 Toggle
Write an 8051 C program to toggle all the bits of P1 continuously.
C
P1 Signed
Write an 8051 C program to send values of –4 to +4 to port P1.
C
P1 Toggle Bit
Write an 8051 C program to toggle bit D0 of the port P1 (P1.0) 50,000 times.
C
P1 Toggle Forever
Write an 8051 C program to toggle bits of P1 continuously forever with some delay.
C
P1 Toggle 250ms
Write an 8051 C program to toggle bits of P1 ports continuously with a 250 ms.
C
P1 to P2 LEDs
LEDs are connected to bits P1 and P2. #### Write an 8051 C program that shows the count from 0 to FFH (0000 0000 to 1111 1111 in binary) on the LEDs.
C
P1 to P2 Data
Write an 8051 C program to get a byte of data form P1, wait 1/2 second, and then send it to P2.
C
P0 to P1 P2
Write an 8051 C program to get a byte of data form P0. If it is less than 100, send it to P1; otherwise, send it to P2.
C
P2.4 Toggle
Write an 8051 C program to toggle only bit P2.4 continuously without disturbing the rest of the bits of P2.
C
P1.5 Monitor
Write an 8051 C program to monitor bit P1.5. If it is high, send 55H to P0; otherwise, send AAH to P2.
C
Door Sensor
A door sensor is connected to the P1.1 pin, and a buzzer is connected to P1.7. Write an 8051 C program to monitor the door sensor, and when it opens, sound the buzzer. You can sound the buzzer by sending a square wave of a few hundred Hz.
C
LCD 16x2
The data pins of an LCD are connected to P1. The information is latched into the LCD whenever its Enable pin goes from high to low. Write an 8051 C program to send “The Earth is but One Country” to this LCD.
C
P0 P1 P2 Toggle
Write an 8051 C program to toggle all the bits of P0, P1, and P2 continuously with a 250 ms delay. Use the sfr keyword to declare the port addresses.
C
P1.5 Toggle
Write an 8051 C program to turn bit P1.5 on and off 50,000 times.
C
P1.0 to P2.7
Write an 8051 C program to get the status of bit P1.0, save it, and send it to P2.7 continuously.
C
Bitwise Operations
Run the following program on your simulator and examine the results.
C
P0 P2 Toggle
Write an 8051 C program to toggle all the bits of P0 and P2 continuously with a 250 ms delay. Using the inverting and Ex-OR operators, respectively.
C
P1.0 to P2.7 Invert
Write an 8051 C program to get bit P1.0 and send it to P2.7 after inverting it.
C
P1.0 P1.1 to P0
Write an 8051 C program to read the P1.0 and P1.1 bits and issue an ASCII character to P0 according to the following table.
P1.1 P1.0 0 0 send ‘0’ to P0 0 1 send ‘1’ to P0 1 0 send ‘2’ to P0 1 1 send ‘3’ to P0
C
Packed BCD to ASCII 0x29
Write an 8051 C program to convert packed BCD 0x29 to ASCII and display the bytes on P1 and P2.
C
Packed BCD to ASCII 47
Write an 8051 C program to convert ASCII digits of ‘4’ and ‘7’ to packed BCD and display them on P1.
C
Checksum
Write an 8051 C program to calculate the checksum byte for the data 25H, 62H, 3FH, and 52H.
C
Checksum with G B
Write an 8051 C program to perform the checksum operation to ensure data integrity. If data is good, send ASCII character ‘G’ to P0.Otherwise send ‘B’ to P0.
C
FD to Decimal
Write an 8051 C program to convert 11111101 (FD hex) to decimal and display the digits on P0, P1 and P2.
C
RAM Space
Compile and single-step the following program on your 8051 simulator. Examine the contents of the 128-byte RAM space to locate the ASCII values.
C
Code Space
Write, compile and single-step the following program on your 8051 simulator. Examine the contents of the code space to locate the values.
C
Code Space RAM
Compile and single-step the following program on your 8051 simulator. Examine the contents of the code space to locate the ASCII values.
C
Code Space RAM simulator
Write, compile and single-step the following program on your 8051 simulator. Examine the contents of the code space to locate the values.
C
Code Space RAM - ABCDEF
Compile and single-step the following program on your 8051 simulator. Examine the contents of the code space to locate the ASCII values.
C
Serial Output LSB
Write a C program to send out the value 44H serially one bit at a time via P1.0. The LSB should go out first.
C
Serial Output MSB
Write a C program to send out the value 44H serially one bit at a time via P1.0. The MSB should go out first.
C
Serial Input LSB
Write a C program to bring in a byte of data serially one bit at a time via P1.0. The LSB should come in first.
C
Serial Input MSB
Write a C program to bring in a byte of data serially one bit at a time via P1.0. The MSB should come in first.
C
P1 Toggle
Example 9-20 Write an 8051 C program to toggle all the bits of port P1 continuously with some delay in between. Use Timer 0, 16-bit mode to generate the delay.
C
P1.5 Toggle every 50 ms
Example 9-21 Write an 8051 C program to toggle only bit P1.5 continuously every 50 ms. Use Timer 0, mode 1 (16-bit) to create the delay. Test the program on the (a) AT89C51 and (b) DS89C420.
C
P2 Toggle every 500 ms
Example 9-22 Write an 8051 C program to toggle all bits of P2 continuously every 500 ms. Use Timer 1, mode 1 to create the delay.
C
Switch Monitor
Example 9-25 A switch is connected to pin P1.2. Write an 8051 C program to monitor SW and create the following frequencies on pin P1.7: SW=0: 00Hz SW=1: 750Hz, use Timer 0, mode 1 for both of them.
C
P1.5 Toggle every 250 ms
Example 9-23 Write an 8051 C program to toggle only pin P1.5 continuously every 250 ms. Use Timer 0, mode 2 (8-bit auto-reload) to create the delay.
C
P2.7 Toggle every 250 ms
Example 9-24 Write an 8051 C program to create a frequency of 2500 Hz on pin P2.7. Use Timer 1, mode 2 to create delay.
C
Counter 1
Example 9-26 Assume that a 1-Hz external clock is being fed into pin T1 (P3.5). Write a C program for counter 1 in mode 2 (8-bit auto reload) to count up and display the state of the TL1 count on P1. Start the count at 0H.
C
Counter 0
Example 9-27 Assume that a 1-Hz external clock is being fed into pin T0 (P3.4). Write a C program for counter 0 in mode 1 (16-bit) to count the pulses and display the state of the TH0 and TL0 registers on P2 and P1, respectively.
C
Serial Output
Example 10-15 Write a C program for 8051 to transfer the letter “A” serially at 4800 baud continuously. Use 8-bit data and 1 stop bit.
C
Serial Output - Message
Example 10-16 Write an 8051 C program to transfer the message “YES” serially at 9600 baud, 8-bit data, 1 stop bit. Do this continuously.
C
Serial Input
Example 10-17 Program the 8051 in C to receive bytes of data serially and put them in P1. Set the baud rate at 4800, 8-bit data, and 1 stop bit.
C
Serial Output - Switch Monitor
Example 10-19 Write an 8051 C Program to send the two messages “Normal Speed” and “High Speed” to the serial port. Assuming that SW is connected to pin P2.0, monitor its status and set the baud rate as follows: SW = 0, 28,800 baud rate SW = 1, 56K baud rate Assume that XTAL = 11.0592 MHz for both cases.
C
Serial Output - DS89C4x0
Example 10-20 Write a C program for the DS89C4x0 to transfer the letter “A” serially at 4800 baud continuously. Use the second serial port with 8-bit data and 1 stop bit. We can only use Timer 1 to set the baud rate.
C
Serial Input - DS89C4x0
Example 10-21 Program the DS89C4x0 in C to receive bytes of data serially via the second serial port and put them in P1. Set the baud rate at 9600, 8-bit data and 1 stop bit. Use Timer 1 for baud rate generation.
C
Bit Reading with Square Wave
Write a C program that continuously gets a single bit of data from P1.7 and sends it to P1.0, while simultaneously creating a square wave of 200 us period on pin P2.5. Use Timer 0 to create the square wave. Assume that XTAL = 11.0592 MHz.
C
Serial Communication with Square Wave
Write a C program using interrupts to do the following: (a) Receive data serially and send it to P0 (b) Read port P1, transmit data serially, and give a copy to P2 (c) Make timer 0 generate a square wave of 5 kHz frequency on P0.1 Assume that XTAL = 11.0592 MHz. Set the baud rate at 4800.
C
Event Counter with Wave Generation
Write a C program using interrupts to do the following: (a) Generate a 10 KHz frequency on P2.1 using T0 8-bit auto-reload (b) Use timer 1 as an event counter to count up a 1-Hz pulse and display it on P0. The pulse is connected to EX1. Assume that XTAL = 11.0592 MHz. Set the baud rate at 9600.
C
LCD Busy Flag
Example 12-2 Write an 8051 C program to send letters ‘M’, ‘D’, and ‘E’ to the LCD using the busy flag method.
C