www.mikrocontroller.net

Forum: Compiler & IDEs C-Funktion zum Entprellen eines Anfängers


Autor: C Entprellanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte zerlegen, verbessern und kritisieren.
int Entpreller(int Pin);  // Entprellfunktion einbinden
 #define Taster PORTEbits.RE2 //Taster definieren
int TasterBit =0;        // Bei Beginn wird der Taster als nicht geschaltet angenommen, besser Lösung? =Taster gibt Fehler
/** D E C L A R A T I O N S **************************************************/
void main (void)
{
  
    TRISD = 0b00000000;         // PORTD bits 7:0 are all outputs (0)
    ADCON1 = 0x0F;              // AN0-7 are digital inputs 
    TRISEbits.TRISE2 = 1;       // PORTE bit 2 als Eingang (1) vom Board P40



    while (1) //Hauptprogramm
    {
 if(TasterBit==0)    // Prüfen ob Bit gesetzt ist
     LATD = 0b00000000; 
 else
    LATD = 0b11111111;     
TasterBit=Entpreller(Taster);  //Entprellfunktion für Taster aufrufen
  }   
        
}    


int Entpreller(int Pin)    // Der Tasterwert wird in Pin übernommen
{
int Kontrolllauf=1;
do              //Do -While solange Kontrolllauf kleiner 5
{
if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
{    
return(Pin);
}
if(Pin!=TasterBit)      // Wenn ungleich, wird kurz gewartet und der Kontrollauf höher gesetzt.
{
Delay10TCYx(25);
Kontrolllauf++;
}
}
while(Kontrolllauf<=5);
return(Pin);
}

Kann ich auch ne variable kleiner int nehmen?
bool geht komischerweise nicht.
int TasterBit=0; gefällt mir nicht, weiß aber net wie ich es besser 
lösen kann.

Ist das Programm sinnvoll, dank 2 Bier frage ich mich grade ob ich das 
Entprellen selbst verstanden habe ;) (Trotz Artikel)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht ja durcheinander wie Kraut und Rüben.  Einrückungen wurden 
bereits erfunden.
int Entpreller(int Pin);  // Entprellfunktion einbinden
#define Taster PORTEbits.RE2 //Taster definieren
int TasterBit =0;        // Bei Beginn wird der Taster als nicht geschaltet angenommen, besser Lösung? =Taster gibt Fehler
/** D E C L A R A T I O N S **************************************************/
void main (void)
{
  
  TRISD = 0b00000000;         // PORTD bits 7:0 are all outputs (0)
  ADCON1 = 0x0F;              // AN0-7 are digital inputs 
  TRISEbits.TRISE2 = 1;       // PORTE bit 2 als Eingang (1) vom Board P40

  while (1) //Hauptprogramm
    {
      if(TasterBit==0)    // Prüfen ob Bit gesetzt ist
        LATD = 0b00000000; 
      else
        LATD = 0b11111111;     
      TasterBit=Entpreller(Taster);  //Entprellfunktion für Taster aufrufen
    }   
        
}    


int Entpreller(int Pin)    // Der Tasterwert wird in Pin übernommen
{
  int Kontrolllauf=1;
  do              //Do -While solange Kontrolllauf kleiner 5
    {
      if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
        {    
          return(Pin);
        }
      if(Pin!=TasterBit)      // Wenn ungleich, wird kurz gewartet und der Kontrollauf höher gesetzt.
        {
          Delay10TCYx(25);
          Kontrolllauf++;
        }
    }
  while(Kontrolllauf<=5);
  return(Pin);
}

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

Bewertung
0 lesenswert
nicht lesenswert
C Entprellanfänger schrieb:
> Bitte zerlegen, verbessern und kritisieren.

Von einem Tastenentprellen, welches auf delays basiert, halte ich 
grundsätzlich nicht viel.

Bei deiner Funktion Enptreller fällt mir auf, dass sie in beiden Fällen 
denselben Return-Wert hat. hmm. Wie unterscheidet dann der Aufrufer, ob 
die Taste gedrückt wurde oder nicht?

