delay(nanosekunden)?

Gast #1921803
Lesenswert?

Hallo,

in meiner bisherigen "Programmierlaufbahn" bin ich mit delay(ms) immer 
gut
ausgekommen, allerdings suche ich momentan nach einer
delay(nanosekunden)- Funktion.

Reicht es, wenn ich ich bei
1
uint16_t max = 262.14/F_CPU*1000000;
einfach hinten eine Null mehr hinzufüge?.... und ist das auch bei 8bit
Mikrocontrollern möglich?

Danke im Voraus
1
#ifndef F_CPU
2
#define F_CPU 7372800UL
3
#endif
4

5
#include <avr/delay.h>
6

7
 void delay_ms(unsigned long ms)
8
 {
9
  uint16_t max = 262.14/F_CPU*1000000;
10
  for (uint16_t z = ms/max; z > 0; z--) _delay_ms(max);
11
  _delay_ms(ms%max);
12
 }
#1921831
Lesenswert?

Damien schrieb:
> Geht das auch so?

Wenn du die Zeit die, die while-Schleife benötigt mit einrechnest 
(ASM-Listing ansehen und Takte zählen) könnte dies durchaus 
funktionieren. Wenn du nicht unbedingt sehr lange Verzögerungen 
brauchst, dann tut es auch ein unsigned char.
Welchen Compiler verwendest du?
Michael G. schrieb:
> Wie
> auch, eine einzige Taktperiode ist bei 20MHz Systemtakt 50ns lang.
Stimmt, aber manche AVRs kommen mit einer PLL so weit ich weiß auf bis 
zu 64MHz Timertakt.
Gast #1921860
Lesenswert?

Ich empfehle Dir ebenfalls, das ASM-Listing anzuschauen und Takte zu 
zählen.

Meine Empfehlung:
ein Macro, keine Subroutine (deren Aufruf schon etliche Zyklen bruacht).

#define dly(times) {do while(--times);}

habe ich jetzt nicht ausprobiert, aufpassen, dass der Optimierer noch 
etwas davon übrig lässt, evtl.
#define dly(times) {do asm(nop);while(--times);}

Die while(--times) abfrage ist sehr zeiteffektiv, da sie in
dec times
bne
übersetzt wird (anstelle eines Vergleiches wird das Zero-Flag 
verwendet).


Oder einfach an der Stelle im Code einige asm(nop); einfügen.
Moderator (Firma: Titel) Persönliche Seite #1921865
Lesenswert?

Damien schrieb:
> allerdings suche ich momentan nach einer delay(nanosekunden)- Funktion.
Sag doch einfach mal, warum und wofür du so etwas brauchst...

Zum Hintergrund: wenn du das Datenblatt eines uC mal gelesen hast (das 
ist eine interessante Lektüre, besonders für jemanden, der so einen uC 
verwendet), dann hast du auch gesehen, dass der alle Aktionen 
taktgesteuert ausführt. Jeder (Assembler-)Befehl braucht eine bestimmte 
Anzahl Takte. Und mit einem 10MHz-Takt sind das dann schnellstenfalls 
100ns (z.B. für einen NOP). Weil ja auch die Befehle vor und nach dem 
NOP Zeit verbrauchen, kommst du aber niemals tatsächlich auf so eine 
kurze Zeit. Und vor allem: du kannst nicht sagen: ich möchte eine 
Verzögerung um 266ns...
Gast #1921889
Lesenswert?

Luk4s K. schrieb:
>> Wie auch, eine einzige Taktperiode ist bei 20MHz Systemtakt 50ns lang.
> Stimmt, aber manche AVRs kommen mit einer PLL so weit ich weiß auf bis
> zu 64MHz Timertakt.

Ja, und was sollte das bringen? Damit kann man den AVR trotzdem nicht 
mit höherer Auflösung als einen Taktzyklus warten lassen.

eProfi schrieb:
> Meine Empfehlung:
> ein Macro, keine Subroutine (deren Aufruf schon etliche Zyklen bruacht).

Oder eine Inline-Funktion. Die hat unter anderem den Vorteil, daß der 
Parameter einen definierten Typ hat.

> #define dly(times) {do while(--times);}
>
> habe ich jetzt nicht ausprobiert, aufpassen, dass der Optimierer noch
> etwas davon übrig lässt, evtl.

Davon wird er nichts übrig lassen.

> #define dly(times) {do asm(nop);while(--times);}

Wozu eigentlich ein nop?

#define dly(times) {do asm volatile (""::);while(--times);}

> Die while(--times) abfrage ist sehr zeiteffektiv, da sie in
> dec times
> bne
> übersetzt wird (anstelle eines Vergleiches wird das Zero-Flag
> verwendet).

