Pin toggle bei Atmega 8

Gast #1655591
Ich hab mal iwo gelesen, dass einige AVRs bei Schreiben einer 1 nach 
PORTin das entsprechende Pin togglen, sofern es als Ausgang gesetzt ist. 
Im Datenblatt des ATmega8 steht, das PORTin read-only ist.

Stimmt das mit dem Toggeln? Für welche AVRs geht das? Ist das ein 
undokumentiertes Feature?
Gast
Z.B. aus dem Atmega48 Datenblatt:
---------------Zitat-----------------------------------
The Port Input Pins I/O location is read only, while the Data Register 
and the Data Direction Register are read/write. However, writing a logic 
one to a bit in the PINx Register, will result in a toggle in the 
corresponding
bit in the Data Register.
---------------Zitatende-------------------------------
mega644p kann das, mega128 kann es noch nicht. Gibt es ein #define, 
welches ich im C-Programm abfragen kann?

Ich möchte abhängig vom eingestellten Prozessor autom. die beiden Fälle 
unterscheiden.
1
PORTB ^= ( 1 << PB0 ); 
2

3
bzw.
4

5
PINB |= ( 1 << PB0 );

Wenn vom Prozessor her möglich, ist Weg über PINB der bessere, weil er 
weniger Takte kostet und kein read-modify-write durchführt (was ein 
Problem erzeugt, wenn zwischen "read" und "write" ein Interrupthandler 
oder ein anderer Thread das gleiche mit einem anderen Pin am selben Port 
versucht).
Gast
Hallo,
warum funktioniert bei einem Mega2560 zwar:

PINB |= ( 1 << PB0 );
oder
PINB |= (1 << PINB4);

(ohne die weiteren Portpins zu beeinflussen)

jedoch folgendes nicht:
(toggeln dieses Pins funktioniert schon, jedoch werden alle anderen Pins 
des Ports auf Low gezogen)

PINL |= (1 << PINL4);

die weiteren Varianten funktionieren wieder

PINL = (1<<PINL4);
PINL = (1<<PINL7)|(1<<PINL4);
PINL = 0x90;
PINL = 0x10;

oder retten in variable:
test = PINL;
test|= 0x10;
Chris schrieb:
> jedoch folgendes nicht:
> (toggeln dieses Pins funktioniert schon, jedoch werden alle anderen Pins
> des Ports auf Low gezogen)
>
> PINL |= (1 << PINL4);

Weil man da in die Fallgrube tappt, daß SBI nicht auf PORTL geht.

Michael R. schrieb:
> Also ich toggle einen Pin folgendermaßen:
>  PORTB ^= ( 1 << PB0 );

Mache ich auch grundsätzlich so.
Die paar gesparten Zyklen sind es nicht wert, daß man in Fallgruben 
tappt und der Code schlechter zu verstehen ist.
@Daniel (Gast)


>> Schau dir halt die Doku zu sbi/cbi an.

>Steht in der Doku auch drin warum es bei Port B funktioniert und bei
>Port L nicht?

Sicher. Weil sbi/cbi nur einen kleinen Teil der IO-Adressen ansprechen 
kann, Port L aber zu weit oben im Adressbereich liegt.
Gast
Vielen Dank an alle, habe mir dass mit PortL fast schon so gedacht.

Habe mittlerweile auch die richtigen Worte im Datenblatt gefunden.

8.4.1
General Purpose I/O Registers
The ATmega640/1280/1281/2560/2561 contains three Genera
l Purpose I/O Registers. These registers can be
used for storing any information, and they are particularly
 useful for storing global variables and Status Flags. Gen-
eral Purpose I/O Registers within the address range 0x00 - 0x1F are 
directly bit-accessible using the SBI, CBI,
SBIS, and SBIC instructions. See
“Register Description” on page 34
.

hätte mir jedoch gerne einen Hinweis unter folgendem Punkt gewünscht:

13.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.

Somit gehe ich richtig in der Annahme, dass ich bis einschließlich PortG 
bit adressieren kann und ab PortH nicht mehr.

Gruss
Chris

verwendetes Datenblatt:
http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 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.