Forum: Compiler & IDEs delay-zeit in float.


von bastle (Gast)


Lesenswert?

hallo, wird diese delay so verarbeitet wie ich erwarte oder muss die 
gerundet werden (atmega32,8mhz) : _delay_us(4.5);

mfg

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Das geht so.

von bastle (Gast)


Lesenswert?

ich habe hier den code "main.lss" eingesehen und sehe, das die delay und 
portd zb nicht als asm-code erscheint, wie ich den asm-code von diesen 
einsehen?
  _asm_ volatile (
  9e:  89 e4         ldi  r24, 0x49  ; 73
  a0:  8a 95         dec  r24
  a2:  f1 f7         brne  .-4        ; 0xa0 <main+0xe>

  _delay_us(27.5);

  PORTD |= (1 << sync);

.....
......

wie genau ist die delay_us als float-zahl eigentlich?

mfg

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Mit WinAVR-20071222 sieht das anders aus.

test.c - C-Quellcode
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#define sync 3
5
6
int main(void)
7
{
8
  _delay_us(27.5);
9
  PORTD |= (1 << sync);
10
}

Übersetzt wurde mit den Einstellungen MCU=Atmega128, -Os, F_CPU=8000000.

test.lss - Ausschnitt Disassemblerlisting
1
000000ce <main>:
2
  ce:  89 e4         ldi  r24, 0x49  ; 73
3
  d0:  8a 95         dec  r24
4
  d2:  f1 f7         brne  .-4        ; 0xd0 <main+0x2>
5
  d4:  93 9a         sbi  0x12, 3  ; 18
6
  d6:  80 e0         ldi  r24, 0x00  ; 0
7
  d8:  90 e0         ldi  r25, 0x00  ; 0
8
  da:  08 95         ret

Wegen eines Bugs in der neusten GCC-Toolchain sind die C-Quellcodezeilen 
nicht enthalten.

In Adresse ce bis d2 ist die _delay_us Inline-Funktion. Aus 27.5 µs bei 
8 MHz wurde der Schleifenzähler 0x49 berechnet.

Die Genauigkeit könnte man überprüfen, indem man die Laufzeit dieses 
Abschnitts im AVR-Studio im Debugger mit dessen Stoppwatch  misst. Man 
kann auch die Taktzyklen der einzelnen Befehle im AVR Instruction Set 
Manual nachschlagen und das mit Stift und Papier ausrechnen.

Und bei Adresse d4 ist das Manipulieren des Ports.

von bastle (Gast)


Lesenswert?

...WinAVR-20071222....

wo hast du die version vom 22.12.07 her, ich habe nur die vom 21.12.07?

habe festgestellt, das die genauigkeit mindestens  immer aus einen 
durchlauf besteht "brne" ( ich glaube der keinste durchlauf hat 3 zyclen 
):
ldi  r24, 0x01
dec  r24
brne  .-4

also bei 0,5µs (8mhz) hat er einen durchlauf, sind 3 zyclen, müsste aber 
4 zyclen haben. der compiler baut selber keine nop rein.

dieses machst sich noch nicht einmal bei meinem fbas-bildaufbau 
bemerkbar.

also ich bin sehr zufrieden mit dieser zeitmessung.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

WinAVR-20071221 habe ich auch. Ich hatte Tomaten auf den Augen.

von Falk B. (falk)


Lesenswert?

@ bastle (Gast)

>wie genau ist die delay_us als float-zahl eigentlich?

Das landen des Schleifenzählers dauert 1 Takt. Ein Durchlauf dauert 3 
takte, bis auf den letzten, der dauert nur zwei. Bei _delay_ms() dauert 
das Laden des Schleifenzählers 2 Takte, ein Durchlauf vier, der letzte 
3.

MFG
Falk

von bastle (Gast)


Lesenswert?

dieses habe ich aus einem warteschleifen-generator : 8mhz, und 0,5µs

; =============================
;   Warteschleifen-Generator
;     4 Zyklen:
; -----------------------------
; warte 3 Zyklen:
          ldi  R17, $01
WGLOOP0:  dec  R17
          brne WGLOOP0
; -----------------------------
; warte 1 Zyklus:
          nop
; =============================

dann stimmt der ja nicht?oder?

von Karl H. (kbuchegg)


Lesenswert?

bastle wrote:
> dieses habe ich aus einem warteschleifen-generator : 8mhz, und 0,5µs
>
> ; =============================
> ;   Warteschleifen-Generator
> ;     4 Zyklen:
> ; -----------------------------
> ; warte 3 Zyklen:
>           ldi  R17, $01
> WGLOOP0:  dec  R17
>           brne WGLOOP0
> ; -----------------------------
> ; warte 1 Zyklus:
>           nop
> ; =============================
>
> dann stimmt der ja nicht?oder?


Warum soll das nicht stimmen?
Hier werden 4 Taktzyklen verbraten. Bei 8 Mhz dauern diese
4 Zyklen 0.5µs.

  ldi     1 Takt
  dec     1 Takt   -> das Ergebnis davon ist 0
  brne    1 Takt   weil der Branch nicht genommen wird
  nop     1 Takt
         --------
          4 Takte

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Man hätte natürlich auch der Einfachheit gleich 4 NOPs nehmen können. 
;-)

von bastle (Gast)


Lesenswert?

...Man hätte natürlich auch der Einfachheit gleich 4 NOPs nehmen 
können....

bei meiner einstellung -0s wird kein nop eingefügt sondern es wird 
mindestens immer eine schleife erstellt bei delay_µs( )........

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ja, _delay_us() und _delay_ms() machen wirklich nur einfache
Schleifen.  Es ging ja hier eher um deinen Warteschleifen-
Generator (wo auch immer er her ist).

von bastle (Gast)


Lesenswert?

...Ja, _delay_us() und _delay_ms() machen wirklich nur einfache
Schleifen.....

reicht auch vollkommen aus, wenn ich auf 0,5µs runtergehen kann bei 
8mhz. gute leistung für winvr-c.

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.