Forum: Mikrocontroller und Digitale Elektronik Abfrage von Tastern


von Fred (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Community,

ich habe erst vor kurzem angefangen mich mit Mikrocontrollern (Attiny 
2313) zu befassen und wollte jetzt eine Binäruhr programmieren.
Die Anzeige der Zeit funktioniert auch schon nur mit der Abfrage von 
Tastern um die Uhrzeit einzustellen habe ich Probleme.
In der Timerroutine, in der die Zeit berechnet wird, habe ich folgende 
Abfrage des Tasters.
1
ISR(TIMER1_OVF_vect)
2
{
3
Zeitberechnung....
4
5
 if(!(PINB & (1<<PB7))) // Wenn Taste = Low
6
    {
7
      stunden++;
8
    }
9
  PORTD = stunden;
10
}

Mein Problem ist nun, obwohl kein Taster gedrückt ist, die Anzeige der 
Stunden im Sekundentakt hochzählt.

Bitte helft mir, obwohl ich schon im Forum gelesen habe finde ich den 
Fehler einfach nicht, oder ist die Herangehensweise komplett falsch?

von Nico (nico123)


Lesenswert?

Wie ist dein Taster denn angeschlossen? Verbindet er PB7 mit Masse bei 
Betätigung und ist ein Pullup-Widerstand von PB7 vorhanden?

von Uwe (de0508)


Lesenswert?

Hallo Fred,

Stichwort Taster prellen "immer"; du musst auch die Flankenwechsel 
detektieren, sonst Zählt deine ISR den Zähler sehr sehr schnell hoch.

Desweiteren benötigten Variable die in ISR Routinen verändert werden ein 
volatile davor.

Zum Thema Taster prellen durchsuche mal das Forum und dann kannst Du 
eine einer 100.000 Threads lesen.

Stichwort PeDa Entprellung.

von J.-u. G. (juwe)


Lesenswert?

Mit dieser Anweisung:
1
PORTB = minuten;
vor Deiner Tastenabfrage schaltest Du die internen Pullup-Widerstände 
bei PB6 und PB7 aus (Die Du richtigerweise bei der Initialisierung 
eingeschaltet hast).

von Fred (Gast)


Lesenswert?

vielen Dank für die schnellen Antworten,


PB7 verbindet mit Masse bei Betätigung, der Pullup-Widerstand von PB7 
ist aktiviert, was mich gleich zur nächsten Frage bringt. Wieso schaltet 
die Anweisung PORTB = minuten die internen Pullup-Widerstände aus?
Eigentlich sollte er die Zeit binär auf den Port ausgeben.
Zum Thema entprellen, ich glaube ich muss mich mit damit doch noch 
intensiver befassen.

von Karl H. (kbuchegg)


Lesenswert?

Fred schrieb:
> vielen Dank für die schnellen Antworten,
>
>
> PB7 verbindet mit Masse bei Betätigung, der Pullup-Widerstand von PB7
> ist aktiviert, was mich gleich zur nächsten Frage bringt. Wieso schaltet
> die Anweisung PORTB = minuten die internen Pullup-Widerstände aus?

Weil jede direkte Zuweisung an PORTB alle Bits des Ports beeinflusst.
Und sehr wahrscheinlich sind in deiner Variablen minute die 
entsprechenden Bits, die für PB6 bzw. PB7 zuständig sind, eben nicht auf 
0.

> Eigentlich sollte er die Zeit binär auf den Port ausgeben.

Schon. Aber am gleichen Port hängen ja auch die Taster.
D.h. wenn du am PORTB ausgibst, musst du darauf achten, dass du die den 
1-Zustand von PB6 bzw. PB7 nicht zerstörst. Sonst .... schaltest du die 
Pullups wieder aus.
Dein µC weiß ja nicht, dass du mit zum Beispiel

   PORTB = 0;

eigentlich die Zustände von PB6 und PB7 gar nicht verändern wolltest. 
Nur: Der µC macht das was du programmiert hast und nicht das was du 
eigentlich wolltest. Und da steht nun mal an Port B allen Bits eine 0 
zuweisen. Und das beinhaltet selbstverständlich auch PB6 und PB7, die 
damit auf 0 gesetzt werden und daher die entsprechenden Pullups wieder 
ausschalten.

Ob da jetzt
   PORTB = 0;
oder
   PORTB = 2;
oder
   PORTB = minuten;

steht, ist ja Jacke wie Hose. Für die Pullups entscheidend ist nur, ob 
Bit 6 bzw. Bit 7 in dem was zugewiesen wird auf 0 oder auf 1 ist.
Und bei dir sind die beiden Bits auf 0.

Wenn du also den Zustand dieser beiden Bits nicht verändern willst, dann 
hast du 2 Möglichkeiten
a) die faule. Du weißt, dass die beiden eigentlich auf 1 sein müssen, 
daher sorgst du dafür, dass bei der Zuweisung die beiden Bits auf jeden 
Fall wieder eine 1 bekommen
1
  PORTB = minuten | (1<<PB6) | (1<<PB7);
b) du übernimmst den Zustand der Bits vom Port selber und sorgst dafür, 
dass er nicht verloren geht
1
  PORTB = ( minuten & 0x3F) | ( PORTB & ((1<<PB6) | (1<<PB7)));

von Nico (nico123)


Lesenswert?

Wenn Du auf PORTB etwas schreibst, dann werden an den Ports an denen das 
Bit = 0 ist die internen Pullups deaktiviert. Sieh in deinen Code, dort 
machst Du es ja beim Aktivieren der Pullups!
Du musst also deinen Minutenwert maskieren bevor Du ihn auf den Port 
schreibst, damit Du nur die Bits veränderst die Du benötigst.

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.