Forum: Mikrocontroller und Digitale Elektronik LED umschalten mit Taster


von Daniel L. (daniel_l49)


Lesenswert?

hallo zusammen!

ich möchte in c eine schaltung programieren , wenn eine Person auf eine 
Taste drückt geht eine LED an und beim zweiten mal drücken geht die 
wieder aus und eine ander leuchtet nun und beim dritten Drücker geht die 
zweite LED aus und eine dritte LED leuchtet.Und dann wieder von vorne.
Ich hätte mir das etwa so vorgestellt
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
#define TASTE_GEDRUECKT         0
5
#define TASTE_NICHT_GEDRUECKT   1
6
7
int main(void)
8
{
9
  uint8_t tasteVorher;
10
  uint8_t tasteJetzt;
11
12
  DDRB = 0x00;
13
  PORTB = 0xff;
14
  DDRC = 0xff;
15
  
16
  if( PINB & ( 1 << PB0 ) )
17
  tasteVorher = TASTE_GEDRUECKT;
18
  else
19
  tasteVorher = TASTE_NICHT_GEDRUECKT;
20
  
21
22
  while(1)
23
  {
24
    
25
    if( PINB & ( 1 << PB0 ) )
26
    tasteJetzt = TASTE_NICHT_GEDRUECKT;
27
    else
28
    tasteJetzt = TASTE_GEDRUECKT;
29
    
30
31
    
32
    if( tasteVorher != tasteJetzt )
33
    {
34
      
35
      if( tasteJetzt == TASTE_GEDRUECKT )
36
      {
37
      
38
        PORTC = 0b00000001;
39
        
40
      }
41
      
42
      if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000001))
43
      {
44
        PORTC=0b00000000;
45
        PORTC=0b00000010;
46
        
47
      }  
48
      
49
      if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000010))
50
      {
51
        PORTC=0b00000000;
52
        PORTC=0b00000100;
53
      }
54
        
55
      
56
      tasteVorher = tasteJetzt;
57
    }
58
59
    _delay_ms( 30 );   //
60
  }
61
}

Aber leider funktioniert das nicht so ganz. HILFE!!!!!!!!!!!!!!!!!


Ich bedanke mich im voraus!

MFG Daniel

von aGast (Gast)


Lesenswert?

Das schaut wie eine Hausaufgabe aus. Im wirklichen Leben würde ich da 
einen 4017 nehmen. Ein IC und das Thema ist erledigt.

von ich (Gast)


Lesenswert?

Daniel L. schrieb:
> if( PINB & ( 1 << PB0 ) )
>   tasteVorher = TASTE_GEDRUECKT;
>   else
>   tasteVorher = TASTE_NICHT_GEDRUECKT;
>
>
>   while(1)
>   {
>
>     if( PINB & ( 1 << PB0 ) )
>     tasteJetzt = TASTE_NICHT_GEDRUECKT;
>     else
>     tasteJetzt = TASTE_GEDRUECKT;

Nur beim ersten Überfliegen entdeckt. Vergleich mal die beiden 
Sequenzen.

von Daniel L. (daniel_l49)


Lesenswert?

oh ich glaube du hast da was falsch verstanden
1
  if( PINB & ( 1 << PB0 ) ) // das hier heißt if taste nicht gedrückt
2
  tasteVorher = TASTE_GEDRUECKT;
3
  else
4
  tasteVorher = TASTE_NICHT_GEDRUECKT;
5
  
6
7
  while(1)
8
  {
9
    
10
    if( PINB & ( 1 << PB0 ) )
11
    tasteJetzt = TASTE_NICHT_GEDRUECKT;
12
    else
13
    tasteJetzt = TASTE_GEDRUECKT;

von Udo S. (urschmitt)


Lesenswert?

Was ist mit Tastenentprellung?

von G ast (Gast)


Lesenswert?

Daniel L. schrieb:
> hallo zusammen!
>
> ich möchte in c eine schaltung programieren , wenn eine Person auf eine
> Taste drückt [...]


und wenn eine katze auf den taster drückt??

von Daniel L. (daniel_l49)


Lesenswert?

als entprellung habe ich den delay am ende der while schleife genommen

es ist keine hausaufgabe. ich stehe gerade am anfang meiner 
microcontroller karriere und möchte nur ein paar sachen probieren

von Justus S. (jussa)


Lesenswert?

Daniel L. schrieb:
> if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000001))

