LED Blinking is one of the simplest task, which we are going to solve in this tutorial. This could be difficult if we try to do this in assembly language. We are going to write LED Blink 8051 Assembly language code in this tutorial. Before we get started let’s review what kind of previous understanding we need to start writing this code.

You may also want to see the other 8051 Assembly language programming posts which we created in this series. Here is the links.

Prerequisite

Before jumping into the code we must understand the basic registers and internal architecture of the 8051 microcontroller. Also basic understanding of simulation is required because we are going to test this code in proteus. So if you have not watch my basic assembly language and lecture before you must check out my previous YouTube video about assembly language Introduction.

Sudo code for LED Blinking

Now that you may know basic assembly introduction, let’s start understanding the development logic for LED blinking code. So the main steps to make one LED blink we need to follow these orders

  1. Label LED to some Pin of 8051
  2. Make LED HIGH
  3. wait for few milliseconds
  4. Turn LED ON by writing LOW to the LED Pin
  5. Take some delay again
  6. Loop back to Turn the LED Off on step # 2

So these are the basic steps which you need to follow. If you are looking for code to blink multiple LEDs like 8 LED blinking in assembly you can check out my updated post about blinking 8 Leds. Or if you are interested in PIC microcontrollers we have post about LED blinking example of PIC microcontrollers as well. There is another assembly language variation of PIC microcontrollers LED blinking.

What is a Delay in Assembly Language?

Well, you may already aware of the word delay which means to lag some event by some time. But the question arises what is the Delay in Assembly language? Specially in Embedded systems? Or if you had read our previous post about PIC microcontroller LED blinking in assembly language example code.

To answer the above question we must understand that the Microcontroller runs very very fast. Just like, in case of 8051, connected with 12MHz crystal, the one instruction is executed in one micro seconds.

So if in normal case of blinking, where we only need to turn on led and then turn off LED and repeat. Microcontroller will do this so rapidly that we won’t be able to see the actual blinking. We (humans) cannot visualize the on and off of LED at 1us. So for making this visualize able we need to slow down microcontroller.

But the microcontroller always following some instructions. That’s why to slow down the microcontroller we also have to write some code to let microcontroller do some task all the time. We create a Delay task for this purpose and call this a Delay subroutine in assembly language.

Delay function in 8051 Assembly

To write the Delay function in 8051 assembly language we fill some 8bit register with a fix number and then ask 8051 microcontroller to decrement that register with DJNZ Instruction. Once it’s done we repeat the task until we wasted enough microseconds of the 8051 microcontroller. Here is the one register delay function which is called the Delay subroutine in Assembly Language

DELAY1: MOV  R7,#255
        DJNZ R7,$
        RET

Code language: PHP (php)

Delay for approx. 500 millisecond

To modify the given delay routine to take approximately 500 milliseconds (or 0.5 seconds), you can adjust the number of iterations in the loops to achieve the desired delay time. Here’s how you can modify the routine:

DELAY3:
    MOV  R7, #41    ; Set R7 to a value that results in approximately 500ms delay
D3L1:
    MOV  R6, #255   ; Set R6 to 255 for the middle loop
D3L2:
    MOV  R5, #255   ; Set R5 to 255 for the inner loop
D3L3:
    DJNZ R5, D3L3   ; Decrement R5 and loop if not zero
    DJNZ R6, D3L2   ; Decrement R6 and loop if not zero
    DJNZ R7, D3L1   ; Decrement R7 and loop if not zero
    RET
Code language: PHP (php)

Calculating the time of Delay Routine

To calculate the time taken, we need to know the clock cycles required for each instruction. Assuming a standard 8051 microcontroller where most instructions take 1 clock cycle (for MOV, DJNZ, RET, etc.), the delay routine will take 393,216×1=393,216393,216×1=393,216 clock cycles.

R7 (Outer Loop): Setting R7 to 41 gives you 41×256×256=268697641×256×256=2686976 iterations, which is approximately 500ms at an 11.0592MHz crystal frequency.

Please note that the exact duration of the delay might vary slightly due to the execution time of the instructions and the specific crystal accuracy. You may need to adjust the value in R7 slightly to fine-tune the delay duration to exactly 500 milliseconds based on the actual execution time of the instructions on your specific microcontroller.

Here is the complete procedure to calculate the time of the delay routine

Certainly! Let’s calculate the number of iterations needed in the outer loop (R7) to achieve a delay of approximately 500 milliseconds with an 11.0592 MHz crystal. Here’s the calculation process:

Calculate Clock Cycles for 500 Milliseconds:

  • Clock Frequency: 11.0592 MHz = (11,059,200 \, \text{Hz})
  • Desired Delay: 500 milliseconds = (0.5 \, \text{s})
  • Clock Cycles in 500ms = (11,059,200 \times 0.5 = 5,529,600 \, \text{cycles})

Calculate Total Iterations:

  • Each Iteration of Inner Loop (R5) = 256 cycles
  • Each Iteration of Middle Loop (R6) = (256 \times 256 = 65,536) cycles
  • Total Iterations in Nested Loops = (65,536 \times 256 = 16,777,216 \, \text{iterations})

Calculate Iterations for Outer Loop (R7):

  • Required Total Iterations – Total Iterations in Nested Loops = (5,529,600 – 16,777,216 = -11,247,616 \, \text{iterations})
  • However, R7 cannot be negative, so set R7 to 0.

Accuracy of Iterative Delays

In this case, it’s not possible to achieve exactly 500 milliseconds with the given nested loop structure. The provided delay routine’s maximum delay duration is less than 500 milliseconds due to the constraints of the loop structure and the crystal frequency. To achieve a delay closer to 500 milliseconds, you might need to consider other approaches or use external timers for precise timing control.

Even though we took 255 decrements for the R7 register but still this is not enough for human’s to visualize the blinking. So we need at-least 3 registers delay to accomplish LED blinking task. So here is the final complete code for the LED blink in 8051 assembly language.

LED  BIT  P1.0
;--------------------------------------------
 ORG  00H
;--------------------------------------------
MAIN:
 CLR  LED
 ACALL  DELAY3
 SETB LED
 ACALL DELAY3
 SJMP MAIN

;-------------------------------------------

DELAY3:
     MOV  R7,#45
D3L1: MOV  R6,#255
D3L2: MOV  R5,#255
 
     DJNZ R5,$
      DJNZ R6,D3L2
     DJNZ R7,D3L1
     RET
;-----------------------------------------------
END
;-------------------------------------------------Code language: PHP (php)

Here is the YouTube video I created for this tutorial if you like to see things in action

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.