Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - Delays/de: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: AVR Embedded Tutorial - Delays/de

OldNewLine
1+Zur Übersichtseite [[AVR Embedded Tutorial/de]].
2+
3+## Delays für ATmega328 / Arduino
4+
5+... und natürlich andere AVR Controller.
6+
7+Genaues Timing auf den AVR Controllern ist eigentlich ganz einfach - wenn man es in Assembler macht. Einfache Schleifen in Pascal dagegen lassen sich nicht genau timen, denn man weiss nie wie der Compiler die Schleife beim nächsten Mal baut.
8+
9+So wird zum Beispiel bei Compileroption -o1 eine for-Schleife mit einer 16bit-Zählvariable angelegt, die gleiche Schleife bei -o2 und -o3 mit 8bit. Dadurch wird die Schleife fast doppelt so schnell.
10+
11+### Kurze Delays im Mikrosekundenbereich
12+
13+``` pascal
14+{$goto on} // muss angegeben sein
15+
16+procedure delay_short();
17+label
18+ loop;
19+begin
20+ asm
21+ ldi r16, 60
22+ loop:
23+ nop
24+ dec r16
25+ brne loop
26+ end['r16'];
27+end;
28+```
29+
30+Die Größe der Zählvariable muss man ausprobieren. Die Loop dauert 4 Taktzyklen, bei 8MHz wären also 2 Loops eine Mikrosekunde. Dazu kommen aber noch Einsprung in die Routine und der Compiler bastelt noch etwas Stackpointer- und Registersicherung drumrum.
31+
32+### Längere Delays im Millisekundenbereich
33+
34+``` pascal
35+{$goto on} // muss angegeben sein
36+
37+// Pause msec, 1 bis 255 msec
38+
39+procedure delay_ms(time : uint8);
40+const
41+ fmul = 1 * fcpu div 1000000;
42+label
43+ loop1, loop2, loop3;
44+begin
45+ asm
46+ ldd r20, time
47+ loop1:
48+ ldi r21, fmul
49+ loop2: // 1000 * fmul = 1000 * 1 * 8 = 8000 cycles / 8MHz
50+ ldi r22, 250
51+ loop3: // 4 * 250 = 1000 cycles
52+ nop
53+ dec r22
54+ brne loop3
55+ dec r21
56+ brne loop2
57+ dec r20
58+ brne loop1
59+ end['r20','r21','r22'];
60+end;
61+```
62+
63+Mit dieser Schleife bekommt man ein ziemlich genaues Timing im Bereich 1 bis 255msec. Die Schleife darf durch Interrupts unterbrochen werden, dann dauert sie natürlich länger.
64+
65+Die innere Schleife dauert 4 Taktzyklen pro Durchlauf, ergo 1000 Zyklen. Die mittlere Schleife macht daraus je nach Taktfrequenz 1msec (bei 1Mhz 1 Durchlauf, bei 8MHz 8 Durchläufe, bei 16MHz 16 Durchläufe). Die äußere Schleife entspricht dann der Anzahl Millisekunden.
66+
67+**Achtung!** fmul, fcpu müssen Konstanten sein. Dann berechnet der Compiler den Wert beim Kompilieren und setzt ihn fest ein. Als Variablen würde der Compiler eine Ganzzahldivision einbauen und das wollt ihr nicht wirklich - außerdem geht die Zuweisung ldi auf eine Variable schief.
68+
69+### noch längere Delays
70+
71+... im Sekundenbereich? Also echt mal, das muss doch nicht sein. Schon 50msec nimmt man vielleicht beim Startup, wenn der Controller noch auf die Peripherie warten muss. Aber im Programmablauf sind lange Delays schlechter Stil und es gibt eigentlich immer bessere Möglichkeiten.
72+
73+## Siehe auch
74+
75+- Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorial]]
76+
77+---
78+*From the Free Pascal wiki, page "AVR Embedded Tutorial - Delays/de", as it stood on 2020-01-20 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
79+Category: AVR
80+Category: Arduino
81+Category: Deutsch
82+Category: Embedded

Back to history