0
0
Power-electronicsHow-ToBeginner · 3 min read

How to Create Millisecond Delay in Embedded C Easily

To create a millisecond delay in embedded C, you typically use a hardware timer configured to count milliseconds or implement a calibrated busy-wait loop. Using a timer is more accurate and preferred for precise delays, while loops are simpler but less reliable.
📐

Syntax

There are two common ways to create millisecond delays in embedded C:

  • Using a hardware timer: Configure the timer registers to generate an interrupt or flag every millisecond.
  • Using a busy-wait loop: Run a calibrated empty loop that consumes time approximately equal to the desired delay.

Example syntax for a busy-wait delay function:

c
void delay_ms(unsigned int ms) {
    volatile unsigned int count;
    while(ms--) {
        count = 16000; // Adjust this value based on clock speed
        while(count--) {
            // Do nothing, just waste time
        }
    }
}
💻

Example

This example demonstrates a simple busy-wait delay function that blocks the program for approximately the specified milliseconds. The delay value depends on the processor clock speed and the loop calibration.

c
#include <stdio.h>

void delay_ms(unsigned int ms) {
    volatile unsigned int count;
    while(ms--) {
        count = 16000; // Calibrated for 1 ms delay at 16 MHz clock
        while(count--) {
            // Busy wait
        }
    }
}

int main() {
    printf("Start delay\n");
    delay_ms(1000); // Delay for 1000 ms (1 second)
    printf("End delay\n");
    return 0;
}
Output
Start delay End delay
⚠️

Common Pitfalls

  • Uncalibrated loops: Using arbitrary loop counts without calibration leads to inaccurate delays.
  • Interrupts affecting timing: Interrupts can pause the delay loop, making timing inconsistent.
  • Using delay loops in power-sensitive applications: Busy-wait loops waste CPU cycles and power.
  • Not using hardware timers: Hardware timers provide precise and non-blocking delays and are preferred.

Example of a wrong and right approach:

c
// Wrong: Uncalibrated delay loop
void delay_ms_wrong(unsigned int ms) {
    while(ms--) {
        for (unsigned int i = 0; i < 1000; i++) {
            // Arbitrary count, not calibrated
        }
    }
}

// Right: Calibrated delay loop
void delay_ms_right(unsigned int ms) {
    volatile unsigned int count;
    while(ms--) {
        count = 16000; // Calibrated for 1 ms at 16 MHz
        while(count--) {
            // Busy wait
        }
    }
}
📊

Quick Reference

Tips for creating millisecond delays in embedded C:

  • Use hardware timers for accurate and efficient delays.
  • Calibrate busy-wait loops based on your microcontroller clock speed.
  • Avoid busy-wait delays in power-sensitive or multitasking applications.
  • Consider using timer interrupts for non-blocking delays.

Key Takeaways

Use hardware timers for precise and efficient millisecond delays in embedded C.
Busy-wait loops must be calibrated to your microcontroller's clock speed for accuracy.
Avoid busy-wait delays in applications where power efficiency or multitasking is important.
Interrupts can affect delay accuracy if not managed properly.
Timer interrupts enable non-blocking delays and better program responsiveness.