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