Forum: Mikrocontroller und Digitale Elektronik Kriege den Taster nicht eingelesen


von Alexander (Gast)


Lesenswert?

Hallo,
ich verwende das MK2 bard USB von AVR mit einem Atmega8 und versuche 
einen Taster einzulesen doch leider funzt das nicht. Es soll, wenn man 
den Taster drück,eine LED angehen. Bei dem Booard sind die Schalter GND 
schaltend, ist das vielleicht mein Problem?

Was mache ich da noch verkehrt?
Vielen Dank
1
// Test LED blinken - Taster etc. //
2
3
#include <avr/io.h>          
4
#define Bit0 0
5
#define Bit1 1
6
#define Bit2 2
7
#define Bit3 3
8
#define Bit4 4
9
#define Bit5 5
10
11
12
13
int main (void) {            
14
 
15
 
16
   DDRB    = 0xff;       // Port B als Ausgang definieren
17
   DDRC    = 0x00;       // Alle Pins auf Eingang
18
   PORTC   = 0xff;       // Port C Pulldown aktivieren
19
20
21
         
22
23
if ( PINC & (1<<PINC0) ) { 
24
25
26
 // Ausgänge von Port B beschreiben
27
  PORTB = (1<<Bit2) | (1<<Bit0);
28
}         
29
30
31
32
33
34
35
36
   while(1) {                
37
   return 0;                
38
39
}
40
}

von Chris M. (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter

und das folgende Kapitel über Entprellung beachten.

Zum Board bzw. der Schaltung selbst kann ich nichts sagen.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Alexander schrieb:

>    while(1) {
>    return 0;
>
> }
> }

wie wärs mit:
1
 while( 1 ) {
2
3
  // Wenn Pin gesetzt Ausgänge setzen
4
  if ( PINC & ( 1 << PIN0 ) ) PORTB = ( 1 << PIN2 ) | ( 1 << PIN0 );
5
6
  // Sonst Ausgänge löschen
7
  else PORTB = 0;
8
9
 }
10
11
 return 0;
12
}

Und die Bits sind auch schon fertig:

Auszug aus portpins.h ( wird durch io.h eingebunden ):
1
/* Port Input Pins (generic) */
2
#define    PIN7         7
3
#define    PIN6         6
4
#define    PIN5         5
5
#define    PIN4         4
6
#define    PIN3         3
7
#define    PIN2         2
8
#define    PIN1         1
9
#define    PIN0         0

von Alexander (Gast)


Lesenswert?

1000 Dank.

Ich habe es zwar noch nicht ausprobiert aber deine (Tim) Variante ist ja 
weinwenig eleganter. Aber was habe ich denn falsch gemacht. Ich gehe 
jetzt mal davon aus das deine Funktioniert.

von Franz (Gast)


Lesenswert?

Du "kriegst" den Taster nicht eingelesen? ...

von Klaus T. (gauchi)


Lesenswert?

Bei Deinem Programm muss der Taster während dem Reset gedrückt sein, 
sonst landet das Programm in der while(1) und fragt dort gar nicht mehr 
ob der Taster gedrückt ist. (Von Reset bis zur Abfrage sind es weniger 
als eine Millisekunde, so schnell kannst Du nicht drücken)

Zusätzlich hast du in der while(1) ein return drinstehen. Wohin soll 
dein Programm denn zurückkehren? (Das return aus der main() sollte in 
einem Mikrocontrollerprogramm nie erreicht werden.)

von Alexander (Gast)


Lesenswert?

Das mit der while habe ich hiervon:
(Steht im AVR-GCC-Tutorial 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial)
1
* Alle Zeichen zwischen Schrägstrich-Stern 
2
   und Stern-Schrägstrich sind lediglich Kommentare */
3
 
4
// Zeilenkommentare sind ebenfalls möglich
5
// alle auf die beiden Schrägstriche folgenden
6
// Zeichen einer Zeile sind Kommentar
7
 
8
#include <avr/io.h>          // (1)
9
 
10
int main (void) {            // (2)
11
 
12
   DDRB  = 0xff;             // (3)
13
   PORTB = 0x03;             // (4)
14
 
15
   while(1) {                // (5a)
16
     /* "leere" Schleife*/  // (5b)
17
   }                         // (5c)
18
 
19
   /* wird nie erreicht */
20
   return 0;                 // (6)
21
}

Ist das falsch ?

von Justus S. (jussa)


Lesenswert?

Alexander schrieb:
> Das mit der while habe ich hiervon:

nein hast du nicht, da steht das return nämlich nicht in der Schleife...

