www.mikrocontroller.net

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


Autor: Henni (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.


#include "avr/io.h"
#include "inttypes.h"

#ifndef F_CPU
#define F_CPU 1000000UL
#endif

#include "util/delay.h"




int main(void)
{

  uint8_t i=0;
  
  
  DDRA = 0b10000011;
  PORTA= 0b10000111;  
  

  inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
  {
      if ( ! (*port & (1 << pin)) )
      {
          /* Pin wurde auf Masse gezogen, 100ms warten   */
          _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
          _delay_ms(50); 

            if ( *port & (1 << pin) )
            {
              /* Anwender Zeit zum Loslassen des Tasters geben */
              _delay_ms(50);
              _delay_ms(50); 
              return 1;
            }
      }
    return 0;
  }


  while(1)
  {

  PORTA ^= (1 << PA0);

    for(i=0;i<10;i++)
    {
    _delay_ms(10);
    }

  
      if (debounce(&PINA, PA2)) 
    {                /* Falls Taster an PIN PB0 gedrueckt..    */
        PORTA = PINA ^ ( 1 << PA1 );/* ..LED an Port PD7 an-*/
    }              /* bzw. ausschalten */
  }


return 0;
}

danke groetjes Henni

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Henni (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Henni (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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-Tu...

Mein aktueller Code:
#include "avr/io.h"
#include "inttypes.h"

#ifndef F_CPU
#define F_CPU 1000000UL
#endif

#include "util/delay.h"




int main(void)
{

  uint8_t i=0;
  
  
  DDRA = 0b10000011;
  PORTA= 0b10000111;  
  

  inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
  {
      if ( ! (*port & (1 << pin)) )
      {
          /* Pin wurde auf Masse gezogen, 100ms warten   */
          _delay_ms(50);  // max. 262.1 ms / F_CPU in MHz
          _delay_ms(50); 
      return 1;
    }
      if ( *port & (1 << pin) )
      {
          /* Anwender Zeit zum Loslassen des Tasters geben */
          _delay_ms(50);
            _delay_ms(50);   
      return 0;
        }
  }


  while(1)
  {

  PORTA ^= (1 << PA0);

    for(i=0;i<100;i++)
    {
    _delay_ms(10);
    }

  
      if (debounce(&PINA, PA2) ) 
    {                /* Falls Taster an PIN PB0 gedrueckt..    */
        PORTA = PINA ^ ( 1 << PA1 );/* ..LED an Port PD7 an-*/
    }              /* bzw. ausschalten */
  }


return 0;
}


Henni

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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/Entprellun...

Entprellung mittels Warteschleifen: Du verschwendest deine
Zeit damit.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver wrote:
> C kennt keine verschachtelten Funktionen.

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon Küppers wrote:
> Oliver wrote:
>> C kennt keine verschachtelten Funktionen.
>
> Nicht dass es zu Missverständnissen kommt. Was ist hier gemeint?
void foo()
{
  void bar()
  {
  }
}

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
void foo()
{
  int i, j;

  void bar()
  {
    int i;

    j = i;     // das j stammt von foo
  }
}

void foo2()
{
  int a, b;

  void bar()   // ich kann hier nochmal eine Funktion bar
               // machen, die mit der in foo nicht kollidiert
  {
    a = b;
  }
}

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.
void foo()
{
  int i;

  while( 1 ) {
    // Ein neuer Block. Damit können hier neue 'blocklokale'
    // Variablen erzeugt werden, die den Block nicht überleben

    int k = 5;
  }

  // hier gibt es kein k mehr
}

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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.