Forum: Compiler & IDEs Bitte um Erklärung bei kleinen C-Code um Schalter abzufragen


von Jupp (Gast)


Lesenswert?

Hallo, habe folgenden Code aus dem microchip PICKit3 LessonGuide und 
verstehe eins nicht und bei einer anderen Stelle bräuchte ich nur ne 
kurze Erläuterung.
Danke für die Hilfe.

PS: Switch_Pin ist RB0 und DetectsInARow ist einfach 5.

void  main  (void)
{
            while (Switch_Count < DetectsInARow);
unsigned  char  Switch_Count  =  0;
LED_Display  =  1;//  initialize
TRISD  =  0b00000000;//  PORTD  bits  7:0  are  all  outputs  (0)



INTCON2bits.RBPU  =  0;//  enable  PORTB  internal  pullups
WPUBbits.WPUB0  =  1;//  enable  pull  up  on  RB0

???Was machen diese beiden Befehle? Bzw. was Sie machen ist klar,
???aber was würde passieren, wenn ich das nicht eintippen würde?



ANSELH  =  0x00;//  AN8-12  are  digital  inputs  (AN12  on  RB0)
TRISBbits.TRISB0  =  1;//  PORTB  bit  0  (connected  to  switch)  is 
input  (1)
while  (1)
{
   LATD  =  LED_Display;//  output  LED_Display  value  to  PORTD  LEDs
   LED_Display  <<=   1;//  rotate  display  by  1
   if  (LED_Display  ==  0)
       LED_Display  =  1;
//  rotated  bit  out,  so  set  bit  0
   while  (Switch_Pin  !=  1);//  wait  for  switch  to  be  released
   Switch_Count = 5;


????Warum Switch_Count = 5??????????????

   do
   { // monitor switch input for 5 lows in a row to debounce if
        (Switch_Pin == 0)
        { // pressed state detected
             Switch_Count++;
        }
        else
        {
           Switch_Count  =  0;
        }
        Delay10TCYx(25); // delay 250 cycles or 1ms. }
  while (Switch_Count < DetectsInARow);

von Laszlo H. (mobius)


Lesenswert?

Also, Pull-Ups sind dir ein Begriff? Wenn nicht [1] hilft. Und intern 
bedeutet halt, dass sie im IC selber drin sind. Damit spart man sich 
einen externen Widerstand / Schalter. Ohne die wirst du die Tasten gegen 
GND nicht auslesen können.

Zum Zweiten, das Programm willt 5 low Zustände hintereinander einlesen, 
bevor es weiterspringt. Ist die Taste schon gedrückt, wenn er in die 
Schleife reinspringt, passiert nichts, da die Abbruchbedingung mit 
Switch_Count = 6 (also 1x Switch_Count++ - Branch) erfüllt ist. Ist sie 
es nicht, wird es halt auf 0 gesetzt, so lange der Eingang 1 ist, danach 
bei einer 0 (= gedrückt) incrementiert). Sobald nun Switch_Count wieder 
5 ist (prellen hat ein Ende & 5x low hintereinander) ist die Hexerei zu 
ende.

gruß
mobius

[1] http://www.elektronik-kompendium.de/public/schaerer/pullr.htm

btw, es gibt einen Code tag ;).

von Jupp (Gast)


Lesenswert?

Ich raffes immer noch nicht ganz, ich versuche mal meine Deutung zu 
erläutern:

while  (Switch_Pin  !=  1);//  wait  for  switch  to  be  released

In der while Schleife hängt er so lange bis ich den Taster loslasse.

Switch_Count = 5;

Dann setzt er Switch_Count auf 5
und geht in die Überprüfung.
Da ich aber vorher Switch_Count = 5 gesetzt habe, ist die Überprüfung 
auf einen Tastendruck bereits im ersten Durchlauf fertig.

Alles natürlich gemäß der Theorie ich schaff es so schnell den Taster 
los zu lassen und wieder zu drücken,
was wohl nicht geht.

ABER, nach meiner Meinung macht dieser Befehl
Switch_Count = 5;
einfach keinen logischen Sinn, das ist es was mich stört.

Hoffe ich hab mich verständlich ausgedrückt.

von Karl H. (kbuchegg)


Lesenswert?

Du hast recht, sonderlich viel Sinn maxcht es nicht. Auf der anderen 
Seite spielt es auch keine so grosse Rolle.

Ich formatiere mal und schreib ein paar Kommentare dazu
1
   // offenbar ist Switch_Pin genau dann 1, wenn die Taste nicht gedrückt ist
2
   // hier wird also darauf gewartet, dass die Taste in ihrem Ruhezustand ist
3
   while  (Switch_Pin  !=  1)
4
     ;
5
6
   //
7
   // Das wars: Switch_Pin ist nicht mehr 0, d.h. die Taste ist in ihrem
8
   // Ruhezustand und Switch_Pin liefert daher eine 1
9
10
   Switch_Count = 5;
11
12
   do
13
   {
14
     // an dieser Stelle ist klar, dass Switch_Pin beim ersten Betreten
15
     // der Schleife eine 1 sein wird. Denn genau darauf wurde ja vor
16
     // der Schleife gewartet.
17
     //
18
     // Daher wird dieses if nicht genommen ....
19
     //
20
     if( Switch_Pin == 0 ) 
21
     {
22
       Switch_Count++;
23
     }
24
25
     // ... sondern dieses else hier
26
     else
27
     {
28
       // und damit Switch_Count auf 0 gesetzt.
29
       // Die Zuweisung von oben ist damit wirkungslos
30
       Switch_Count  =  0;
31
     }
32
     Delay10TCYx(25); // delay 250 cycles or 1ms.
33
   } while( Switch_Count < DetectsInARow );

Den einzigen Unterschied, den die Anweisung machen wird, ist wenn die 
Taste beim Loslassen prellt. D.h. Die Warteschleife for der 
Entprellschleife wartet auf die 1, aber der prellende Taster liefert bei 
der unmittelbar darauffolgenden Abfrage bereits wieder eine 0. In diesem 
Fall wird dann Switch_Count noch einmal erhöht und die 2te 
while-Schleife abgebrochen - das Programm detektiert einen Tastendruck, 
wo keiner war.

von Jupp (Gast)


Lesenswert?

Danke Karl Heinz also besitze ich doch noch einen "gesunden" 
Menschenverstand ;)

Jetzt kanns weiter gehen :)

von Karl H. (kbuchegg)


Lesenswert?

Der ganze Entprellmechanismus ist Sch....

von Jupp (Gast)


Lesenswert?

sch...ön wolltest du wohl sagen,

aber warum?

Sinn macht das doch, wenn man die 5ms zeit hat oder?

von Karl H. (kbuchegg)


Lesenswert?

Jupp schrieb:
> sch...ön wolltest du wohl sagen,
>
> aber warum?
>
> Sinn macht das doch, wenn man die 5ms zeit hat oder?

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

ist besser:
Sie braucht keine delay, kommt mit allen Tasten klar (selbst wenn sie 
noch so prellen), registriert Tastendrücke auch dann wenn das Programm 
anderweitig beschäftigt ist (solange Interrupts freigegeben sind) und 
behandelt maximal 8 Tasten in einem Aufwasch bei weniger Code. 
Zusätzlich unterscheidet sie noch zwischem kurzem und langem Tastendruck 
und erzeugt auf Wunsch auch noch Autorepeat.

Einziger Nachteil: man müsste sie auf deinen Prozessor anpassen :-)

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.