Forum: Mikrocontroller und Digitale Elektronik Taster verwenden


von Atmega8 (Gast)


Lesenswert?

Hallo
ich bin jetzt neu in der welt der mikrocontroller und versuch mich 
gerade an einem Taster...
Hab folgenden code geschrieben:
1
#include <avr/io.h>
2
3
int main(void) {
4
  // PD5, PD6 Ausgang; PD2, PD3 Eingang
5
  DDRD = (1<<PD6) | (1<<PD5) | (0<<PD2) | (0<<PD3);  
6
  // PD5, PD6 0V; PD2, PD3 Pullup deaktiviert
7
  PORTD = (0<<PD6) | (0<<PD5) | (0<<PD2) | (0<<PD3);
8
  uint8_t comp;
9
  
10
  while (1) {
11
  comp = PIND;
12
  comp = comp & (1<<PD2);
13
    if (comp != 0){
14
      PORTD = PORTD | (1<<PD5);
15
    }
16
  }
17
  return 0;
18
}
eigentlich sollte die Led an PD5 zum leuchten beginnen wenn der Taster 
gedrückt ist! tut sie aber nicht... Was mach ich da falsch?
Verwende einen AtMega8 und das Atmel Evalutions-Board von Polin...

von Michael A. (Gast)


Lesenswert?

Eine Oder-Verknüpfung von 0en bringt z.B. nichts
>  PORTD = (0<<PD6) | (0<<PD5) | (0<<PD2) | (0<<PD3);

In deiner Hauptschleife kann die LED zwar eingeschaltet werden, aber 
nicht aus

von Atmega8 (Gast)


Lesenswert?

ok.... ich habs jetzt mal abgeändert!
1
#include <avr/io.h>
2
3
int main(void) {
4
  // PD5, PD6 Ausgang; PD2, PD3 Eingang
5
  DDRD = (1<<PD6) | (1<<PD5);  
6
  // PD5, PD6 0V; PD2, PD3 Pullup deaktiviert
7
  PORTD = (1<<PD6);
8
  uint8_t comp;
9
  while (1) {
10
    comp = PIND;
11
    comp = comp & (1<<PD2);      
12
    if (comp != 0){            // gedrückt
13
      PORTD = PORTD | (1<<PD5);    
14
      }
15
    if (comp != 1){            // nicht (mehr) gedrückt
16
      PORTD = PORTD | ~(1<<PD5);    
17
      }
18
  }
19
  return 0;
20
}
Jetzt ergibt sich aber das problem, dass die leds von anfang an leuchten 
und auch mit dem taster nicht ausschaltbar sind!?

von Michael A. (Gast)


Lesenswert?

Spiel das Programm erstmal im Simulator durch. Überlege dir, wie die 
Taster beim Pollinbord schalten und welcher Pegel am Port anliegt, wenn 
der Taster nicht gedrückt ist. Falls die Taster nach Gnd schalten, kann 
für High-Pegel einfach der Pull-up Widerstand über das entsprechende Bit 
im PortD Register aktiviert werden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Atmega8 schrieb:
> PORTD = PORTD | ~(1<<PD5);
Man kann nicht eine 0 dazuverODERn.
Hier muß ein UND herhalten...
Das nennt sich Bitmanipulation

von NopNop (Gast)


Lesenswert?

Atmega8 schrieb:
> Jetzt ergibt sich aber das problem, dass die leds von anfang an leuchten
1
comp = PIND;            //Durch Pullups unbetätigt HIGH 
2
comp = comp & (1<<PD2); //D.h. comp ist !=0 wenn Taster unbetätigt
3
if (comp != 0){         //Demnzufolge geht er berechtigt in diese Schleife
4
 PORTD = PORTD | (1<<PD5); //Und setzt PD5 auf HIGH   
5
      }

