Warum nur 8 MIPS bei 16 MHz Systemtakt?

OP Persönliche Seite #3292220
Hallo zusammen!

Auf einem ATmega644P habe ich zu Testzwecken eine Dauerschleife laufen 
lassen, die nur PD6 umschaltet, sonst nichts.
Es ist ein 16 Mhz Quarz angeschlossen und die Fuses entsprechend 
programmiert:
LFUSE: 0x0F7 (0xFF ändert nichts)
HFUSE: 0xD9
EFUSE: 0xFF

1
#include <avr/io.h>
2

3
int main(void) {
4

5
  DDRA = 0x00;
6
  DDRB = 0xff;
7
  DDRC = 0xff;
8
  DDRD = (1 << DDD1) | (1 << DDD5) | (1 << DDD6) | (1 << DDD7);
9

10
  while(1) {
11

12
    PORTD |= (1 << PD6);
13
    PORTD &= ~(1 << PD6);
14

15
    PORTD |= (1 << PD6);
16
    PORTD &= ~(1 << PD6);
17

18
    PORTD |= (1 << PD6);
19
    PORTD &= ~(1 << PD6);
20

21
  }
22

23
  return 0;
24
}

Mit dem Oszi habe ich an PD6 gemessen (gelb) und gleichzeitig den 
Systemtakt an XTAL2 (blau).
Wie am Zeitcursor erkennbar, wird der Pin nach rund 125 ns umgeschaltet, 
was einer Freuquenz von 8 MHz entspricht.
Nun frage ich mich, warum der Controller für so eine leichte Aufgabe 
zwei Takte benötigt und nicht bloß einen.
Ist es möglich, dass er aus irgendwelchen Gründen nur mit 8 MHz taktet 
oder braucht er wirklich zwei Takte dafür?

Grüße,
Vinc
Angehängte Dateien:
Gast
SBI und CBI brauchen auf dem ATMega 2 Takte (im Gegensatz zum ATTiny und 
XMega):
http://www.atmel.com/images/doc0856.pdf
Seite 14 und Fußnote 5 auf Seite 15

Die OUT instruction braucht dagegen auch auf dem ATMega nur 1 Takt, 
allerdings müssen vorher die Bits für den kompletten Port in einem 
Register liegen.

Folgender asm-code müsste also 4 MHz auf PD6 ausgeben (mit Verzögerungen 
für den rjmp nach jeweils 5 Perioden):
1
ldi r16, (1<<PD6)
2
ldi r17, 0
3
loop:
4
out PORTD, r16
5
out PORTD, r17
6
out PORTD, r16
7
out PORTD, r17
8
out PORTD, r16
9
out PORTD, r17
10
out PORTD, r16
11
out PORTD, r17
12
out PORTD, r16
13
out PORTD, r17
14
rjmp loop

Auf dem Mega644 müsste auch das Toggeln über schreiben ins PIN-Register 
funktionieren:
1
ldi r16, (1<<PD6)
2
loop:
3
out PIND, r16
4
out PIND, r16
5
out PIND, r16
6
out PIND, r16
7
out PIND, r16
8
out PIND, r16
9
out PIND, r16
10
out PIND, r16
11
out PIND, r16
12
out PIND, r16
13
rjmp loop
Joachim ... schrieb:
> Moment mal. Du schreibst:
>  PORTD &= ~(1 << PD6);
> Ich vermute mal, daß das nicht einfach dem Komplementär-Befehl
> entspricht.
>
> Bei den PICs gibts da ein:
> PORTDbits.PD7 ^= 1;
> Vieleicht bietet er gcc etwas ähnliches an.
Das ist nicht PIC. Das ist C.

PORTD ^= 1; führt beim AVR und beim PIC wahrscheinlch auch, aber zu 
einem Read-Modify-Write, was wesentlich länger dauert als der eine 
sbi/cbi.

Also das:
PORTD |= (1 << PD6);
PORTD &= ~(1 << PD6);
ist effektiver.

