Path: Home => AVR-Überblick => Zeitschleifen => 8-Bit-Register    (This page in English: Flag EN) Logo
Zeitschleife

Zeitschleife mit 8-Bit-Register in AVR Assembler

Hier wird eine 8-Bit-Zeitschleife erklärt. Wenn Sie das alles schon wissen, blättern Sie es trotzdem kurz durch. Die Zeitberechnungen und die Taktfrequenzen könnten einiges Neues bringen, das bei den etwas komplizierteren Zeitschleifen behilflich sein könnte.

Code einer 8-Bit-Schleife

Eine Zeitschleife mit einem 8-Bit-Register sieht in Assembler folgendermaßen aus:

.equ c1 = 200 ; Anzahl Durchläufe der Schleife
	ldi R16,c1 ; Lade Register mit Schleifenwert
Loop: ; Schleifenbeginn
	dec R16 ; Registerwert um Eins verringern
	brne Loop ; wenn nicht Null dann Schleifenbeginn
Praktischerweise gibt die Konstante c1 die Anzahl Schleifendurchläufe direkt an. Mit ihr kann die Anzahl der Durchläufe und damit die Verzögerung variiert werden. Da in ein 8-Bit-Register nur Zahlen bis 255 passen, ist die Leistungsfähigkeit arg eng beschränkt.

Prozessortakte

Für die Zeitverzögerung mit einer solchen Schleife sind zwei Größen maßgebend: Die Anzahl Prozessortakte, die die einzelnen Instruktionen benötigen, stehen in den Datenbüchern der AVRs. Und zwar ziemlich weit hinten, unter "Instruction Set Summary", in der Spalte "#Clocks". Demnach ergibt sich folgendes Bild:

.equ c1 = 200 ; 0 Takte, macht der Assembler alleine
	ldi R16,c1 ; 1 Takt
Loop: ; Schleifenbeginn
	dec R16 ; 1 Takt
	brne Loop ; 2 Takte wenn nicht Null, 1 Takt bei Null
Damit setzt sich die Anzahl Takte folgendermaßen zusammen:
  1. Laden: 1 Takt, Anzahl Durchläufe: 1 mal
  2. Schleife mit Verzweigung an den Schleifenbeginn: 3 Takte, Anzahl Durchläufe: c1 - 1 mal
  3. Schleife ohne Verzweigung an den Schleifenbeginn: 2 Takte, Anzahl Durchläufe: 1 mal
Damit ergibt sich die Anzahl Takte nt zu:

nt = 1 + 3*(c1-1) + 2

oder mit aufgelöster Klammer zu:

nt = 1 + 3*c1 - 3 + 2

oder halt noch einfacher zu:

nt = 3*c1

Jetzt haben wir die Anzahl Takte.

Taktfrequenz des AVR

Die Dauer eines Takts ergibt sich aus der Taktfrequenz des AVR. Die ist gar nicht so einfach zu ermitteln, weil es so viele Möglichkeiten gibt, sie auszuwählen oder zu verstellen: Haben Sie aus all dem Durcheinander jetzt herausgefunden, mit wieviel MHz der AVR nun eigentlich läuft (fc), dann ergibt sich die Dauer eines Prozessortakts (tc) zu:

tc [µs] = 1 / fc [MHz]

Bei 1,2 MHz Takt (ATtiny13, interner RC-Oszillator mit 9,6 MHz, CLKPR = 8) sind das z.B. 0,83 µs. Die restlichen Stellen können Sie getrost vergessen, der interne RC-Oszillator ist so arg ungenau, dass weitere Stellen eher dem Glauben an Zauberei ähneln.

Zeitverzögerung

Mit der Anzahl Prozessortakte von oben (nc=3*c1, c1=200, nc=600) und 1,2 MHz Takt ergibt sich eine Verzögerung von 500 µs. Mit maximal 640 µs ist die Maximalbegrenzung dieser Konstruktion erreicht.

Verlängerung!

Mit folgendem Trick können Sie noch etwas Verlängerung herausholen:

.equ c1 = 200 ; 0 Takte, macht der Assembler alleine
	ldi R16,c1 ; 1 Takt
Loop: ; Schleifenbeginn
	nop ; tue nichts, 1 Takt
	nop ; tue nichts, 1 Takt
	nop ; tue nichts, 1 Takt
	nop ; tue nichts, 1 Takt
	nop ; tue nichts, 1 Takt
	dec R16 ; 1 Takt
	brne Loop ; 2 Takte wenn nicht Null, 1 Takt bei Null
Jetzt braucht jeder Schleifendurchlauf (bis auf den letzten) acht Takte und es gelten folgende Formeln:

nc = 1 + 8*(c1 - 1) + 7

oder

nc = 8 * c1

Das verlängert die 8-Bit-Registerschleife immerhin auf 256 * 8 = 2048 Takte oder - bei 1,2 MHz - auf ganze 1,7 ms.

Das Summprogramm

Lautsprecher Immer noch nicht für die Blink-LED geeignet, aber immerhin für ein angenehmes Brummen mit 586 Hz im Lautsprecher. Schließen Sie einen Lautsprecher an Port B, Bit 0, an, fairerweise über einen Elko von einigen µF, und lassen Sie das folgende Programm auf den ATtiny13 los:

.inc "tn13def.inc" ; für einen ATtiny13
.equ c1 = 0 ; Bestimmt die Tonhöhe
	sbi DDRB,0 ; Portbit ist Ausgang
Loop:
	sbi PORTB,0 ; Portbit auf high
	ldi R16,c1
Loop1:
	nop
	nop
	nop
	nop
	nop
	dec R16
	brne Loop1
	cbi PORTB,0 ; Portbit auf low
	ldi R16,c1
Loop2:
	nop
	nop
	nop
	nop
	nop
	dec R16
	brne Loop2
	rjmp Loop
Gut brumm!

To the top of that page

©2009 by http://www.avr-asm-tutorial.net