Atmega8 schrieb:
> und auch mit dem taster nicht ausschaltbar sind!?
1
PORTD = PORTD | ~(1<<PD5); //So löscht man KEINE Bits
2
PORTD = PORTD & ~(1<<PD5); //So löscht man ein Bit richtig
3
PORTD&= ~(1<<PD5);         //Oder in kurz

Grüße

von Atmega8 (Gast)


Lesenswert?

OK, Danke jetzt funktionierts!
Das Problem war das ich statt dem und Operator den Oder Operator 
verwendet habe... Bei dem Pollinboard, das ich habe, liegt am Pin 0V 
(also er ist über einen Widerstand an GCC geschalten) an wenn der 
Schalter nicht gedrückt ist!
wenns jemanden interessiert:
1
#include <avr/io.h>
2
3
int main(void) {
4
  // PD5, PD6 Ausgang; PD2, PD3 Eingang
5
  DDRD = (1<<PD6) | (1<<PD5);  
6
  // PD5, PD6 0V; PD2, PD3 Pullup deaktiviert
7
  PORTD = (1<<PD6);
8
  uint8_t comp;
9
  while (1) {
10
    comp = PIND;
11
    comp = comp & (1<<PD2);      
12
    if (comp != 0){            // gedrückt
13
      PORTD = PORTD | (1<<PD5);    
14
      }
15
    if (comp != 1){            // nicht (mehr) gedrückt
16
      PORTD = PORTD & ~(1<<PD5);    
17
      }
18
  }
19
  return 0;
20
}
Danke!

von Karl H. (kbuchegg)


Lesenswert?

das hier
1
    if (comp != 0){            // gedrückt
2
     ...
3
    }
4
    if (comp != 1){          
5
     ...
6
    }

gewöhnst du dir gleich wieder ab.

1) hat deine variable comp nur 2 mögliche Werte.
   Die sind 0 und 4  (weil dein Taster an PD2 hängt)

2) solltest du dir angewöhnen eine derartige Variable so
   zu sehen:
   Entweder sie ist 0 oder sie ist nicht 0
   aber auf keinen Fall willst du dir hier eine Abhängigkeit
   vom Portpin und damit auf einen spezifischen Wert einhandeln.
   Es genügt, dass sie nicht 0 ist. Welcher Wert genau, ist
   uninteressant.

3) Wenn eine Variable sowieso nur 2 Werte haben kann, dann genügt
   es

   if (comp == 0) {   // wenn sie 0 ist
     ...
   }
   else {             // andernfalls kann sie nur nicht 0 sein
     ...
   }

   d.h. die 2.te explizite Abfrage ist sinnlos und nur eine
   zusätzliche potentielle Fehlerquelle.

4) Und da damit die Variable comp ein bischen sinnlos geworden ist,
   wirfst du sie gleich wieder raus und schreibst das kürzer

    if (PIND & (1<<PD2)) {            // gedrückt
      PORTD = PORTD | (1<<PD5);
    }
    else {                            // nicht (mehr) gedrückt
      PORTD = PORTD & ~(1<<PD5);
    }

von Atmega8 (Gast)


Lesenswert?

Danke für die Verbesserungen!

von Karl H. (kbuchegg)


Lesenswert?

Atmega8 schrieb:
> Danke für die Verbesserungen!

Gerne.

Denn durch deine Fehler hast du nämlich in Wirklichkeit was anderes 
programmiert:

Deine LED hat in Wirklichkeit nämlich ganz schnell geblinkt! Und durch 
den Tastendruck hast du das Blinken unterbunden, indem du das 
Einschalten nicht mehr durchgeführt hast.

Mit einem Oszi am Ausgang hätte man es gesehen, dass da in Wirklichkeit 
ständig Pulse aus dem Ausgang herausgekommen sind. Mit freiem Auge 
allerdings, ist das BLinken zu schnell. Was man sehen würde ist, dass 
die LED etwas dunkler brennt als eine die auf Dauer-Ein steht. Aber dazu 
müsste man eine Vergleichsled haben. Optisch ist der Effekt nicht sehr 
deutlich.

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.