Kommt auf den Typ von times an.
#1922111
Lesenswert?

Rolf Magnus schrieb:
> Luk4s K. schrieb:
>>> Wie auch, eine einzige Taktperiode ist bei 20MHz Systemtakt 50ns lang.
>> Stimmt, aber manche AVRs kommen mit einer PLL so weit ich weiß auf bis
>> zu 64MHz Timertakt.
>
> Ja, und was sollte das bringen? Damit kann man den AVR trotzdem nicht
> mit höherer Auflösung als einen Taktzyklus warten lassen.
Stimmt, macht tatsächlich nur minder Sinn.
#1922163
Lesenswert?

>Nur mal 'ne wahrscheinlich doofe Frage: Das zwischen Millisekunden und
>Nanosekunden 10 hoch 6 liegt und Mikrosekunden genau dazwischen, ist
>bekannt?

Offensichtlich nicht, sonst würde man nicht solche Fragen stellen (vor 
allem vor dem Hintergrund, daß ein AVR-Takt üblicherweise bereits 
etliche 10ns braucht - er also ohnehin nicht genauer auflösen kann).
Vermutlich meinte er eher µs - das könnte ich mir noch so einigermaßen 
als sinnvoll vorstellen. Wenn es wirklich um ns geht, dann machen es 
vermutlich auch reine nops, die eine Verzögerung entsprechend der 
Taktperiode bwerkstelligen.
Moderator (Firma: Titel) Persönliche Seite #1922165
Lesenswert?

Jens G. schrieb:
> Offensichtlich nicht, sonst würde man nicht solche Fragen stellen
Jaja, Rätselraten ist alles, was uns bleibt...  ;-)
Lothar Miller schrieb:
> Damien schrieb:
>> allerdings suche ich momentan nach einer delay(nanosekunden)- Funktion.
> Sag doch einfach mal, warum und wofür du so etwas brauchst...
Gast #1923260
Lesenswert?

Hallo,
danke für die vielen Anregungen :)

Ich möchte ein Dreiecksignal generieren. Dabei soll die Frequenz
300 Mhz betragen(diese muss später erhöht werden)
Ich habe mich heute entschieden einen PIC18F2620 zu nehmen.
Dieser hat 8bit, also 255 Schritte...
Wenn ich jetzt also die Periodendauer T= 1/300Hz durch 4 
teile(Dreieckspitzen) erhalte ich 1/1200....
Zwischen jeden Schritt(Erhöhung von 'fr') soll nun eine Verzögerung 
eingebaut werden.
Also (1/1200)/255 = 3,3 x (10^-6)
Das sind doch 0,0000033 Sekunden und 3300 Nanosekunden bzw 3,3 
Mikrosekunden.

Sollte doch so stimmen oder? Fehlt mir nur noch die Delay-Funktion :)
1
void dreieck_signal_ausgabe()        // Ausgabe des Dreiecksignals
2
{  
3
  while(fr <= 255){        // Hochzählen
4
  fr++;
5
  dreieck_REG = fr;                               // LATA
6
  //delay nano/mikro
7
  }
8

9
  while(fr >= -255){                          // Runterzählen
10
  fr--;
11
  dreieck_REG = fr;                               // LATA
12
        //delay nano/mikro
13
  }
14
}
Gast #1923309
Lesenswert?

Ich möchte ein elektromagnetisches Feld erzeugen.
Dabei wird das digitale Signal über ein R2R Netzwerk in ein analoges 
Signal
umgewandelt und mit Hilfe von OPs wird das elektromagnetische Feld 
erzeugt.
Im Anhang befinden sich die Taktfrequenzen. Soweit komme ich noch mit, 
aber
bei 'branch' verstehe ich nicht mehr viel :(
Angehängte Dateien:
#1923345
Lesenswert?

Damien schrieb:
> bei 'branch' verstehe ich nicht mehr viel :(

Du solltest unbedingt die Assemblersprache deines PIC lernen und 
erstmal anfangen auszurechnen wieviele Befehle du zur Verfügung hast um 
deinen Takt überhaupt zu erzeugen.
Das werden nicht viele sein.
Dann musst du ausrechnen wieviele Befehle du mindestens brauchst um 
einen Schritt zu erzeugen. Das werden einige sein.

Deine Anwendung befindet sich definitiv sehr nah an der oberen 
Leistungsgrenze des Mikrokontrollers und die 10khz Anwendung (mit 256 
Schritten) ist mit Sicherheit über der Leistungsfähigkeit des 
Controllers.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren