La macro _Waiste_us il cui codice sorgente è riportato nel listato 1, consente di generare con precisione un ritardo da un minimo di 1000000/F_CPU (F_CPU è la frequenza in Hz a cui lavora il micro) fino ad un massimo di 25.769.803.779/F_CPU_in_MHz.
;******************************************************************************
.equ F_CPU = 3579545 ;Hz
.Macro _Waiste_us ;n
.set Fraction = @0*F_CPU/1000000
.set Fraction = Fraction * 100
.set Fraction = @0*F_CPU/10000 - Fraction
.if Fraction >= 50
.equ Cycles_Needed = (@0 * F_CPU /1000000)+1
.endif
.if Fraction < 50
.equ Cycles_Needed = (@0 * F_CPU /1000000)
.endif
_Cycle_Waister Cycles_Needed
.endmacro
.macro _Cycle_Waister
.If @0 == 1
nop
.EndIf
.If @0 == 2
nop
nop
.EndIf
.If ((@0 > 2) && (@0 < 769))
;C=3n
;769=(3 * (2^8)) + 1
.set Loops_Needed = @0/3
ldi R16,Low(Loops_Needed)
Loop:
dec R16
brne Loop
.set Cycles_Left_To_Do = @0 - (3*Loops_Needed)
_Cycle_Waister Cycles_Left_To_Do
.EndIf
.If (@0 > 768) && (@0 < 262146)
;C=1+4n
;262146 = 1 + (4 * 2^16) + 1
.set Loops_Needed = (@0 - 1)/4
ldi ZL,Low(Loops_Needed)
ldi ZH,High(Loops_Needed)
Loop:
sbiw ZL,1
brne Loop
.set Cycles_Left_To_Do = (@0 - (4*Loops_Needed))-1
_Cycle_Waister Cycles_Left_To_Do
.EndIf
.If (@0 > 262145) && (@0 < 83886083)
;C=2+5n
;83.886.083 = 2 + (5 * 2^24) +1
.set Loops_Needed = (@0 - 2)/5
ldi R16,Low(Loops_Needed)
ldi ZL,Byte2(Loops_Needed)
ldi ZH,Byte3(Loops_Needed)
Loop:
subi R16,1
sbci ZL,0
sbci ZH,0
brne Loop
.set Cycles_Left_To_Do = (@0 - (5*Loops_Needed))-2
_Cycle_Waister Cycles_Left_To_Do
.EndIf
.If (@0 > 83886082) && (@0 < 25769803780)
;C=3+6n
;25769803780 = 3 + (6 * 2^32) +1
.set Loops_Needed = (@0 - 3)6
ldi XL,Low(Loops_Needed)
ldi XH,Byte2(Loops_Needed)
ldi ZL,Byte3(Loops_Needed)
ldi ZH,Byte4(Loops_Needed)
Loop:
sbiw Xl
sbci ZL,0
sbci ZH,0
brne Loop
.set Cycles_Left_To_Do = (@0 - (6*Loops_Needed)) - 3
_Cycle_Waister Cycles_Left_To_Do
.endif
.endmacro
| Listato 1 |
Per utilizzare la macro è sufficiente chiamarla passandogli come parametro un intero che costituisce il tempo di ritardo espresso in microsecondi. La precisione è pari all’inverso della frequenza del clock e la macro occupa un massimo di 13 words di codice. Prima di utilizzare la macro è necessario inizializzare la costante F_CPU assegnandoli il valore della frequenza della CPU espressa in Hz.





Per approfondimento vi segnalo anche questo articolo http://it.emcelettronica.com/come-generare-ritardi-precisi-con-i-nop
Ciao,
per un micro con frequenza 16Mhz, il ritardo minimo è 1000000/F_CPU = 10^6 /(16*10^6) = 0,0625 sec, mentre il ritardo massimo è 25.769.803.779/F_CPU_in_MHz. = 1610 sec.
Poi nella descrizione finale, c’è scritto di passare il parametro di attesa in us.
Sicuramente non sto calcolando in modo corretto i 2 ritardi minimo e massimo.
Grazie