Forum: Compiler & IDEs Taster geht nicht! Debouce Funktion greift nicht ...


von Henni (Gast)


Lesenswert?

Moin Community,

also ich hab folgendes Problem. Ich habe eine Schaltung an der 2 LED 
angeschlossen sind und ein Taster der auf Masse geht. Die 4 PINS sollen 
von PORTA realisiert werden.

PA0 = blinke LED
PA1 = LED die durch einen Taster ab und aus geschaltet wird
PA2 = Taster [Eingang internen aktiver pull upp]
PA7 = LED die permanent leuchte (Betriebsbereitschaft)

Ich hab die Funktion aus dem tutorial übernommen und angepasst. Aber 
allerdings funktioniert der Taster nicht. Bzw. PINA2 wo der Taster auf 
Masse angeschlossen ist zeigt keine Wirkung. Die Debounce funktion 
greift nicht.

Ohne Debouce Funktion leuchtet erwartungsgemäß die LED ???

Kann mir einer von euch helfen??? Taster Funzt nicht.


1
#include "avr/io.h"
2
#include "inttypes.h"
3
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
8
#include "util/delay.h"
9
10
11
12
13
int main(void)
14
{
15
16
  uint8_t i=0;
17
  
18
  
19
  DDRA = 0b10000011;
20
  PORTA= 0b10000111;  
21
  
22
23
  inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
24
  {
25
      if ( ! (*port & (1 << pin)) )
26
      {
27
          /* Pin wurde auf Masse gezogen, 100ms warten   */
28
          _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
29
          _delay_ms(50); 
30
31
            if ( *port & (1 << pin) )
32
            {
33
              /* Anwender Zeit zum Loslassen des Tasters geben */
34
              _delay_ms(50);
35
              _delay_ms(50); 
36
              return 1;
37
            }
38
      }
39
    return 0;
40
  }
41
42
43
  while(1)
44
  {
45
46
  PORTA ^= (1 << PA0);
47
48
    for(i=0;i<10;i++)
49
    {
50
    _delay_ms(10);
51
    }
52
53
  
54
      if (debounce(&PINA, PA2)) 
55
    {                /* Falls Taster an PIN PB0 gedrueckt..    */
56
        PORTA = PINA ^ ( 1 << PA1 );/* ..LED an Port PD7 an-*/
57
    }              /* bzw. ausschalten */
58
  }
59
60
61
return 0;
62
}

danke groetjes Henni

von Oliver (Gast)


Lesenswert?

Wenn dein Prigramm nichts weiter tun soll, als die LED'S zu schalten, 
lass die "debounce"-Funktion einfach weg, die braucht es dafür nicht.

Soll das Programm später einmal erweitert werden, und etwas sinnvolles 
tun, dan schmeiss diese "debounce"-Funktion weg, denn mit diesem Konzept 
wird das nichts. Dein Programm wartet die meiste Zeit in sinnlosen 
delays.

Du wirst nicht drumrumkommen, so etwas wie dieses erprobte Beispiel zu 
realisieren:
Beitrag "Tasten entprellen - Bulletproof"

Oliver
P.S. Wo im Tutorial steht denn die Vorlage zu deinem Code?

von Henni (Gast)


Lesenswert?

Hi,

das beispiel ist ja für ASM und wenn ich die debouce Funktion weglasse
blinkt meine zweite LED einfach. Also der Taster spielt keine Rolle.
Die debouce Funktion guckt doch ob sich der Zustand am pin geändert hat 
?!

groetjes Henni

von Oliver (Gast)


Lesenswert?

Ein paar Hinweise:

C kennt keine verschachtelten Funktionen.
Standard-Header werden üblicherweise mit <> includiert.

Und last, but not least:
Dein Finger ist zu langsam :-)

Geh deine debounce-Funktion mal Schritt für Schritt durch, und überlege, 
was da passiert. Hilfreich ist es auch, sich das mal im Simulator 
anzuschauen. Da solltest du aber alle delays auskommentieren, sonst 
macht das keinen Spaß.

Nimm bitte die Funktionen aus dem o.a link. Die funktionieren.

Oliver

von Henni (Gast)


Lesenswert?

Danke,

ich hab das jetzt ein wenig geändert und nun funzt es :). Naja aber 
eingeschränkt, zeitweise richtig, manchmal setzt ein wenig aus. Ich 
vermute aber die kontakte und mein blödes bread bord sind dran schuld ?!

den link für den quellcode den ich benutzt habe:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Tasten_und_Schalter

