How to make a delay in assembly for avr microcontrollers?

UmeRonaldo picture UmeRonaldo · Jun 7, 2014 · Viewed 36.7k times · Source

I am having a problem in calculating delays. I want to make a delay for 1 sec when I am using 1MHz clock speed for my atmega128 microcontroller.

I use proteus for simulation and avr studio for coding in assembly for atmel microcontroller.

For example this code is for 8MHz clock microcontroller

Delay_15mS:                 ; For CLK(CPU) = 8 MHz
    LDI     dly1,   120     ; One clock cycle;
Delay1:
    LDI     dly2,   250     ; One clock cycle
Delay2:
    DEC     dly2            ; One clock cycle
    NOP                     ; One clock cycle
    BRNE    Delay2          ; Two clock cycles for true 1 clock for false

    DEC     dly1            ; One clock Cycle
    BRNE    Delay1          ; Two clock cycles for true 1 clock for false
RET

Can you teach me how to calculate the time this delay will take? So I could make 1 for 1 sec delay @ 1 MHz

Thank you

Answer

ferrangb picture ferrangb · Jun 13, 2014

To calculate a delay, you need to calculate the cycle time and then count how may cycles you need to reach the wanted delay.

In your case, 1MHz clock means 1000000 cycles per second. So 1 cycle equals 1/1000000 seconds or 1us. To get 1 second delay, you need 1000000 cycles of 1us, so it means that you have to create an algorithm of 1000000 cycles.

Building on your example, a 1 sec delay @ 1MHz clock would be:

Delay_1sec:                 ; For CLK(CPU) = 1 MHz
    LDI     dly1,   8       ; One clock cycle;
Delay1:
    LDI     dly2,   125     ; One clock cycle
Delay2:
    LDI     dly3,   250     ; One clock cycle
Delay3:
    DEC     dly3            ; One clock cycle
    NOP                     ; One clock cycle
    BRNE    Delay3          ; Two clock cycles when jumping to Delay3, 1 clock when continuing to DEC

    DEC     dly2            ; One clock cycle
    BRNE    Delay2          ; Two clock cycles when jumping to Delay2, 1 clock when continuing to DEC

    DEC     dly1            ; One clock Cycle
    BRNE    Delay1          ; Two clock cycles when jumping to Delay1, 1 clock when continuing to RET
RET

In this case there is the internal loop Delay3 that is 4 cycles long because DEC=1, NOP=1 and BRNE=2 when jumping to Delay3. So, 4 cycles repeated 250 times (the value of dly3) are 1000 cycles or 1000us = 1ms.

Then the loop Delay2 repeats the Delay3 125 times (the value of dly2). So the accumulated delay in this case is 125ms.

And finally, the loop Delay1 repeats the Delay2 8 times (the value of dly1). So the accumulated delay in this case is 1000ms or 1 second.

NOTE: This example delay is actually a little bit longer than 1sec because I didn't consider the time of the instructions of Delay2 and Delay1. The influence is very small, but for a precise 1sec delay, these instructions must be counted and the values of dly1, dly2 and dly3 must be adjusted to guarantee that the algorithm is exactly 1000000 cycles long.

NOTE2: With this algorithm the microcontroller can't do anything else while executing the delay because you are using it to count cycles. If you want to do other things while doing a delay, take a look at timers and interrupts of the microcontroller.