Forum: Mikrocontroller und Digitale Elektronik delay(nanosekunden)?


von Damien (Gast)


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
 }

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Nein, tut es nicht.

Rechne dir aus, wieviele Takte deine Zeit lang ist (das werden bei ns 
nicht allzu viele sein) und bau enstprechende Pausen.

Gruß
Lasse

von Damien (Gast)


Lesenswert?

Hmm,
ich weiß nicht wirklich was Sie meinen...

Geht das auch so?
1
  void _nano(int nop){
2
   int i = 0;
3
    while(i != nop){
4
     _asm nop _endasm
5
     i++;
6
    }
7
  }

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Nein.
Du kannst einen Timer verwenden, aber bis auf den unteren 
Nansosekundenbereicha aufzuloesen ist mit einem AVR nicht moeglich. Wie 
auch, eine einzige Taktperiode ist bei 20MHz Systemtakt 50ns lang.

von Lukas K. (carrotindustries)


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.

von Qertz (Gast)


Lesenswert?

Damien schrieb:
> ausgekommen, allerdings suche ich momentan nach einer
> delay(nanosekunden)- Funktion.

Bist du sicher?
Ein Delay im Nanosekundenbereich ist auf AVRs nicht sinnvoll...

von eProfi (Gast)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von Rolf Magnus (Gast)


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.

von DirkB (Gast)


Lesenswert?

Damien schrieb:
> 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?


Zwischen ms und ns ist mehr als eine Null unterschied.

von Lukas K. (carrotindustries)


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.

von Lutz (Gast)


Lesenswert?

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

von Jens G. (jensig)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von DirkB (Gast)


Lesenswert?

Vielleicht meinte er auch nur 0,1 ms, da er ja auch nur eine Null 
dranhängen wollte.

von Damien (Gast)


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
}

von Floh (Gast)


Lesenswert?

Damien schrieb:
> 300 Mhz betragen(diese muss später erhöht werden)
     ^^
Ist das M für mega beabsichtigt ??
:-)

von Michael B. (mb_)


Lesenswert?

Damien schrieb:
> Dabei soll die Frequenz 300 Mhz betragen(diese muss später erhöht werden)

Na dann besorge dir mal einen mikrocontroller mit 1 bis 2 GHz CPU Takt. 
Denn den wirst du so ungefähr je nach Anwendung benötigen. (Mal davon 
abgesehen, was dort am Pin für ein "Rechteck-"Gemüse bei 300MHz 
rauskommt)

von Damien (Gast)


Lesenswert?

Nein^^ 300Hz :D

von Huch (Gast)


Lesenswert?

Sich über den Unterschied von 300Hz, 300kHz und 300MHz bzw. 300ms oder 
300ns nicht im klaren zu sein und das dann auch noch zu kommunizieren 
ist für uns, nun sagen wir mal, ein wenig anstrengend.
Denn das sind Unterschiede die hier sehr wichtig sind.
Bitte achte darauf etwas besser.

von Eddy C. (chrisi)


Lesenswert?

Ich denke, es ist Zeit, die Popcorn in die Mikrowelle zu legen... 300Mhz 
Dreieck in Software, das ist ganz grossartig und auch Richtung weisend. 
Thumbs up!

von Michael B. (mb_)


Lesenswert?

Damien schrieb:
> Nein^^ 300Hz :D

Naja, 300Hz Rechteck wäre kein Problem. Aber Dreieck mit 256 Schritten? 
Das halte ich schon ohne delay Funktion for hart an der Grenze des 
überhaupt machbaren.
Welche Taktfrequenz hat der Mikrocontroller? Wieviel Takte braucht der 
so pro increment und branch instruktion?

von Damien (Gast)


Lesenswert?

Entschuldigt!! Das war nicht meine Absicht!

Ich spreche von 300 Hz und wie gesagt, soll die Frequenz später erhöht 
werden.. Dann bis 10 kHz( das k ist beabsichtigt ).
Das Ganze läuft dann innerhalb 1s(sekunde) ab.

von Eddy C. (chrisi)


Lesenswert?

Schreibe mal was über die Anwendung. Mag sein, dass eine schnuckelige 
DDS in Software genau das Richtige für Dich ist.

von Damien (Gast)


Angehängte Dateien:

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 :(

von Michael B. (mb_)


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.

von Rage (Gast)


Lesenswert?

Hmm, würde es Sinn machen, nur 128 Schritte pro Amplitude zu nehmen?
Dann könnte man das schön mit Mikrosekunden lösen...
Also 4 Bit

von Karl H. (kbuchegg)


Lesenswert?

Rage schrieb:
> Hmm, würde es Sinn machen, nur 128 Schritte pro Amplitude zu nehmen?

Das kannst nur du wissen, wie genau dein quantisiertes Dreieck an einem 
realen Dreick sein muss.

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.