Taster verwenden

Gast #2218877
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...
Gast #2218972
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!?
Gast #2218992
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.
Gast #2219001
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
Gast #2219059
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!
#2219064
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);
    }
#2219075
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren