How to Create Microsecond Delay in Embedded C
To create a microsecond delay in embedded C, use hardware timers configured to count microseconds or implement a calibrated busy-wait loop with known clock cycles. Using
timer registers is the most accurate method, while a for loop delay depends on processor speed and compiler optimization.Syntax
Microsecond delay can be created by configuring a hardware timer or by writing a busy-wait loop. The typical syntax for a busy-wait loop is:
void delay_us(unsigned int microseconds) {
while(microseconds--) {
// calibrated nop or empty loop
}
}For hardware timers, you set timer registers to count the required microseconds and wait for the timer flag.
c
void delay_us(unsigned int microseconds) { while(microseconds--) { // calibrated nop or empty loop } }
Example
This example shows a simple busy-wait loop delay function assuming a 16 MHz CPU clock. The loop is calibrated to approximately 1 microsecond per iteration.
c
#include <stdint.h> void delay_us(uint32_t us) { // Approximate delay for 1 microsecond at 16 MHz volatile uint32_t count; while(us--) { count = 16; // Adjust this value for your CPU speed while(count--) { __asm__("nop"); // Prevent optimization } } } int main() { // Example usage: delay 10 microseconds delay_us(10); return 0; }
Common Pitfalls
- Uncalibrated loops: Busy-wait loops vary with CPU speed and compiler optimization, causing inaccurate delays.
- Interrupts: Interrupts can extend delay time unexpectedly if not disabled.
- Timer configuration: Incorrect timer prescaler or count values lead to wrong delay durations.
Always calibrate delay loops for your specific hardware and consider using hardware timers for precise timing.
c
/* Wrong way: uncalibrated loop, may be optimized away */ void delay_us_wrong(unsigned int us) { while(us--) { for(int i=0; i<100; i++) { // empty loop } } } /* Right way: use volatile and nop to prevent optimization */ void delay_us_right(unsigned int us) { volatile int i; while(us--) { for(i=0; i<16; i++) { __asm__("nop"); } } }
Quick Reference
| Method | Description | Accuracy | Notes |
|---|---|---|---|
| Busy-wait loop | Simple CPU cycle counting loop | Low to medium | Needs calibration, affected by compiler and CPU speed |
| Hardware timer | Use MCU timer registers | High | Most accurate, requires timer setup |
| Delay functions from libraries | Prebuilt delay APIs | Depends on implementation | Easy but check underlying method |
| Disabling interrupts | Prevent delay interruption | Improves accuracy | May affect system responsiveness |
Key Takeaways
Use hardware timers for the most accurate microsecond delays in embedded C.
Busy-wait loops require careful calibration and can be affected by compiler optimizations.
Disable interrupts during delay if precise timing is critical.
Always test delay functions on your target hardware to ensure accuracy.
Avoid empty loops without volatile or nop instructions to prevent compiler removal.