Help
  • FAQ
    browse most common questions
  • Live Chat
    talk with our online service
  • Email
    contact your dedicated sales:
0

8051 Microcontroller LED Blink Programming

Author : AIVON January 07, 2026

Content

 

Delay Concept

In earlier examples we only turned LEDs on and off or changed which LEDs are lit. To make LEDs blink repeatedly, we need to introduce delays so the LED stays on for a while and then off for a while. A microcontroller does not truly stop during a delay; instead, it executes instructions that consume time, so the pause is implemented by executing idle or looping instructions.

One simple way to implement a pause is to execute a loop that does nothing. This is commonly called a delay. For example:

while(n < 100) { n--; }

Or using a for loop:

for(n = 0; n < 100; n++) { ; }

These loops can be nested to create longer delays. In basic examples we often control delay length by adjusting a variable such as n: increase n for a longer delay or decrease it for a shorter one. To determine the appropriate value for n in a given application, you need to understand clock timing concepts: clock cycle, machine cycle, and instruction cycle.

Clock cycle is the period of the oscillator; it is the inverse of the oscillator frequency. For example, a 12 MHz crystal has a clock period of 1/12 MHz.

On the 8051 family, a machine cycle typically consists of 12 clock cycles, so a 12 MHz oscillator yields a 1 MHz machine cycle, i.e., 1 microsecond.

An instruction cycle is the time required to execute a particular instruction and normally consists of one or more machine cycles. Details vary by specific device; consult the chip datasheet because enhanced 8051 variants and other microcontrollers can have different timings.

You can calibrate delay counts by simulation or by downloading code to hardware and measuring pin waveforms with an oscilloscope. A more precise and flexible approach uses hardware timers; timer-based delays will be covered in the section on timers.

 

Blink Example

Based on the delay idea, here is a simple LED blink example. Follow the comments to understand the code.

#include // This is the 52 microcontroller header file #include // This is another compiler header used later typedef unsigned char u8; // typedef is an alias keyword typedef unsigned int u16; void main() { u8 i, j; // define variables P1 = 0xfe; // light the first LED for(i = 0; i < 200; i++) // first delay { for(j = 0; j < 200; j++) { ; } } P1 = 0xff; // turn off the first LED for(i = 0; i < 200; i++) // second delay { for(j = 0; j < 200; j++) { ; } } }

The example uses direct port assignment to P1 to control LEDs. After turning the LED on, the program delays, then turns it off and delays again, producing a blink effect.

 

Packaging Delay as a Function

Packaging the delay loop into a function makes the code reusable and clearer. Here is a refactored version that defines a delay function.

#include // This is the 52 microcontroller header file #include // This is another compiler header used later typedef unsigned char u8; typedef unsigned int u16; //void delay(); // function declaration example void delay(u8 ms); void main() { P1 = 0xfe; // light LED 1 delay(50); // call delay function P1 = 0xff; // turn off LED 1 delay(50); } void delay(u8 ms) // function definition { u8 i, j; // define i and j for this delay function for(i = 0; i < ms; i++) { for(j = 0; j < 200; j++) { ; } } }

Using a parameterized delay function such as delay(u8 ms) provides flexibility in specifying delay lengths.

 

Running LED (Rotating LEDs)

To make a more interesting pattern than a single blink, you can implement a running or rotating LED effect using bit shifts. The following program demonstrates a cyclic right-rotate operation to create a running LED across eight positions.

#include #include typedef unsigned char u8; typedef unsigned int u16; void delay(u8 ms); void main() { u8 rol = 0xfe; u8 i; for(i = 0; i < 8; i++) { // Initialize P1 port, set P1.0 to lit P1 = rol; // Delay a while delay(100); // Rotate the variable rol = _cror_(rol, 1); // After rotation, rol will be assigned to P1 in the next loop } } void delay(u8 ms) // function definition { u8 i, j; // define i and j for this delay function for(i = 0; i < ms; i++) { for(j = 0; j < 200; j++) { ; } } }

The _cror_ function performs a circular right rotate. For example, 11111110 rotated right by one bit becomes 01111111, with the least significant bit wrapped into the high bit. The _iror_ variant performs a logical right shift that fills the high bit with 0. Similarly, _crol_ is a circular left rotate and _irol_ is a logical left shift. Each shift type has specific uses, so experiment to become familiar with their behavior.


2025 AIVON.COM All Rights Reserved
Intellectual Property Rights | Terms of Service | Privacy Policy | Refund Policy