3.4.11 How Can I Implement a Delay in My Code?

If an accurate delay is required, or if there are other tasks that can be performed during the delay period, then using a timer to generate an interrupt is the best way to proceed.

If these are not issues in your code, then you can use the compiler’s in-built delay pseudo-functions: _delay(), __delay_ms() or __delay_us() (see 9.2.9 _delay Builtin). These all expand into in-line assembly instructions or a (nested) loop of instructions that will consume the specified number of cycles or time. The delay argument must be a constant expression (i.e. it cannot contain variables or function calls) and evaluate to less than 50,463,240. To use the __delay_ms() or __delay_us() versions of the delay, the preprocessor macro _XTAL_FREQ must be correctly defined to match the device clock frequency.

Note that these code sequences will only use the nop instruction and/or instructions which form a loop. The alternate watchdog versions of these pseudo-functions, e.g., _delaywdt(), can use the clrwdt instruction as well.