Forum: Compiler & IDEs LEDs an-/ausschalten


von Thomas Huxhorn (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich versuche seit einigen Tagen einen ATMEGA 8 so zu programmieren,
dass wenn ich einen Knopf auf meinem STK500 drücke die entsprechende
LED ausgeht und nach nochmaligem drücken des selben Knopfes die LED,
die gerade ausgegangen ist, wieder angeht. Mit dem ausgehen klapts, nur
das wieder angehen will nicht.

Kann mir da wer helfen? (bisherigen Quellcode siehe Anhang)

Thomas

von Stefan Kleinwort (Gast)


Lesenswert?

Das funktioniert so nicht:
  //Lampe i ist aus -> anmachen
  PORTB |= (0<<i);

Du steuerst Deine LED low-aktiv an, korrekt?
Dann musst Du so schreiben:
  PORTB &= ~(1<<i);


Überleg mal, was der Befehl genau macht: (Bsp.: i = 2):
  1<<i  bedeutet: eine 1 um i (Bsp.: 2) Stellen nach links schieben,
  also:  0000 0100 binär

  1<<i bedeutet: eine Null (!) um i STellen nach links schieben,
  und das ergibt immer wieder Null, egal was i für ein Wert ist.

Ok, Du hast jetzt aus 1<<i eine "Maske gemacht. Diese Maske wird zum
VerODERn (->Pin auf high schalten) oder invertiert zum verUNDen (Pin
auf GND schalten) benutzt:
  PORTB |= 00000100b bedeutet: Bit 2 des PB wird gesetzt.

Das VerUNDen ist nur geringfügig komplizierter:
  PORTB &= ~00000100b bedeutet:
  PORTB UND invertierte Maske
  00000100b invertiert -> 11111011b, also:
  PORTB &= 11111011b
  D.h. alle Bits des Ports bleiben unverändert bis auf Bit 2, das
  wird immer Null.

Viel Spass, Stefan

von Hubert.G (Gast)


Lesenswert?

Ich baue mir so ein Toggle-Led immer ein wenn eine Funktion nicht so
richtig tut was ich will. Z.B
SIGNAL(SIG_OVERFLOW1) /*TIMER 1 ÜBERLAUF*/
     if(PORTD&0x80){  /*ist PORTD 7 gesetzt ?*/
         cbi(PORTD,7);/*wenn ja  PORT löschen*/
      }
     else{
         sbi(PORTD,7); /* wenn nicht dann Port setzen*/
       }

Anstelle des Interrupt brauchst du ja nur die Taste abfragen und dir
das jeweilige Port aussuchen an dem die LED hängt.

von Dirk (Gast)


Lesenswert?

Hi,

und bei den neuen AVR's geht ganz easy indem man den Pin als Output
schaltet und dann in den PINB eine "1" schreibt.

Mfg

Dirk

von Alex (Gast)


Lesenswert?

Wenn du die '1' in PORTB anstatt in PINB schreibst, wird es vielleicht
sogar funktionieren :-)

von Dirk (Gast)


Lesenswert?

Hi,

du hast schon richtig gelesen (SBI PINB,1) NICHT PORTB.

Das sind die neuen Feature's der neuen Atmel Generation
(Tiny13,Mega44/88)

Mfg

Dirk

von OldBug (Gast)


Lesenswert?

Das ist allerdings erst mal NUR in Assembler möglich!
Hier handelt es sich allerdings um ein C-Programm ;-)

von Stefan Kleinwort (Gast)


Lesenswert?

@Oldbug:
Warum nur Assembler? Aus
  PINB |= _BV(1)     wird beim gcc:

 149:buskoppler.c  ****   PINB |= _BV(1);
 433                 .LM21:
 434 0058 B19A          sbi 54-0x20,1

Die Frage ist nur, wofür man den Befehl sinnvoll nutzt. Vielleicht ist
es ganz interessant, wenn das Ganze auch für einen kompletten Port
funktioniert. Dann könnte man ein ganzes Bitpattern mit einem Schlag
invertieren.

Viele Grüße, Stefan

von OldBug (Gast)


Lesenswert?

Stimmt auch wieder...

Ich war jetzt schon nen Schritt weiter :-)

PORTB ^= _BV(1);

Müsste der neuen Funktion nach auch in "sbi PINB, 1" übersetzt
werden...

Aber trotzdem Vorsicht: Das geht alles nur so lange die Werte Konstant
sind!

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.