LED umschalten mit Taster

OP #3296909
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
Gast #3296926
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.
OP #3296930
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;
Gast #3296954
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
#3296957
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...
Gast #3297441
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!
Persönliche Seite #3297480
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.
Gast #3297677
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
Angehängte Dateien:

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