Path:
Home =>
AVR-Überblick =>
Zeitschleifen => N-Bit mit SBC
(This page in English:
)
Sehr einfache Zeitschleife mit ganz vielen Bits für lange Zeiten in AVR Assembler
Es gibt noch eine weitere Zeitschleifen-Methode, die sich den besonders cleveren
Befehlssatz der AVR zunutze macht: das fortgesetzte Subtrahieren von Null mit Carry.
Es geht für einen 32-Bit-Zähler so:
.equ zaehler = 12345678
ldi R17,Byte1(Zaehler) ; 1 Takt
ldi R18,Byte2(Zaehler) ; +1 = 2 Takte
ldi R19,Byte3(Zaehler) ; +1 = 3 Takte
ldi R20,Byte4(Zaehler) ; +1 = 4 Takte
Schleife: ; Schleifentakte
clr R16 ; +1 = 1 Schleifentakt
sec ; +1 = 2 Schleifentakte
sbc R17,R16 ; +1 = 3 Schleifentakte
sbc R18,R16 ; +1 = 4 Schleifentakte
sbc R19,R16 ; +1 = 5 Schleifentakte
sbc R20,R16 ; +1 = 6 Schleifentakte
brne Schleife ; +1 beim letzten Durchlauf = 7 Schleifentakte, +2 bei allen anderen = 8 Schleifentakte
; Ende des Schleifenzaehlers
Zu Beginn wird der Schleifenzähler in den Registern R20:R19:R18:R17 auf eine Zahl
gesetzt. Werden statt der Register R16 bis R20 solche aus dem unteren Registerbereich
gewählt, müssen die Zählregister mit MOV aus einem oberen Register
geladen werden. Das braucht dann 8 Takte (4 für LDI, 4 für MOV).
Jetzt kommt die Schleife. Zuerst wird mit CLR R16 die Z-Flagge gesetzt und eine Null
in das Register geschrieben. Mit SEC wird die Carry-Flagge gesetzt. Mit vier SBC
wird jeweils Null und die Carry-Flagge abgezogen. Ist am Ende die Z-Flagge nicht
gesetzt, geht es wieder an den Anfang der Schleife. Nur bei gesetzter Z-Flagge ist
die Schleife fertig.
Der Algorithmus macht sich eine Besonderheit der Z-Flagge bei den SBC zunutze. Wenn vor
dem SBC die Z-Flagge nicht gesetzt ist, wird sie selbst dann nicht gesetzt, wenn beim SBC
Null herauskommt. Oder anders ausgedrückt: die Z-Flagge bleibt nur dann gesetzt,
wenn sie auch schon vorher gesetzt war UND wenn beim SBC Null herauskommt. Ein einziger
Nicht-Null-Fall in der Vierkette an SBCs löscht daher die anfangs mit CLR gesetzte
Z-Flagge und alle nachfolgenden SBC können daran dann auch nichts mehr ändern.
Einfach nur clever!
Die Formel zur Zeitberechnung ist recht viel einfacher als bei anderen Methoden. Sie
lautet
N = 4 + (Zaehler - 1 ) * 8 + 7 = 8 * Zaehler + 3
Umgekehrt kriegen wir den Zähler aus einer vorgegebenen Anzahl an Takten N mit
Zaehler = (N - 3) / 8
Brauchen wir also 1.000.000 Takte Verzögerung, dann kommt für den Zähler
124.999,625 heraus. Für Grobmotoriker reichen 124.999 oder 125.000 aus, der sehr
penible Takt-Erbsen-Zähler macht am Anfang noch fünf NOP dazu und nimmt
124.999.
In die 32 Bits passen Zahlen bis zu 4.294.967.295, was dann bei 1 MHz Takt mal eben bis
zu 1,9 Stunden Zählzeit entspricht und auch höchsten Ansprüchen
gerecht wird. Wer's noch länger braucht, fügt weitere Zählbits und SBCs
dazu und korrigiert die Formel ein wenig.
An den Seitenanfang
©2023 by http://www.avr-asm-tutorial.net