Forum: Mikrocontroller und Digitale Elektronik Zustand des Eingangsregister bei Tastendruck?


von Timmm (Gast)


Lesenswert?

Mein Problem ist recht grundlegend, trotzdem finde ich darauf keine 
direkte Erklärung im Internet.

Ich habe ein AVR-Experimentierboard von meiner Schule für ein Projekt 
zur Verfügung gestellt bekommen. Ich programmiere es mit dem GCC.

Nun wollte ich einfach nur ein kleines Programm schreiben, das eine LED 
anschalten, wenn ein Taster gedrückt wird. (Nur zu Experimentierzwecken, 
ob ich alles verstanden habe)

Mir wurde gesagt, dass Board hätte eine "invertierte Logik" was wohl 
bedeutet, dass bei nicht gedrückter Taste das entsprechende Bit im 
Eingangsregister = 1 ist und wenn es gedrückt wird, ist es = 0.
Entsprechend dachte ich mir, ich Verknüpfe das Byte des 
Eingangsregisters mit einer Bitmaske, in der das mich interessierende 
Bit markiert ist (00 01 00 00), ein (wie es ja in den Tutorials auch 
gemacht wird) und prüfe in einer Endlosschleife, ob dieser Ausdruck = 0 
ist.
Das Problem ist, dass das nicht funktioniert und ich nicht verstehe 
wieso.
wo ist der Fehler in meiner Überlegung? Steht in dem Byte, das ich aus 
Verküpfung des Eingangsregisters und Bitmaske erstelle etwas noch etwas 
drin, was ich gerade nicht hervorsehe?


Hier nochmal kurz der Code der Abfrage
1
while(1)
2
{
3
  if ((PIND & (1<<PIN4) == 0))
4
  {
5
     PORTD |= (1<<PIN3);
6
  }
7
}

von Spess53 (Gast)


Lesenswert?

Hi

Hast du PIN3 auch als Ausgang konfiguriert?

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Laut deiner Beschreibung hat das Board also active low Taster. Was das 
heisst ist (IMHO schön) im AVR-GCC-Tutorial erklärt. Dort sieht man 
auch, dass für die Funktion ein Pullup-widerstand erforderlich ist. Der 
kann sich intern im AVR oder extern auf dem Board befinden. Den interen 
Pullup muss man im Programm aktivieren. Den externen je nach Board ggf. 
durch einen Jumper. Möglicherweise gilt das active low/high auf deinem 
Board auch für die LED und das Setzen der LED mit |= schaltet sie in 
Wirklichkeit aus. Eine ausführlichere Hilfe ist leider ohne Schaltplan 
(oder Link dazu) und kompletten Code kaum möglich. Vielleicht reichen 
die Hinweise, so dass du dir ab hier selber helfen kannst.

von Karl H. (kbuchegg)


Lesenswert?

Timmm schrieb:

> Hier nochmal kurz der Code der Abfrage

> while(1)
> {
>   if ((PIND & (1<<PIN4) == 0))

Hier ist die Klammerung falsch

    if ( (PIND & (1<<PIN4)) == 0 )


zusammen mit den Vorrangregeln von C, hat der Compiler deinen Code so 
aufgefasst

    if ( PIND & ((1<<PIN4) == 0))

und das ergbit natürlich Unsinn

von Thomas E. (thomase)


Lesenswert?

Timmm schrieb:
> while(1)
>
> {
>
>   if ((PIND & (1<<PIN4) == 0))
>
>   {
>
>      PORTD |= (1<<PIN3);
>
>   }
>
> }

So wird es laufen:

DDRD |= (1 << PIN3)  //PD3 = Ausgang
PORTD |= (1 << PIN4)  //Pull-Up des Eingangs, sonst ist der immer Low

while(1)
{
  if (PIND & (1 << PIN4))
  {
    PORTD |= (1 << PIN3);  //Taste gedrückt LED ein
  }
  else
  {
    PORTD &= ~(1 << PIN3);  //Taste losgelassen LED aus
  }
}

mfg.

von Thomas E. (thomase)


Lesenswert?

Thomas Eckmann schrieb:
> while(1)
>
> {
>
>   if (PIND & (1 << PIN4))
>
>   {
>
>     PORTD |= (1 << PIN3);  //Taste gedrückt LED ein
>
>   }
>
>   else
>
>   {
>
>     PORTD &= ~(1 << PIN3);  //Taste losgelassen LED aus
>
>   }
>
> }

sorry, genau anders rum
while(1)
{
  if (PIND & (1 << PIN4))
  {
     PORTD &= ~(1 << PIN3);  //Taste losgelassen LED aus
  }
  else
  {
    PORTD |= (1 << PIN3);  //Taste gedrückt LED ein
  }
}

oder so:

while(1)
{
  if (!(PIND & (1 << PIN4)))
  {
    PORTD |= (1 << PIN3);  //Taste gedrückt LED ein
  }
  else
  {
    PORTD &= ~(1 << PIN3);  //Taste losgelassen LED aus
  }
}

von Timmm (Gast)


Lesenswert?

Hallo,

zunächst vielen Dank für die reichlichen Antworten und Hilfsvorschläge.

Zunächst kurz zu einigen Fragen und anmerkungen:

- Das Board ist laut unserem Lehrer mit einem Pull-Up Widerstand 
ausgerüstet, den ich auch im Programm aktiviert habe.

-PIN3 ist auch als Ausgang eingeschaltet.

-Um die LED anzuschalten, muss das entsprechende Bit im Ausgangsregister 
wohl auf 1 gesetzt werden, denn eine LED unabhängig vom Schalter, also 
einfach bei Programmstart, einzuschalten, schaffe ich.

Vermutlich werde ich heute das Board mit nach Hause nehmen dürfen und 
werde dann die vorgeschlagenen Codestücke mal durcharbeiten.
(Dieser Post dient jetzt hauptsächlich dazu, mich schon mal zu bedanken 
und kenntlich zu machen, dass das Thema noch nicht gestorben ist ;) )

von Timm (Gast)


Lesenswert?

So, das Projekt wurde leider abgesagt. Aber was mich trotzdem einmal 
interessiert ist, warum kann ich nicht einfach Abfragen, ob das 
Eingangsregister ==0 ist. Das sollte doch eigentlich komplett "leer" 
sein, wenn die Taste bei invertierter Logik gedrückt ist?

von Peter D. (peda)


Lesenswert?

Timm schrieb:
> Das sollte doch eigentlich komplett "leer"
> sein, wenn die Taste bei invertierter Logik gedrückt ist?

Nur wenn Du alle 8 Pins mit GND verbindest, ist das gesamte Register 0.
Ein "leer" gibt es nicht.
Verbindest Du nur einen Pin mit GND, ist nur dieser 0 und die anderen 7 
Bits sind unbestimmt.


Peter

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.