Hallo, wie kurz kann denn der kürzestmögliche Impuls am Ausgang eines Ports sein, den ich per Software erzeugen kann? Mein gemessener Impuls dauert 2 CPU-Takte. Aber, wenn ich das richtig verstanden habe, sollte ja eine Impulsdauer von 1 Takt möglich sein, weil die SBI und CBI Befehle laut Datenblatt nur 1 cycle brauchen. Ich mach das so in C: PORTD |= (1<<PORTD3); PORTD &= ~(1<<PORTD3); Im Disassembler schauts dann so aus: +00000166: 9A5B SBI 0x0B,3 Set bit in I/O register +00000167: 985B CBI 0x0B,3 Clear bit in I/O register Am Logikanalysator schauts dann so aus: Clck: 010101010101010101010101010 Port: 000000000111100000000000000 Also, der Port ist 2 Takte lang auf 1, und nicht nur einen. Weiß jemand, woran das liegt könnte? Danke, Johngo
Ich weiß jetzt nicht, in welch komischem Datenblatt Du nachgesehen hast, aber in der Befehlssatzdokumentation steht recht eindeutig, dass cbi und sbi zwei Taktzyklen benötigen! EDIT: In meinem Datenblatt vom ATMega48/88/168 steht ebenfalls zwei Taktzyklen...
Ja, genau, alles klar! Da hab ich wohl in die Spalte vom xmega geschaut! Danke! Johngo
Gehts über einen Schreibzugriff auf PINx evtl schneller? Im Atmega48-Datenblatt unter "12.2.2": 12.2.2 Toggling the Pin Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port. also
1 | PIND=(1<<PIND3); |
2 | PIND=(1<<PIND3); |
Mal ausprobieren, ob das schneller ist...
Ja, geht schneller. cbi/sbi müssen halt Lesen, verodern und zurückschreiben.
Benedikt K. wrote:
> Ja, geht schneller.
Wie das? Der Compiler macht sicher aus den beiden Zeilen von Ernst auch
ein sbi (wie ja schon im Original). Und sbi braucht nunmal je 2 Takte,
da ändert es auch nichts, wenn man auf PIND statt PORTD zugreift.
Es gibt afaik keine einzige Möglichkeit, per Software an einen Pin etwas
in weniger als zwei Taktzyklen auszugeben.
Johannes M. wrote: > Wie das? Der Compiler macht sicher aus den beiden Zeilen von Ernst auch > ein sbi (wie ja schon im Original). Und sbi braucht nunmal je 2 Takte, > da ändert es auch nichts, wenn man auf PIND statt PORTD zugreift. Warum sollte er? Da steht doch kein "|=", sondern "=", und daraus macht der Compiler ein OUT, was 1 Takt braucht.
Stefan Ernst wrote: > Warum sollte er? Da steht doch kein "|=", sondern "=", und daraus macht > der Compiler ein OUT, was 1 Takt braucht. Für ein out muss aber erst mal ein Wert in einem Rechenregister stehen, und der kommt mit ldi da rein, was der zweite Takt ist... (OK, im Prinzip hast Du natürlich Recht: Das ldi muss nur einmal ganz am Anfang gemacht werden. Demnach haut es natürlich doch hin...)
Johannes M. wrote:
> Für ein out muss aber erst mal ein Wert in einem Rechenregister
Das muss man aber nur einmal machen, nicht jedesmal.
Der Compiler macht aus dem Sourcecode von Ernst: LDI R24,0x08 OUT 0x10,R24 OUT 0x10,R24 Und damit hat man einen Puls mit einer Breite von einem Takt.
Stefan Ernst wrote: > Johannes M. wrote: >> Für ein out muss aber erst mal ein Wert in einem Rechenregister > > Das muss man aber nur einmal machen, nicht jedesmal. Richtig, siehe oben...
Sorry. Habe ich das überlesen, oder hast du nochmal editiert?
Stefan Ernst wrote:
> Sorry. Habe ich das überlesen, oder hast du nochmal editiert?
Sagen wir es so: Ich habe mein Privileg als registrierter User schamlos
ausgenutzt...
Und das funktioniert auch beim Zugriff aufs normale PORTD Schreibregister: nur 1 Takt. portD = PORTD; hibit = portD | (1 << PORTD3); lobit = portD & ~(1 << PORTD3); PORTD = hibit; PORTD = lobit;
John Go wrote: > Und das funktioniert auch beim Zugriff aufs normale PORTD > Schreibregister: nur 1 Takt. > > portD = PORTD; > hibit = portD | (1 << PORTD3); > lobit = portD & ~(1 << PORTD3); > > PORTD = hibit; > PORTD = lobit; Jo, damit veränderst Du aber jedes Mal auch alle anderen Bits im Portregister, wenn PORTD sich in der Zwischenzeit ändert, und musst außerdem darauf spekulieren, dass der µC noch genügend Register frei hat, um die beiden Konstanten in Rechenregistern zu lassen. Der ATMega168 hat extra für solche Sachen die Pin-Toggle-Funktion durch Schreibzugriff auf PINx, also warum nutzt Du sie nicht?
Genau, jetzt hab ich erst die Pin-Toggle Funktion verstanden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.