Hallo zusammen.
Beim testen div. Boards habe ich eine interessante Entdeckung gemacht.
Beim Arduino Nano Every konnte ich eine Portspeed (HIGH und dann direkt
wieder LOW) mit DigitalWrite von max. 3,6µs (Foto:
NanoEveryDigitWrite.PNG) pro Cycle erreichen.
1
//LOOP:
2
digitalWrite(TEST_PIN,HIGH);
3
digitalWrite(TEST_PIN,LOW);
Dieser hat ja eine Clock von 20MHz.
Jetzt habe ich das ganze mit einem MKR 1000 verglichen der ja eine Clock
von 48MHz hat. Ich hätte jetzt erwartet, dass ich somit eine mind.
doppelte Geschwindigkeit habe, messen konnte ich für den Cycle jedoch
nur 3,4µs. (Foto: MKR_digiWrite.PNG).
Kann mir das Verhalten jemand erklären?
Liegt es daran, dass der MRK einen völlig anderen Prozessor hat und
dieser auf den Ausgangsports deutlich langsamer ist?
Ich folgere daraus, dass die MHz Zahl nicht zwingend proportional zur
Portgeschwindigkeit sein muss, ist das richtig?
Wen es interessiert, ich habe dann auch nochmal das ganze am Nano Every
mit direkten PORT befehlen getestet und die Zustände per OR und AND
gesetzt.
1
//LOOP:
2
PORTD|=0b00000001;
3
PORTD&=0b11111110;
Cycle Speed: 0,380 µs
Das Resultat ist zudem deutlich interessant (Bild: NanoEvery_OrAnd.PNG):
Hier ist zu erkennen, dass der Prozessor anscheinend unterschiedliche
Geschwindigkeiten für AND und OR processing hat.
Bin auf eure Meinung dazu gespannt :)
LG, Markus.
Markus N. schrieb:> Hier ist zu erkennen, dass der Prozessor anscheinend unterschiedliche> Geschwindigkeiten für AND und OR processing hat.
Das bezweifel ich ganz stark...
Selbst wenn du direkt auf die Register zugreifst, nutzt du Arduino und
somit läuft im Hintergrund z.B. der Timer für die millis usw.
Wenn der genau da zuschlägt, dann würde es auch so aussehen.
AND und OR brauchen genau 1 Takt (50ns @20MHz) beim ATmega4808/4809.
> Cycle Speed: 0,380 µs> Das Resultat ist zudem deutlich interessant (Bild: NanoEvery_OrAnd.PNG):> Hier ist zu erkennen, dass der Prozessor anscheinend unterschiedliche> Geschwindigkeiten für AND und OR processing hat.
Wenn du diese Befehle in einer Schleife verwendest, muss der Prozessor
ja wieder auf den Schleifenbeginn springen, und in dieser Zeit bleibt
der Pin auf 0.
Markus N. schrieb:> Beim Arduino Nano Every konnte ich eine Portspeed (HIGH und dann direkt> wieder LOW) mit DigitalWrite von max. 3,6µs (Foto:
Was für ein Kauderwelsch. "eine Portspeed". AUA!
> NanoEveryDigitWrite.PNG) pro Cycle erreichen.//LOOP:> digitalWrite(TEST_PIN, HIGH);> digitalWrite(TEST_PIN, LOW);> Dieser hat ja eine Clock von 20MHz.
Nein, hat er nicht, bestenfalls einen CPU-Takt von 20 MHz.
> Jetzt habe ich das ganze mit einem MKR 1000 verglichen
Was ist das? Einer er Millionen Arduino Ableger? Link?
> der ja eine Clock> von 48MHz hat. Ich hätte jetzt erwartet, dass ich somit eine mind.> doppelte Geschwindigkeit habe, messen konnte ich für den Cycle jedoch> nur 3,4µs. (Foto: MKR_digiWrite.PNG).> Kann mir das Verhalten jemand erklären?
Ja, da bremst wohl jemand, vermutlich die Arduino-Funktionen.
> Liegt es daran, dass der MRK einen völlig anderen Prozessor hat und> dieser auf den Ausgangsports deutlich langsamer ist?
Kann sein.
> Ich folgere daraus, dass die MHz Zahl nicht zwingend proportional zur> Portgeschwindigkeit sein muss, ist das richtig?
Ist auch so. Ein Raspberry Pi mit seinen 1GHz++ ist beim IO-Pins wackeln
nicht viel schneller als ein 50 MHz ARM.
> Wen es interessiert, ich habe dann auch nochmal das ganze am Nano Every> mit direkten PORT befehlen getestet und die Zustände per OR und AND> gesetzt.//LOOP:> PORTD |= 0b00000001;> PORTD &= 0b11111110;> Cycle Speed: 0,380 µs
Ja, voll cool, cycle speed! Mein Gott. Schon mal überlegt, daß ein
"Speed" meist was mit m/s zu tun hat und eine Periodendauer eher was mit
s.
> Das Resultat ist zudem deutlich interessant (Bild: NanoEvery_OrAnd.PNG):> Hier ist zu erkennen, dass der Prozessor anscheinend unterschiedliche> Geschwindigkeiten für AND und OR processing hat.
Nö. Das ist der Sprungbefehl zum Schleifenanfang.
Karlo schrieb:> Markus N. schrieb:>>1> //LOOP:> 2> PORTD |= 0b00000001;> 3> PORTD &= 0b11111110;> 4>>> Cycle Speed: 0,380 µs>> Das Resultat ist zudem deutlich interessant (Bild: NanoEvery_OrAnd.PNG):>> Hier ist zu erkennen, dass der Prozessor anscheinend unterschiedliche>> Geschwindigkeiten für AND und OR processing hat.>> Wenn du diese Befehle in einer Schleife verwendest, muss der Prozessor> ja wieder auf den Schleifenbeginn springen, und in dieser Zeit bleibt> der Pin auf 0.
Hey Karlo, das ist ein guter Hinweis! Dann muss ich also mehrmals
hintereinander die Pins toggeln und dann messen, bevor der Loop kommt.
Werde ich ausprobieren.
Markus N. schrieb:> Kann mir das Verhalten jemand erklären?
Das Datenblatt und die "Clock-Configuration" des MC. Diese ist, wie der
Name shcon sagt, konfigurierbar.
Hallo,
befasse dich einmal mit Bit Operationen.
Gezielt Bits setzen und löschen macht man üblicherweise so
1
var=var|_BV(0);
2
var=var&~_BV(0);
Wenn du nichts an den Every / IDE Einstellungen geändert hast, dann
taktet dieser default mit 16MHz.
Ändere die IDE Einstellungen auf "NONE" Register Emulation und schlage
das Manual Kapitel 16 auf.
Verwende entweder die VPORT Register für Bit Manipulationen. Oder mach
dir das Leben leichter und verwende die PORT Register mit ihren Extra
Registern. Dann spart man sich eigene Bit Manipulationen ohne Einbußen.
1
bspw.
2
PORTx.DIRSET
3
PORTx.OUTSET
4
PORTx.OUTCLR
5
PORTx.OUTTGL
Damit einfach nur das/die gewünschte(n) Bit(s) setzen! die geändert
werden sollen. Hinter die Logik kommste ganz schnell.
Veit D. schrieb:> Hallo,>> befasse dich einmal mit Bit Operationen.> Gezielt Bits setzen und löschen macht man üblicherweise so>
1
>var=var|_BV(0);
2
>var=var&~_BV(0);
3
>
> Wenn du nichts an den Every / IDE Einstellungen geändert hast, dann> taktet dieser default mit 16MHz.>> Ändere die IDE Einstellungen auf "NONE" Register Emulation und schlage> das Manual Kapitel 16 auf.>> Verwende entweder die VPORT Register für Bit Manipulationen. Oder mach> dir das Leben leichter und verwende die PORT Register mit ihren Extra> Registern. Dann spart man sich eigene Bit Manipulationen ohne Einbußen.>
1
>bspw.
2
>PORTx.DIRSET
3
>PORTx.OUTSET
4
>PORTx.OUTCLR
5
>PORTx.OUTTGL
6
>
> Damit einfach nur das/die gewünschte(n) Bit(s) setzen! die geändert> werden sollen. Hinter die Logik kommste ganz schnell.
Hi Veit,
oh das sind völlig „neue“ Möglichkeiten für mich die du schreibst.
Diese Commands kannte ich bisher nicht. Vielen Dank dafür!
Werde mir das genauer ansehen.
Hallo,
_BV(x) ist ein Makro. Damit wird das angegebene Bit an Ort und Stelle
geschoben. Das Makro ist C Standard.
Das andere PORTx. usw. sind Namen von Registern, sind keine Kommandos.
Überlicherweise so geschrieben wie man es im Manual vorfindet.