der erste Murks der mir nur beim schnellen Überfliegen auffällt....

von Daniel L. (daniel_l49)


Lesenswert?

jaaa ich habe leider keinen plan wie das hier funktionieren sollte. ich 
programiere ca 2 wochen und habe noch sehr wenig erfahrung.

von bbb (Gast)


Lesenswert?

Der Wurm liegt in den inneren Ifs,
1
  while(1)
2
  {
3
    
4
    if( PINB & ( 1 << PB0 ) )
5
    tasteJetzt = TASTE_NICHT_GEDRUECKT;
6
    else
7
    tasteJetzt = TASTE_GEDRUECKT;
8
    
9
10
    
11
    if( tasteVorher != tasteJetzt )
12
    {
13
14
      if( tasteJetzt == TASTE_GEDRUECKT )
15
      {
16
17
        // Jedesmal, wenn sich die Taste geändert hat und gedrückt wird,
18
        // wird hier PORTC auf 1 gesetzt.
19
        PORTC = 0b00000001;
20
        
21
      }
22
      
23
      // Bei gedrückter Taste ist PORTC hier immer gleich 1 ...
24
      if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000001))
25
      {
26
        // ... und wird hier auf 2 gesetzt
27
        PORTC=0b00000000;
28
        PORTC=0b00000010;
29
        
30
      }  
31
      
32
      if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000010))
33
      {
34
        // ... und hier mit derselben Logik auf 4.
35
        PORTC=0b00000000;
36
        PORTC=0b00000100;
37
      }
38
        
39
      
40
      tasteVorher = tasteJetzt;
41
    }
42
43
    _delay_ms( 30 );   //
44
  }
45
}
Um dem abzuhelfen kann man unterschiedlich vorgehen, zum Beispiel so
1
    if( tasteVorher != tasteJetzt )
2
    {
3
      if( tasteJetzt == TASTE_GEDRUECKT )
4
      {
5
        switch (PORTC) 
6
        {
7
           case 0b00000000: PORTC = 0b00000001; break;
8
           case 0b00000001: PORTC = 0b00000010; break;
9
           case 0b00000010: PORTC = 0b00000100; break;
10
           case 0b00000100: PORTC = 0b00000000; break;
11
        }
12
      }
13
      tasteVorher = tasteJetzt;
14
    }
15
16
    _delay_ms( 30 );   //
17
  }
Ich habe den Code nicht compiliert, mag sein, dass man den noch in 
fehlerfreies C übersetzen muss. Die Idee sollte aber klar werden.

BBB

von Justus S. (jussa)


Lesenswert?

Daniel L. schrieb:
> if( PINB & ( 1 << PB0 ) ) // das hier heißt if taste nicht gedrückt
>   tasteVorher = TASTE_GEDRUECKT;

aha...also wenn Taste nicht gedrückt, dann ist die Taste gedrückt...sehr 
logisch

Daniel L. schrieb:
> jaaa ich habe leider keinen plan wie das hier funktionieren sollte. ich
> programiere ca 2 wochen und habe noch sehr wenig erfahrung.

dann nimm dir ein C-Buch und lerne erst mal C ohne µC dahinter...wer 
nicht mal einen Vergleich richtig hinrotzen kann, der sollte die Finger 
von µCs lassen, aus eigenem Interesse...

von Daniel L. (daniel_l49)


Lesenswert?

