atmega168: Minimale Impulsbreite am Portausgang?

OP #898312
Lesenswert?
• ▲
▼
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
#898408
Lesenswert?
• ▲
▼
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...
#898437
Lesenswert?
• ▲
▼
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.
#898460
Lesenswert?
• ▲
▼
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.
#898467
Lesenswert?
• ▲
▼
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...)
#898504
Lesenswert?
• ▲
▼
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?

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