Forum: Mikrocontroller und Digitale Elektronik Pin toggle bei Atmega 8


von Sven (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

zb der Mega48

Und nein, das ist alles schön sauber dokumentiert.

von Michael R. (dj_motionx)


Lesenswert?

Hallo !

Also ich toggle einen Pin folgendermaßen:
1
 PORTB ^= ( 1 << PB0 );

(laut Tutoral)

L.g

von Drachenbändiger (Gast)


Lesenswert?

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

von Flo (Gast)


Lesenswert?

Das togglen unterstützen nur neuere Atmel AVRs.

von dr.schmock (Gast)


Lesenswert?

Im Datenblatt unter
"I/O Ports -> Ports as General Digital I/O -> Toggling the Pin"
Der ATmega ist zu alt

von Holger M. (qibono)


Lesenswert?

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

von Chris (Gast)


Lesenswert?

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;

von Oliver S. (oliverso)


Lesenswert?

Chris schrieb:
> PINL |= (1 << PINL4);

Schau dir halt die Doku zu sbi/cbi an.

Oliver

von Peter D. (peda)


Lesenswert?

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.

von Daniel (Gast)


Lesenswert?

Oliver S. schrieb:
> Chris schrieb:
>> PINL |= (1 << PINL4);
>
> Schau dir halt die Doku zu sbi/cbi an.
>
> Oliver

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

von Falk B. (falk)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

Danke.

von Chris (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

>Somit gehe ich...

Nein. Es wird nur in andere Assembler-Befehle umgesetzt.

Mit freundlichen Grüßen Spess

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
Noch kein Account? Hier anmelden.