ich habe das jetzt mal so gemacht, aber es tut sich nichts.. ich kann 
wild die taste drücken, aber es passiert nichts

von Daniel L. (daniel_l49)


Lesenswert?

aus meiner sicht ist das ganz logisch wenn die taste nicht gedrückt ist 
war der vorherige tastenzustand taste gedrückt was ist hier nicht 
logisch

von Gerald M. (gerald_m17)


Lesenswert?

geht das nicht einfach mit:
1
if( PINB & ( 1 << PB0 ) ){
2
  if(PortC == 0b00000100){
3
     PortC= 0b00000001;
4
     }
5
6
   else {
7
     PortC << 1;
8
     }
9
   _delay_ms(30);
10
}

von Schreiben und Verstehen (Gast)


Lesenswert?

Ich hab's mal ein wenig umformatiert,
damit man es besser lesen kann ;-)

> aus meiner sicht ist das
> ganz logisch wenn die taste
> nicht gedrückt ist war der
> vorherige tastenzustand taste
> gedrückt was ist hier
> nicht logisch

Ist das jetzt eine Feststellung, eine Frage,
oder was bedeuten die zusammenhanglosen
Wörter?
Keine Groß/Kleinschreibung, keine Satzzeichen,
rein gar nix. Da bricht man sich doch das Gehirn
beim Lesen!

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

bbb schrieb:
> if( tasteJetzt == TASTE_GEDRUECKT )
>       {
>
>         // Jedesmal, wenn sich die Taste geändert hat und gedrückt wird,
>         // wird hier PORTC auf 1 gesetzt.
>         PORTC = 0b00000001;
>
>       }
>
>       // Bei gedrückter Taste ist PORTC hier immer gleich 1 ...
>       if ((tasteJetzt == TASTE_GEDRUECKT) && (PORTC=0b00000001))

Was soll das nach dem &&? Das einzelne "=" ist eine Zuweisung und kein 
Vergleich (die Zuweisung funktioniert hier zwar auch, ist aber immer 
Wahr) - es muss "==" heißen.

Wenn die Taste im ersten Vergleich gedrück ist, wird PORTC auf 1 
gesetzt.
Da "tasteJetzt" danach immer noch TASTE_GEDRUECKT ist, trifft auch der 
zweite Vergleich sofort zu (mal abgesehen vom einzelnen "=").

PORTC wird also ziemlich schnell auf 0 und dann auf 2 gesetzt (das 
siehst Du nicht).

Dann kommt der nächste Vergleich. Auch dieser trifft wieder zu, da 
tasteJetzt immer noch den gleichen Zustand hat und PortC nun auch (nach 
dem 2. IF) der zweiten Bedingung entspricht.

Bei Deinem Programm wird sicherlich nach dem ersten Tastendruck immer 
die dritte LED an sein. Die Zwischenzustände siehst Du nicht.

von bbb (Gast)


Angehängte Dateien:

Lesenswert?

@ Christian H.,
ich (bbb) hatte heute nachmittag den falchen Operator (= statt ==) in 
Daniels Programm nicht gesehen. Ich wollte eigentlich nur zeigen, dass 
auch mit den richtigen Operatoren im Grunde nur Ruckzuck die dritte Led 
eingeschaltet wird. Dazu hatte ich Kommentare in Daniels Programm 
eingefügt. Wir sind uns also einig.

@Daniel L.,
ich habe dein Programm um die oben vorgeschlagene Methode mit 
switch/case ergänzt, siehe Anhang. Dabei fliegen die falschen 
Vergleichsoperatoren als Nebeneffekt raus. Das Programm funktioniert bei 
mir einwandfrei auf einem Mega8.

bbb

von daniel lauss (Gast)


Lesenswert?

danke für die tolle antwort :) es funktioniert jetzt genau wie ich es 
mir vorstelle ^^

von bbb (Gast)


Lesenswert?

Gern geschehen.
Danke für die Rückmeldung.

bbb

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.