Das Zusammenspiel aus globaler Variable + der vorgeschriebenen Zuweisung 
des Funktionsergebnisses an die Variable Tasterbit ist einfach nur 
ekelhaft.

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

Bewertung
0 lesenswert
nicht lesenswert
2 Variablen sind entweder gleich oder sie sind es nicht:
     if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
        {    
          return(Pin);
        }
      if(Pin!=TasterBit)      // Wenn ungleich, wird kurz gewartet und der Kontrollauf höher gesetzt.

Wenn aber ein if wegen nicht erfüllter Bedingung nicht genommen wird, 
muss man nicht die umgekehrte Bedingung noch einmal prüfen.
das 2.te if ist sowas von überflüssig und wird besser durch ein 'else' 
ersetzt bzw. in deinem Fall (da im if nur ein return steht) ist gar 
keine Abfrage notwendig.

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

Bewertung
0 lesenswert
nicht lesenswert
Ich frage mich, wie die Variable Pin in der Funktion Entpreller jemals 
ihren Wert ändern soll? Ausserdem ist der daneben stehende Kommentar 
falsch. Da wird nicht mehr der Taster abgefragt, sondern die Variable 
Pin. Pin hat ihren Wert beim Betreten der Funktion bekommen (vom 
momentan vorliegenden Zustand des Tasters), aber das wars dann auch. Die 
Variable Pin und der Port-Eingang des Tasters sind nicht magisch 
miteinander verknüpft.

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

Bewertung
0 lesenswert
nicht lesenswert
Kommentiere nicht das, was sowieso im Code auch steht. Im besten Fall 
ist der Kommentar nichtssagend. Im schlimmsten Fall ist der Kommentar 
einfach nur falsch. Solche Kommentare sind absolut entbehrlich.

Autor: C Entprellanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muß sie ja nicht, da sich der Pin Taster ändert und somit auch die 
Variable Pin.

Mit MPLAB Sim hat es funktioniert.

Zu meinem Verständnis.

Wenn der Taster umschaltet,
prüfe 5mal ob er wirklich umgeschaltet ist
und dann arbeite damit.

Wird in der Prüfschleife festgestellt, dass nicht umgeschasltet wurde 
breche den Vorgang ab.

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

Bewertung
0 lesenswert
nicht lesenswert
C Entprellanfänger schrieb:
> Muß sie ja nicht, da sich der Pin Taster ändert und somit auch die
> Variable Pin.

No.
C ist nicht Excel

> Mit MPLAB Sim hat es funktioniert.

Glaub ich nicht


> Wenn der Taster umschaltet,
> prüfe 5mal ob er wirklich umgeschaltet ist
> und dann arbeite damit.

Das wäre die Idee gewesen. Imlpementiert hast du aber etwas anderes.

Autor: C Entprellanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nehme alles zurück und behaupte das gegentwil ;)

bei meinem geiste wahren die Variable und der reale Pin magisch 
verknüpft :)

Autor: C Entprellanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soll ich die funktion denn so weiter verfolgen oder auf was anderes 
umsatteln, wenn delays schon nicht so beliebt sind

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

Bewertung
0 lesenswert
nicht lesenswert
C Entprellanfänger schrieb:
> soll ich die funktion denn so weiter verfolgen oder auf was anderes
> umsatteln, wenn delays schon nicht so beliebt sind

Fürs erste: lass es so.
Sobald du mit Timern klarkommst und in deinem Programm eine asynchrone 
Funktione (eine Interrupt Service Routine) implementieren kannst, wird 
es Zeit das Entprellen darauf unmzustellen.


Das heißt nicht, dass du die Funktion nicht überarbetien sollst. Sie hat 
ein grausiges 'Benutzerinterface'.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ooch nöö.

Es gibt doch schon wunderschöne Entprellroutinen, die keine Wünsche 
offen lassen:

Beitrag "Universelle Tastenabfrage"


Peter

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Funktion zum Entprellen eines Anfängers
Warum, frage ich mich, muss man Anfänger eigentlich entprellen?

Autor: xGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Warum, frage ich mich, muss man Anfänger eigentlich entprellen?

na liegt doch auf der Hand. Anfänger fallen öfter auf die Schnautze und 
stehn wieder auf. Das prellt ganz schön :D

