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


von C Entprellanfänger (Gast)


Lesenswert?

Bitte zerlegen, verbessern und kritisieren.
1
int Entpreller(int Pin);  // Entprellfunktion einbinden
2
 #define Taster PORTEbits.RE2 //Taster definieren
3
int TasterBit =0;        // Bei Beginn wird der Taster als nicht geschaltet angenommen, besser Lösung? =Taster gibt Fehler
4
/** D E C L A R A T I O N S **************************************************/
5
void main (void)
6
{
7
  
8
    TRISD = 0b00000000;         // PORTD bits 7:0 are all outputs (0)
9
    ADCON1 = 0x0F;              // AN0-7 are digital inputs 
10
    TRISEbits.TRISE2 = 1;       // PORTE bit 2 als Eingang (1) vom Board P40
11
12
13
14
    while (1) //Hauptprogramm
15
    {
16
 if(TasterBit==0)    // Prüfen ob Bit gesetzt ist
17
     LATD = 0b00000000; 
18
 else
19
    LATD = 0b11111111;     
20
TasterBit=Entpreller(Taster);  //Entprellfunktion für Taster aufrufen
21
  }   
22
        
23
}    
24
25
26
int Entpreller(int Pin)    // Der Tasterwert wird in Pin übernommen
27
{
28
int Kontrolllauf=1;
29
do              //Do -While solange Kontrolllauf kleiner 5
30
{
31
if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
32
{    
33
return(Pin);
34
}
35
if(Pin!=TasterBit)      // Wenn ungleich, wird kurz gewartet und der Kontrollauf höher gesetzt.
36
{
37
Delay10TCYx(25);
38
Kontrolllauf++;
39
}
40
}
41
while(Kontrolllauf<=5);
42
return(Pin);
43
}

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)

von Hc Z. (mizch)


Lesenswert?

Das geht ja durcheinander wie Kraut und Rüben.  Einrückungen wurden 
bereits erfunden.
1
int Entpreller(int Pin);  // Entprellfunktion einbinden
2
#define Taster PORTEbits.RE2 //Taster definieren
3
int TasterBit =0;        // Bei Beginn wird der Taster als nicht geschaltet angenommen, besser Lösung? =Taster gibt Fehler
4
/** D E C L A R A T I O N S **************************************************/
5
void main (void)
6
{
7
  
8
  TRISD = 0b00000000;         // PORTD bits 7:0 are all outputs (0)
9
  ADCON1 = 0x0F;              // AN0-7 are digital inputs 
10
  TRISEbits.TRISE2 = 1;       // PORTE bit 2 als Eingang (1) vom Board P40
11
12
  while (1) //Hauptprogramm
13
    {
14
      if(TasterBit==0)    // Prüfen ob Bit gesetzt ist
15
        LATD = 0b00000000; 
16
      else
17
        LATD = 0b11111111;     
18
      TasterBit=Entpreller(Taster);  //Entprellfunktion für Taster aufrufen
19
    }   
20
        
21
}    
22
23
24
int Entpreller(int Pin)    // Der Tasterwert wird in Pin übernommen
25
{
26
  int Kontrolllauf=1;
27
  do              //Do -While solange Kontrolllauf kleiner 5
28
    {
29
      if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
30
        {    
31
          return(Pin);
32
        }
33
      if(Pin!=TasterBit)      // Wenn ungleich, wird kurz gewartet und der Kontrollauf höher gesetzt.
34
        {
35
          Delay10TCYx(25);
36
          Kontrolllauf++;
37
        }
38
    }
39
  while(Kontrolllauf<=5);
40
  return(Pin);
41
}

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

2 Variablen sind entweder gleich oder sie sind es nicht:
1
     if(Pin==TasterBit)      // Wenn Taster und Bit gleich sind, wieder zum Hauptprogramm zurück
2
        {    
3
          return(Pin);
4
        }
5
      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.

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von C Entprellanfänger (Gast)


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.

von Karl H. (kbuchegg)


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.

von C Entprellanfänger (Gast)


Lesenswert?

Ich nehme alles zurück und behaupte das gegentwil ;)

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

von C Entprellanfänger (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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'.

von Peter D. (peda)


Lesenswert?

Ooch nöö.

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

Beitrag "Universelle Tastenabfrage"


Peter

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von xGast (Gast)


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

von C Entprellanfänger (Gast)


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!

von Karl H. (kbuchegg)


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.

von goil (Gast)


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 ;-)

von Frank L. (hermastersvoice)


Lesenswert?

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

von alf (Gast)


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.

von Peter D. (peda)


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

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.