Forum: Compiler & IDEs Bitadressierung beim ATmega


von Martin Raffelsieper (Gast)


Lesenswert?

Hallo, weiss jemand, ob und wie man einzelne Port-Bits ansprechen kann:

zur Zeit verwende ich etwa die Form PORTA = PORTA|0x01, um den PIN
PORTA-Bit0 zu setzen. Daraus resultieren aber 3oder 4 Assembler
schritte. Gibts da nichts Bitadressierbares, etwa

  "PORTA.0 = 1;"


Gruß Martin

von Matthias (Gast)


Lesenswert?

Hi

also PORTA = PORTA|0x01; wird bei meinem AVRGCC (aus aktuellem WINAVR)
zu einem SBI genauso wie PORTA = PORTA&(unsigned char)~(0x01); zu einem
CBI wird.

Matthias

von Joerg Wunsch (Gast)


Lesenswert?

Schreibt sich übrigens etwas eleganter

PORTA |= 1;

von Martin Raffelsieper (Gast)


Lesenswert?

danke für die tips!

aber weiss denn auch jemand, wie man ein Portbit toggeln kann, etwa in
der Form

   PORTA ^= 0x01;

aber ohne dass der compiler daraus

     LDI     R22,0x01         Load immediate
     IN      R24,0x1B         In from I/O location
     EOR     R24,R22          Exclusive OR
     OUT     0x1B,R24         Out to I/O location

macht? schliesslich ist das ja ein mehrfacher bytezugriff mit der
Gefahr, dass ein Interrpt "dazwischenhaut" und alles
durcheinanderbringt. Hier hätte ich gerne einen Bitbefehl!!!



Gruß M.

von Matthias (Gast)


Lesenswert?

Hi

den gibts beim AVR nicht.

Matthias

von Martin Raffelsieper (Gast)


Lesenswert?

ok, danke!

von Florian Pfanner (Gast)


Lesenswert?

Der Interrupt darf den Ablauf nicht durcheinander bringen. Um das
sicherzustellen werden die Register, welche in einer Unterroutiene
verwendet werden auf dem Stack gesichert.

Gruß, Florian

von Joerg Wunsch (Gast)


Lesenswert?

Wenn die Interruptroutine den Port selbst aber manipulieren könnte,
dann muß man das entsprechende Stück Code allerdings mit cli()/sei()
absichern.

von Florian Pfanner (Gast)


Lesenswert?

@Joerg:

ich weiß zwar nicht genau was du meinst, aber wenn der AVR in eine
Interruptroutiene springt, so wird automatisch das Interrputflag
gelöscht und nach dem Verlassen der Routiene wieder gesetzt. So kann
die Abarbeitung eines Interrupts nicht durch einen anderen Interrupt
unterbrochen werden.

Der AVR-GCC hat 2 Interruptfunktionen: einmal Signal und Interrupt. Die
eine funktion funktioniert wie oben beschrieben. Bei der anderen wird
bei Beginn der Funktion das Interruptbit wieder gesetz. So kann dieser
Interrupt durch einen weitern Interrupt unterbrochen werden.

Gruß, Florian

von Joerg Wunsch (Gast)


Lesenswert?

Nein, das meine ich nicht.  Wenn Du obige xor-Geschichte in Deinem
main() hast, eine Interruptroutine potentiell aber auf dem gleichen
Port Ausgaben machen kann, dann mußt Du die xor-erei in main() mit
einem cli()/sei() schützen um sicherzustellen, daß der temporäre
Wert, der vor dem xor vom Port gelesen wird, auch der korrekte ist.

von Florian Pfanner (Gast)


Lesenswert?

Ok, jetzt hab ichs verstanden. Ist natürlich richtig.

Gruß, Florian

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.