Autor: C Entprellanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
al

Peter Dannegger schrieb:
> Beitrag "Universelle Tastenabfrage"

schön und gut, aber ich als ausgewiesener Anfänger kann damit 0 
anfangen.
Hättest da auch gerne in ägyptischen hiroglyphen schreiben können und 
ich hätte genau soviel verstanden.

Danke!

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

Bewertung
0 lesenswert
nicht lesenswert
C Entprellanfänger schrieb:
> al
>
> Peter Dannegger schrieb:
>> Beitrag "Universelle Tastenabfrage"
>
> schön und gut, aber ich als ausgewiesener Anfänger kann damit 0
> anfangen.
> Hättest da auch gerne in ägyptischen hiroglyphen schreiben können und
> ich hätte genau soviel verstanden.

Da du auf einen anderen Prozessor portieren müsstest, sei es diesmal ok. 
Aber deine Kentnisse werden im Lauf der Zeit wachsen, und dann ist es 
Zeit sich diese Funktionalität zu holen. Es spielt dabei keine 
allzugrosse Rolle, ob du alle Details verstehst oder nicht. Der Kern in 
der Interruptfunktion ist schon ein ziemlich tricky, das gestehen dir 
hier sicherlich alle zu. Aber in der Zuverlässigkeit ist diese 
Funktionalität kaum zu schlagen und das ist das wichtige.
Ausserdem ist die angegebene Entprellung einfach zu benutzen und nur 
darauf kommt es dabei letztendlich an.

Autor: goil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"C-Funktion zum Entprellen eines Anfängers"

Wobei da noch immer nicht geklärt ist, was da bei einem Anfänger 
entprellt werden soll ;-)

Autor: Frank L. (hermastersvoice)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anfänger entprellen ist mal was Neues, sonst werden Anfänger hier doch 
eher verprellt...

Autor: alf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wobei da noch immer nicht geklärt ist, was da bei einem Anfänger
> entprellt werden soll

Na seine Finger, mit denen er auf die Taster drückt.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C Entprellanfänger schrieb:
> schön und gut, aber ich als ausgewiesener Anfänger kann damit 0
> anfangen.

Ach komm schon, der Code ist doch kurz und knackig. Ein Timerinterrupt, 
ein paar logische Operationen, das wars auch schon.

Mal Dir mal einen rückstellbaren 2Bit-Zähler aus EXOR-, NOT-, 
AND-Gattern und D-FF auf und takte ihn mit 100Hz, genau das macht der 
Code pro Input-Bit.
2Bit-Zähler heißt, bis zum Überlauf darf kein Rückstellen erfolgen, also 
4-mal muß das Input-Bit stabil bleiben (4 * 10ms = 40ms Entprellzeit).


Da es C ist, kannst Du es einfach auf den PIC portieren.
Einen etwa 10ms Timerinterrupt initialisieren und dann den Handler 
aufrufen.
cli() = global Interrupts sperren,
sei() = global interrupts freigeben.
Und fertig ist die Anpassung.

Du kannst Dir aber auch AVRStudio/Winavr downloaden und es im Simulator 
durchprobieren.

Der Trick an meinem Code ist, die Trennung zwischen 
Entprellen/Flankenerkennung (Timerinterrupt) und Auswertung 
(Mainfunktion).
Beides kostet nur wenige µs, d.h. nirgends wird Zeit nutzlos verwartet.
Das Main kann die Auswertefunktion "get_key_press()" sogar erst 
aufrufen, wenn die Taste schon wieder losgelassen wurde, der Druck geht 
also nicht verloren.


Da logischen Operatoren immer auf ein ganzes Byte arbeiten, wird 
automatisch immer ein ganzer Port entprellt. Es spielt also keine Rolle, 
ob Du eine oder 8 Tasten anschließt. Der Code ist immer gleich und 
dauert auch gleich lang.

Viele andere Code benutzen dagegen ein Array aus separaten Zählern pro 
Taste. Dann dauert ein Code für 8 Tasten aber auch 8-mal länger. 
Obendrein dauern auch die indirekten Zugriffe auf dieses Zähler-Array 
erheblich länger.


Peter

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.