intTasterBit=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
voidmain(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
intEntpreller(intPin)// Der Tasterwert wird in Pin übernommen
27
{
28
intKontrolllauf=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)
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.
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.
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.
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.
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.
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.
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'.
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
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!
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.
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