Forum: Projekte & Code Delay: Exakt n Ticks erzeugen (avr-gcc)


von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hi, zum Erzeugen exakter Verzögerungen hier ein Makro, das exakt die 
vorgegebene Anzahl von Ticks zur Ausführung braucht.

Dies beinhaltet natürlich nicht die Zeit evtl. ISRs.

Erlaubt sind alle Konstanten <= 0x40000 (262144), wobei für Werte 
kleiner als 0 kein Code ausgegeben wird. Zeitmaschine gibt's erst 
nächstes Jahr :-)

Verwendung zB:
1
#include "exact-delay.h"
2
3
void foo (void)
4
{
5
    exact_delay (3);
6
}
verzögert genau 3 Ticks.

Viel Spaß beim Testen

von Gast (Gast)


Lesenswert?

>Dies beinhaltet natürlich nicht die Zeit evtl. ISRs.

Was verstehst Du denn unter exakt?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Gast wrote:
> Was verstehst Du denn unter exakt?

What you type is what you get :-)

Wenn du zB eine Verzögerung von 1000 Ticks haben willst, geht das evtl. 
über eine Verzögerungsschleife.

Bei 1001 Ticks geht das dann nicht mehr, weil man keine Schleife 
hinbekommt, deren Durchlaufzeit 1 Tick ist. Daher müssen nach der 
Schleife ne bestimmte Anzahl NOPs eingefügt werden.

Diese lästige Arbeit wird von den Makros übernommen.

Ausserdem funktionieren sie auch für kleine Verzögerungen wie 0, 1, 2, 
3, 4, ... ohne daß man sich den Kopf zerbrechen muss, wenn man den Delay 
ändern/anpassen will. Bei 1000 Ticks will man ja auch nicht 1000 NOPs im 
Code rumgammeln haben :-)

von Gast (Gast)


Lesenswert?

Na ja, wenn ich 10 Takte Verzögerung haben möchte, und mir bei diesem 
"exakten" Verfahren ein Interrupt 1000 Takte daraus macht, ist mir nicht 
gedient.

Ein Vorschlag meinerseits wäre, per CLI/SEI das Timing besser 
einzuhalten. Andernfalls kann man auch for-next Schleifen verwenden, die 
dann genauso "exakte" Zeiten liefern. Bei 1000 Takten und mehr sind 
Timer die bessere Wahl.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Es ist das, was es ist: eine Warteschleife. Und kein Design-Guide oder 
Tipp-Sammlung, wann welche Strategie eingesetzt werden sollte ;-)

Es ist einfach ein weiteres Teil in einem Werkzeugkasten. Nicht mehr, 
nicht weniger.

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Habs noch etwas verbessert:

* Es geht jetzt auch für ältere Versionen der binutils
* Der erzeugte Code ist kürzer geworden:
1
  Ticks  | Anz. Befehle
2
---------+--------------- 
3
    <= 0 |      0
4
     1   |      1
5
     2   |      1
6
     3   |      2
7
     4   |      2
8
     5   |      3
9
     6   |      3
10
     7   |      4
11
     8   |      4
12
         +
13
     9   |      3
14
    10   |      4
15
    11   |      4
16
    12   |      3
17
    13   |      4
18
    14   |      4
19
    15   |      3
20
    16   |      4
21
    17   |      4
22
   ...   |    ...
23
   768   |      3 
24
   769   |      4 
25
   770   |      4 
26
         +
27
   771   |      5 
28
   772   |      6 
29
   773   |      4 
30
   774   |      5 
31
   775   |      5 
32
   776   |      6 
33
   777   |      4 
34
   ...   |    ...
35
0x40004  |      6

== EDIT ==
ARGL

Hatte eben nen Tippteufel im Post...

von Benedikt K. (benedikt)


Lesenswert?

Könntest du das ganze noch auf längere Delays erweitern? Dann hättest du 
damit nämlich eine bessere delay Funktion geschaffen, als das was der 
gcc mitliefert.

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Benedikt K. wrote:
> Könntest du das ganze noch auf längere Delays erweitern?

hmmm... eigentlich wollte ich ja keine Monster-Makros schreiben...

Hab's erweitert auf ein Maximum von 0x5000007 = 83.886.087 Ticks.

Vielleich kann das auch mal jemand testen, der nen anderen Simulator als 
Brain 0.9 hat?

von Benedikt K. (benedikt)


Lesenswert?

Vielen Dank, ich werde es nachher mal an einem echten AVR nachmessen. 
83.886.087 Ticks sind rund 4s (bei 20MHz), das sollte eigentlich für 
alle Fälle ausreichen. Klar, für Verzögerungen größer als ein paar ms 
ist ein Timer sinnvoll, aber z.B. für eine Wartezeit bei einer Init 
reicht solch ein einfaches Delay. Und es ist schön, wenn diese eine 
Delay Funktion eben alles kann, von 1 Tick bis >4s, dann kann man diese 
universell einsetzen.

von Mehmet K. (mkmk)


Lesenswert?

Ich habe es mal im AVR-Studio mit 0x5000007 durchlaufen lassen. Stimmt 
exakt.
Danke für dieses nette Weihnachtsgeschenk.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi, danke. Könntest du auch mal für ein paar kleinere Werte testen?

Ist blöd, ich weiß, weil der Wert ja konstant sein muss. Könnte man das 
Testen irgendwie automatisieren? zB mal Durchtesten für alle Werte 
0...1000?

Dazu müsste man AVR-Studio skripten können bzw. batch-Jobs laufen 
lassen.

Der Grund dafür ist, weil immer anderer Code generiert wird abhängig von 
der Verzögerung.

Daß es also für eine Verzögerung stimmt, heisst nicht automatisch, daß 
es auch für einen anderen Delay korrekt ist. Auch dann nicht, wenn der 
Delay kleiner ist.

von Mehmet K. (mkmk)


Lesenswert?

Keine Ahnung wie man in AVR-Studio skriptet.
Ich habe jetzt mal folgede Werte getestet und sie sind alle i.O.
1
5
10 bis und mit 50
100
500
1000
5000
10000
50000

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.