Beim AVR gibt es aber noch PINx |= 1; Da wird wieder der sbi eingesetzt.
Damit ist Toggle-Toggle zeitlich das gleiche wie Setzen-Löschen.

mfg.
Gast
RTFM schrieb:

> SBI und CBI brauchen auf dem ATMega 2 Takte (im Gegensatz zum ATTiny und
> XMega):

Das verstehst du falsch, jedenfalls was die ATtinys betrifft. Da steht: 
"reduced core tinyAVR". Das sind nur die ganz, ganz kleinen (4,5,9,10).

Ab Tiny11 aufwärts kostet SBI/CBI 2 Takte.
A. K. schrieb:
> Thomas Eckmann schrieb:
>> XORLW ist doch mit immediate.
>
> Du willst nicht das Bit im Akku (W) toggeln, sondern im Port (f). Und
> dafür brauchst du XORWF, nicht XORLW:
> http://www.sprut.de/electronic/pic/assemble/befehle.html#xorwf
Kann ja keiner ahnen, daß W der Akku ist.

> Daumenregel: In einen PIC Befehl fester Länge passt entweder eine
> Konstante oder eine Adresse. Aber i.d.R. nicht beides.
Ja. Ist logisch.

mfg.
Markus Weber schrieb:
> Thomas Eckmann schrieb:
>> A. K. schrieb:
>>> Nope. PICs können XOR zum Port hin.
>> Nicht schlecht.
>
> Das bringt mich auf die Frage, warum Vinc nicht einfach die
> Port-Toggle-Funktion verwendet:
>
>
1
PIND|= 1<<PD6
>
> Hab jetzt nicht speziell im Datenblatt des ATmega644P geschaut, aber der
> sollte das eigentlich auch können.

Kann er auch. Aber zeitlich bringt das nichts.
Um das gleiche zu erreichen, muss
1
PIND|= 1<<PD6
ja zweimal ausgeführt werden.

mfg.
>>Das ist nicht PIC. Das ist C.
>PORTD ^= 1; führt beim AVR und beim PIC wahrscheinlch auch, aber zu
einem Read-Modify-Write, was wesentlich länger dauert als der eine
sbi/cbi.

Hmmmm...also ich bekomme auf einem 18F458 mit C18 das hier:

112:    LEDPin ^= 1;
28AC  7E8C     BTG LATD, 7, ACCESS

BTG ist:
BTG f, d, a Bit Toggle f 1 0111 bbba ffff ffff

Und er braucht dazu einen Takt.
(Firma: guloshop.de)
Thomas Eckmann schrieb:
> Markus Weber schrieb:
>> Das bringt mich auf die Frage, warum Vinc nicht einfach die
>> Port-Toggle-Funktion verwendet:
>>
>>
1
PIND|= 1<<PD6
>>
>> Hab jetzt nicht speziell im Datenblatt des ATmega644P geschaut, aber der
>> sollte das eigentlich auch können.
>
> Kann er auch. Aber zeitlich bringt das nichts.
> Um das gleiche zu erreichen, muss
>
1
PIND|= 1<<PD6
> ja zweimal ausgeführt werden.

Sorry, Tippfehler von mir, ich meinte:
1
PIND= 1<<PD6;

Das ist dann nur ein Takt.
1
.include "m8def.inc" ; durch passendes config-file ersetzen
2

3
ldi r16, 0x01
4
out DDRD, r16
5

6
loop: 
7
clr PORTD
8
ser PORTD
9

10
rjmp loop

eine taktmessung (einfach nur einen pin togglen) würde ich eher in ASM 
schreiben - und clr/ser brauchen laut meinem instructionset-ausdruck nur 
jeweils 1 takt. alternativ könnte man ein clr nach die initialisierung 
packen und in der schleife nur mehr com ausführen.

hier sinds 3 takte pro schleifendurchlauf, der overhead kann durch 
mehrfaches clr/ser einfach reduziert werden...

ok, ich habs auswendig geschrieben und mangels eines 644 auch nicht 
getestet, aber das prinzip sollte klar sein ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.