Arduino Nano Every vs MKR 1000 Portspeed

#7040107
Lesenswert?

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.
Angehängte Dateien:
#7040130
Lesenswert?

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.
Gast #7040162
Lesenswert?

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.
#7040169
Lesenswert?

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.
#7040224
Lesenswert?

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.
#7041678
Lesenswert?

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.
#7041831
Lesenswert?

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.

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