Forum: Mikrocontroller und Digitale Elektronik toggle eines PortBits


von justus (Gast)


Lesenswert?

Es treibt mich nun seit zwei Stunden fast in den Wahnsinn:
Ich möchte ein Bit des PortB togglen bei einem Interrupt. Interrupt und
so weiter klappt. Nur das toggeln will nicht hinhauen.
Folgendes habe ich versucht:
  in r16, PINB
        out PORTB, (r16 ^ 0b00000001)
d.h. Port B wird eingelesen, alle Bits werden belassen ausser Bit 0
(XOR Verknüpfung mit 0000 0001).

Nun bringt AVR Studio einen Fehler bei der zweiten Zeile: Illegal
Argument type or count.

Wer weiss Rat bzw. kann mir einen Link auf eine Seite geben wo solche
grundsätzlichen Sachen wie Bits toggeln (u.v.m.) einem Anfänger erklärt
werden.

von Jörg Wunsch (Gast)


Lesenswert?

Die exor-Operation mußt Du vom Prozessor ausführen lassen (Befehl
EOR), nicht vom Assembler.

von Tobi (Gast)


Lesenswert?

in r16, PINB
ldi r17, 0b00000001
eor r16,r17
out PORTB, r16

von justus (Gast)


Lesenswert?

Danke für den Tipp.
Nun siehts folgendermassen aus:
    in r16, PINB
    ldi r19, 0b00000001
    eor r16, r19
    out PORTB, r16
gibts eine kürzere Möglichkeit?

von Henning (Gast)


Lesenswert?

denke nicht, ausser du willst nur einen pin behandeln

  sbic PortB, OutPin2    ; Pin Toggle für Clock aussen
  rjmp ClrBitNow
  sbi PortB, OutPin2
  rjmp BitReady
ClrBitNow:
  cbi PortB, OutPin2
BitReady:

oder geht das noch kürzer?

von Peter D. (peda)


Lesenswert?

Das ist schon das kürzeste, aber im Interrupt mußt Du ja noch die
verwendeten Register und das SREG sichern.

Kürzer ist daher:

        sbis    PINB, 0
        sbi     PORTB, 0
        sbic    PINB, 0
        cbi     PORTB, 0

da nichts gesichert werden muß.

Peter

von Henning (Gast)


Lesenswert?

deinen code kann man doch pauschal immer verwenden, oder?
ist 1 Takt und 1 Befehl kürzer als meiner.

es gibt wohl doch noch viel mehr zu entdecken, für mich :)

von Hagen (Gast)


Lesenswert?

Die Diskussion hatten wir schon mal. Das Problem mit Peters Code ist das
er PINB zweimal sequentiell abfragt und dazu 3 Taktzyklen benötigt.
Innerhalb dieser Takte könnte es zu einem Pegelwechsel am PIN kommen
und somit würde der neue Ausgangstatus falsch sein.
Die XOR Maskierung hat dieses Problem nicht, benötigt auch nur 4
Zyklen, dafür aber verbraucht sie mehr Resourcen.

Gruß Hagen

von Peter D. (peda)


Lesenswert?

In der Tat hat die von mir gezeigte Routine einen Knackpunkt.
Zwischen der 2. und 3. Instruktion darf kein Interrupt erfolgen, sonst
würde das SBIC ja schon den Pegel des SBI auswerten.

Eine andere Möglichkeit wäre, wenn man nur Pin 8 kippen will:

        in      r16, PORTB
        subi    r16, 0x80
        out     PORTB, r16


Peter

von crazy horse (Gast)


Lesenswert?

oder umsteigen, können wir wieder mal dem 8051 ein Pünktchen gewähren
:-)

cpl bitadresse

von justus (Gast)


Lesenswert?

Peter's Vorschlag hat schon einiges für sich:
- nur drei Zeilen
- nur ein Register
---> die Lösung nehm ich.

Gruss Justus

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.