von Alexander (Gast)


Lesenswert?

Wann brauche ich denn das return ?

von Alexander (Gast)


Lesenswert?

Tatsache....
Ich habe soviel ausprobiert, da ist das dann verrutscht. Danke.
Also wenn ich es richtig verstehe muss mein Prog in die While Schleife. 
Deklerationen kommen über die Schleife. (Registerfestlegeung etc.) Wenn 
ich die Dekleration ändere reicht es dann das ich neu übertrage oder 
muss ich zwingend ein Reset ausführen ?

PS. Bin seit 1h Stunde erst dabei mich mit dem Micro zu befassen.Sorry.

von Karl H. (kbuchegg)


Lesenswert?

Alexander schrieb:
> Tatsache....
> Ich habe soviel ausprobiert, da ist das dann verrutscht. Danke.
> Also wenn ich es richtig verstehe muss mein Prog in die While Schleife.

Genau.
Dort findet deine Programmlogik statt

Der grundsätzliche Aufbau ist immer gleich
1
#include <avr/io.h>
2
 
3
int main (void)
4
{
5
6
  // Variablen definieren, die in main gebraucht werden
7
  // globale Variablen auf die richtigen Werte einstellen
8
9
10
  // µC richtig konfigurieren
11
  // Ports einstellen, Timer einstellen etc.
12
13
  while( 1 ) {
14
15
    // Programmlogik
16
    // zb wenn Taster gedrückt, LED einschalten
17
    //    wenn Taster nicht gedrückt, LED ausschalten
18
19
  }
20
21
  return 0;
22
}

> Deklerationen kommen über die Schleife. (Registerfestlegeung etc.) Wenn
> ich die Dekleration ändere reicht es dann das ich neu übertrage oder
> muss ich zwingend ein Reset ausführen ?

Wenn du neu überträgst, wird sowieso der Prozessor immer resettet

von Alexander (Gast)


Lesenswert?

Super Danke.

von Alexander (Gast)


Lesenswert?

Warum aber funktioniert das hier nicht:
1
   while(1) {     
2
   
3
4
  if ( PINC & ( 1 << PIN0 ) ) {
5
6
 // Ausgänge von Port B beschreiben
7
  PORTB = (1<<PIN2) | (1<<PIN1);
8
}      
9
    
10
   }         
11
12
   return 0;                
13
}

und das funktioniert:
1
 while( 1 ) {
2
3
  // Wenn Pin gesetzt Ausgänge setzen
4
  if ( PINC & ( 1 << PIN0 ) ) PORTB = ( 1 << PIN2 ) | ( 1 << PIN0 );
5
6
  // Sonst Ausgänge löschen
7
  else PORTB = 0;
8
9
 }
10
11
 return 0;
12
}

Kann ich bei ner If - Anweisung nicht hinterm { was stehen haben ? 
Versteh ich nicht ....

von Oliver J. (skriptkiddy)


Lesenswert?

Alexander schrieb:
> Warum aber funktioniert das hier nicht:
>    while(1) {
>
>
>   if ( PINC & ( 1 << PIN0 ) ) {
>
>  // Ausgänge von Port B beschreiben
>   PORTB = (1<<PIN2) | (1<<PIN1);
> }
>
>    }
>
>    return 0;
> }
>

Weil hier in keinster Weise die in der If-Anweisung gesetzen Bits 
zurückgesetzt werden. In dem anderen Quelltext wird das jedoch im 
Else-Zweig getan.

von Alexander (Gast)


Lesenswert?

Shit, du has so recht;-)------ mmmhhh.
Kannst Du mir auch noch sagen warum in dieser Anweisung die LED's beim 
drücke ausgehen ?
1
   while(1) {     
2
   
3
4
  if ( PINC & ( 1 << PIN0 )) 
5
6
 
7
  PORTB = (1<<PIN0) | (1<<PIN1);      // Ausgänge von Port B beschreiben
8
     
9
  else PORTB = 0;

Für mich ist dieser Part  ( PINC & ( 1 << PIN0 ))  ein ganz klares UND.

von Alexander (Gast)


Lesenswert?

Weil die Schalter am MK2 board auf GND schalten.... Kerl Montag heute...

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


Lesenswert?

Alexander schrieb:
> PORTC   = 0xff;       // Port C Pulldown aktivieren
Nur, um sich das mal auf der Zunge zergehen zu lassen....  :-o

Als kleiner Denkanstoss: auch zusammen mit dem Kommentar wird der PortC 
keinen Pulldown einschalten können...

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.