Mein aktueller Code:
1
#include "avr/io.h"
2
#include "inttypes.h"
3
4
#ifndef F_CPU
5
#define F_CPU 1000000UL
6
#endif
7
8
#include "util/delay.h"
9
10
11
12
13
int main(void)
14
{
15
16
  uint8_t i=0;
17
  
18
  
19
  DDRA = 0b10000011;
20
  PORTA= 0b10000111;  
21
  
22
23
  inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
24
  {
25
      if ( ! (*port & (1 << pin)) )
26
      {
27
          /* Pin wurde auf Masse gezogen, 100ms warten   */
28
          _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
29
          _delay_ms(50); 
30
      return 1;
31
    }
32
      if ( *port & (1 << pin) )
33
      {
34
          /* Anwender Zeit zum Loslassen des Tasters geben */
35
          _delay_ms(50);
36
            _delay_ms(50);   
37
      return 0;
38
        }
39
  }
40
41
42
  while(1)
43
  {
44
45
  PORTA ^= (1 << PA0);
46
47
    for(i=0;i<100;i++)
48
    {
49
    _delay_ms(10);
50
    }
51
52
  
53
      if (debounce(&PINA, PA2) ) 
54
    {                /* Falls Taster an PIN PB0 gedrueckt..    */
55
        PORTA = PINA ^ ( 1 << PA1 );/* ..LED an Port PD7 an-*/
56
    }              /* bzw. ausschalten */
57
  }
58
59
60
return 0;
61
}

Henni

von Karl H. (kbuchegg)


Lesenswert?

Henni wrote:
> Danke,
>
> ich hab das jetzt ein wenig geändert und nun funzt es :). Naja aber
> eingeschränkt, zeitweise richtig, manchmal setzt ein wenig aus. Ich
> vermute aber die kontakte und mein blödes bread bord sind dran schuld ?!

Wenn dein Board Wackelkontakte hat, könnte das sein.
Ansonsten: Benutz die PeDa Entprellung wie bereits einmal
gesagt.

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

Entprellung mittels Warteschleifen: Du verschwendest deine
Zeit damit.

von Simon K. (simon) Benutzerseite


Lesenswert?

Oliver wrote:
> C kennt keine verschachtelten Funktionen.

Nicht dass es zu Missverständnissen kommt. Was ist hier gemeint?

von Karl H. (kbuchegg)


Lesenswert?

Simon Küppers wrote:
> Oliver wrote:
>> C kennt keine verschachtelten Funktionen.
>
> Nicht dass es zu Missverständnissen kommt. Was ist hier gemeint?
1
void foo()
2
{
3
  void bar()
4
  {
5
  }
6
}

Das ist kein Standard-C, auch wenn es der gcc akzeptiert.

von Simon K. (simon) Benutzerseite


Lesenswert?

Jou, das geht in der Tat nicht, da habt ihr Recht. Aber was hätte das 
fürn Sinn? *grübel

Vermutlich keinen, weil es sonst zum C-Standard gehören würde. Hehe!

von Karl H. (kbuchegg)


Lesenswert?

Simon Küppers wrote:
> Jou, das geht in der Tat nicht, da habt ihr Recht. Aber was hätte das
> fürn Sinn? *grübel
>
> Vermutlich keinen, weil es sonst zum C-Standard gehören würde. Hehe!

Och, das würde ich so nicht sagen.
Das macht schon auch Sinn, weil ja durch die Funktion ein
Scope eröffnet wird:
1
void foo()
2
{
3
  int i, j;
4
5
  void bar()
6
  {
7
    int i;
8
9
    j = i;     // das j stammt von foo
10
  }
11
}
12
13
void foo2()
14
{
15
  int a, b;
16
17
  void bar()   // ich kann hier nochmal eine Funktion bar
18
               // machen, die mit der in foo nicht kollidiert
19
  {
20
    a = b;
21
  }
22
}

Die Sinnhaftigkeit ist im Grunde dieselbe, die auch zu einer
Änderung der Variablendefinition geführt hat:
Früher mussten alle Variablen am Funktionsanfang definiert
werden. Dann wurde das geändert: in jedem Block können
Variablen definiert werden, die sich auch nicht ins Gehege
kommen.
1
void foo()
2
{
3
  int i;
4
5
  while( 1 ) {
6
    // Ein neuer Block. Damit können hier neue 'blocklokale'
7
    // Variablen erzeugt werden, die den Block nicht überleben
8
9
    int k = 5;
10
  }
11
12
  // hier gibt es kein k mehr
13
}

Die Idee dahinter ist es, Variablen erst dann zu definieren, wenn
sie auch tatsächlich gebraucht werden.
So ähnlich kann man das auch mit Funktionen sehen:
Eine Funktion kann nur in dem Kontext definiert werden, in dem
sie auch benutzt wird. Die übergeordnete Funktion fungiert als
eine Art 'Sichtbarkeitsbremse'. Ausserhalb davon weiss niemand was
von der Funktion.

In Ur-Pascal war das eine sinnvolle Sache. In C ist der Sinn
aber, na ja, etwas zweifelhaft, weil man ja mit Aufteilung von
Funktionen in verschiedene Files und static-Funktionen dasselbe
erreichen kann.

Compilertechnisch ist das ganze auch kein grosses Problem, nur
ist wahrscheinlich die Nachfrage danach nicht gross genug, sodass
das Standard-Kommitee bisher keine Veranlassung fand sowas zu
normieren.

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.