Delay: Exakt n Ticks erzeugen (avr-gcc)

OP Persönliche Seite #1086190
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
Angehängte Dateien:
OP Persönliche Seite #1086217
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 :-)
Gast #1086505
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.
OP Persönliche Seite #1087155
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...
Angehängte Dateien:
#1087289
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.
OP Persönliche Seite #1087989
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.