www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu delay loop von peter fleury


Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
static inline void _delayFourCycles(unsigned int __count)
{
    if ( __count == 0 )
        _asm_ __volatile__( "rjmp 1f\n 1:" );    // 2 cycles
    else
        _asm__ __volatile_ (
          "1: sbiw %0,1" "\n\t"
          "brne 1b"                              // 4 cycles/loop
          : "=w" (__count)
          : "0" (__count)
         );
}

#define delay(us)  _delayFourCycles( ( ( 1*(XTAL/4000) )*us)/1000 )


die delay funktion wird dann mit der Angabe der verzögerung ausgeführt.

z.b. delay(500) müssten 500µs delay sein.

Kann mir jemand erklären wie das ungefähr funktioniert.

Wenn count 0 ist dann habe ich ja alleine durch den overhead einige 
cycles dabei, und somit stimmen die 2 cycles ja nicht oder?

--( ( ( 1*(XTAL/4000) )*us)/1000 ) <- was wird da genau berechnet?

bitte um eure comments!!! danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ganze funktioniert unter 2 Voraussetzungen

* Für us benutzt du eine Konstante
* Der Optimizer ist eingeschaltet.

> --( ( ( 1*(XTAL/4000) )*us)/1000 ) <- was wird da genau berechnet?

Was denkst du?
Hinweis: XTAL wird gerne als Makro für die tatsächliche
Taktrequenz (in Herz) genommen.
XTAL ist also für den Compiler eine Konstante, mit zb dem
Wert 4000000 (bei 4MHz Taktfrequenz)

> Wenn count 0 ist dann habe ich ja alleine durch den overhead
> einige cycles dabei,

Nicht wenn der Optimizer eingeschaltet ist. Von der ganzen
Orgie bleibt letztendlich nur noch
  _asm_ __volatile__( "rjmp 1f\n 1:" );
übrig. Alles andere schmeist der Optimizer raus.

Autor: chriss (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-Was denkst du?
-Hinweis: XTAL wird gerne als Makro für die tatsächliche
-Taktrequenz (in Herz) genommen.
-XTAL ist also für den Compiler eine Konstante, mit zb dem
-Wert 4000000 (bei 4MHz Taktfrequenz

Das ist mir schon klar, dass die taktfrequenz in die berechnung mit 
einfließen muss, nur wie es genau funktioniert wäre interresant.

Ok. das mit dem Optimizer geht mir ein....

danke erstmal..
Also falls mir das jemand noch genau erklären könnte wäre ich froh..

danke für eure mühen..

danke karl heinz...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
chriss wrote:
> -Was denkst du?
> -Hinweis: XTAL wird gerne als Makro für die tatsächliche
> -Taktrequenz (in Herz) genommen.
> -XTAL ist also für den Compiler eine Konstante, mit zb dem
> -Wert 4000000 (bei 4MHz Taktfrequenz
>
> Das ist mir schon klar, dass die taktfrequenz in die berechnung mit
> einfließen muss, nur wie es genau funktioniert wäre interresant.

Ach komm.
Das ist doch ein simpler Dreisprung: 10 Äpfel kosten 2 Euro,
wieviel kosten 7 Äpfel.

Wenn in einer Sekunde XTAL (zb 4000000) Takte anfallen,
wieviele Takte müssen dann für 1 µs vergehen.

1µs, das sind 0.000001 oder 1E-6 Sekunden

   XTAL   .......   1
     x    .......   1E-6
-------------------------

       XTAL * 1E-6
  x = -------------  = XTAL * 1E-6
           1
                                  XTAL
oder was gleichbedeutend ist:   --------
                                1000000

jetzt wollen wir aber nicht 1 µs sondern wir wollen y µs.

Ergo:  y * XTAL
      ----------
       1000000

Wenn wir jetzt mal genau nachdenken, wollen wir ja nicht Takte
haben, die verbrutzelt werden müssen, damit y µs vergehen,
sondern wir brauchen die Anzahl der Schleifenwiederholungen.
Eine Schleifenwiederholung dauert 4 Takte, also brauchen wir

       y * XTAL
      -------------
       4 * 1000000

Schleifenwiederholungen.

Jetzt gibt es noch ein kleines C-Problem: Die Berechnungen
müssen so gestaffelt werden, dass
* es zu keinen Overflow kommt
* bei der Division nichts, oder nicht viel verloren geht.
  Wenn XTAL 4879000 ist, dann ist XTAL / 1000000 nun mal
  4 und nicht 4.879000

Daher wird ein bischen umgestellt, ein Tausender im Nenner
von den 1000000 zu den 4 verschoben ( 4 * 1000000 ergibt
dasselbe wie 4000 * 1000), und es kommt zu

  ( ( ( 1*(XTAL/4000) )*us)/1000 )

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.