Forum: Mikrocontroller und Digitale Elektronik AVR: Zustand eines Tasters einlesen nicht möglich


von Daverda Kevin (Gast)


Lesenswert?

Hallo... Ich habe folgendes Problem: Ich möchte mit einem Atmega8 den 
Zustand eines Bits einlesen. Dafür hab ich den Code
1
DDRB&=~(1<<PB1);
2
PORTB|=(1<<PB1);
3
DDRB|=(1<<PB0);
verwendet, um die Datenrichtung zu bestimmen und die Pull-Up-Widerstände 
zu aktivieren, dann
1
if(PINB&(!(1<<PB1)))
2
{
3
  PORTB|=(PB0<<1);//Led aus
4
}
5
if(PINB&((1<<PB1)))
6
{
7
  PORTB&=(PB0<<0);//Led ein
8
}
um den Zustand einzulesen. Den Schalter (PB1) habe ich gegen Masse 
geschaltet, die Diode (PB0) mit einem Vorwiderstand mit den 5V 
verbunden. Nun sollte das Programm eigentlich funktionieren, jedoch 
bleibt die Diode konstant eingeschaltet.
P.s.: Mikrokontroller, Taster usw. sind alle funktionsfähig, also nicht 
kaputt. Bitte wenn mir jemand helfen könnte.

von troll (Gast)


Lesenswert?

>if(PINB&(!(1<<PB1)))

if(!(PINB&(1<<PB1)))

von troll (Gast)


Lesenswert?

>PORTB|=(PB0<<1);
PORTB|=(1<<PB0);

>PORTB&=(PB0<<0);
PORTB&=~(1<<PB0);

Bitmanipulation

von Norbert (Gast)


Lesenswert?

Daverda Kevin schrieb:
> DDRB &= ~(1<<PB1);
> PORTB |= (1<<PB1);
> DDRB |= (1<<PB0);

Erste Zeile schaltet PB1 auf Eingang.
Zweite Zeile schaltet Pullup ein.
Dritte Zeile schaltet PB1 auf Ausgang!

Ist es das was du willst?

von Norbert (Gast)


Lesenswert?

Kommando zurück, habe mich bei der dritten Zeile verlesen, die ist ja 
für PB0!

von Kevin D. (Firma: m5) (daverda00)


Lesenswert?

Jetzt, mit der Verbesserung von troll, funktionierts perfekt. Dankeschön 
:)

von Karl H. (kbuchegg)


Lesenswert?

Eines noch:

Du hast hier
1
if(PINB&(!(1<<PB1)))
2
{
3
  PORTB|=(PB0<<1);//Led aus
4
}
5
if(PINB&((1<<PB1)))
6
{
7
  PORTB&=(PB0<<0);//Led ein
8
}

2 gegensätzliche Abfragen programmiert. (Es geht mir jetzt nicht um die 
Schreibweise, die ist ja schon korrigiert). Es geht um die beiden if. 
Das zweite if fragt genau die gegenteilige Situation vom ersten if ab. 
Ein einzelnes Bit kann aber nur 0 oder 1 sein. Es gibt keine 3. 
Möglichkeit. D.h. du weißt aus dem Ausgang der ersten Abfrage bereits, 
wie die zweite Abfrage ausgehen MUSS! Es gibt keine andere Möglichkeit.
Und in so einem Fall ist es dann besser ein 'else' ('andernfalls') 
einzusetzen ...
1
   if( !(PINB & (1<<PB1)) )
2
     PORTB |= (1<<PB0);
3
   else
4
     PORTB &= ~(1<<PB0);

... denn dieses else drückt automatisch aus, dass es hier um nur um den 
Pin PB1 geht. Entweder der ist 0 oder er ist es eben nicht.

   entweder der Pin ist auf 0
       dann setze PB0
   oder er ist es nicht
       dann lösche PB0


Ein nicht ganz unwesentlicher Vorteil liegt darin, dass du durch den 
Wegfall der zweiten Bedingung dort dann auch keine Tipp- oder sonstige 
Fehler machen kannst. Der else Teil ist automatisch das Gegenteil der 
Abfrage, ohne dass du das ausprogrammieren musst.
Entweder ein Pin ist auf 0 oder er ist es nicht (dann MUSS er auf 1 
sein).
Entweder eine Zahl x ist kleiner als y, oder sie ist es nicht (dann MUSS 
sie größer-gleich sein).
Entweder 2 Zahlen sind gleich oder sie sind es nicht (dann MÜSSEN sie 
ungleich sein).
Entweder .... oder eben nicht (dann liegt offenbar das genaue Gegenteil 
vor)

In C gibt es Fälle, in denen weniger mehr ist. Dies hier ist so einer.

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.