Forum: Mikrocontroller und Digitale Elektronik Taster am ATMega 16


von Timo (Gast)


Lesenswert?

Hallo ...

Also mein Programm läuft dank des Forums super und ich lerne dank euch 
dazu ... also nun bin ich da angekommen, dass ich drei Taster an meinen 
ATMega16 anschließen möchte ... also ich weiß, dass es einem High - 
Aktiv und einmal Low - Aktiv gibt ... mir egal, was ich verwende ... bin 
da net festgelegt ... ich bin ebenfalls mit dem Einstellen der Richtung 
des Ports vertraut ... sprich ... DDR = 0xff; oder DDR = 0x00; ...
Nun kann man ja mit Pin auf den Port zugreifen ... möchte aber nur 
einzellne Pins abfragen, so dass ich mehrere Taster an einen Port hängen 
kann ...

Zum Beispiel an PortA ...

Taster 1 an Pin PA0
Taster 2 an Pin PA1
Taster 3 an Pin PA2

... mein Ziel ist es per If - Abfrage bzw. swich - Abfrage zu schauen 
welcher Taster gedrückt ist und dem entsprechend eine Aktion ausführen 
...

Also beispielsweise:

Wenn Taster 1 = "High", dann zähle eine Variable um den Wert '1' hoch, 
sonst machte nichts ...

if (... Was schreibe ich nun hier genau rein ... );
{
  Zaehler = Zaehler + 1;
}
else
{
}

Die Taster möchte ich zudem entprellen ... Vielen Dank für die Hilfe ...

Gruß Timo

von Karl H. (kbuchegg)


Lesenswert?

Zunächst mal:
Schalte den Taster low aktiv, das ist einfacher.
Der Taster schaltet also nach Masse durch. Dadurch brauchst
du am Port nur den Pull Up Widerstand aktivieren und
hast dadurch immer einen definierten Pegel:
  Taster nicht gedrückt    -> 1
  Taster gedrückt          -> 0

Den Pullupwiderstand an einem Pin schaltet man ein, indem
der Port auf Eingang geschaltet wird (das ist er nach
einem Reset sowieso) und mit einer PORT Ausgabe das
gewünschte Bit auf 1 gesetzt wird:
1
int main()
2
{
3
   // Port B ist bereits auf Eingabe
4
   //
5
   // Jetzt noch an den Pins 0 und 1 den
6
   // Pullup Widerstand einschalten
7
   PORTB = ( 1 << PB0 ) | ( 1 << PB1 );
8
}

Um einen Pin abzufragen, wird der komplette Port eingelesen.
Danach holt man sich mittels einer Maske die gewünschten
Bits heraus. Dazu braucht man eine Bitweise UND Verknüpfung:

UND
   A   B   Ergebnis
  ------------------
   0   0     0
   0   1     0
   1   0     0
   1   1     1

Das Ergebnis einer Und Verknüpfung ist also immer dann 1
wenn sowohl A als auch B 1 waren. Interessanter ist aber
folgende Beobachtung:
In der 3. und 4. Zeile der UND Tabelle sieht man, dass
das Ergebnis den gleichen Pegel hat wie Eingang B. Das heist
aber auch ich kann mit A das Ergebnis steuern: Ist A 0
dann ist das Ergebnis auf jeden Fall 0. Ist A 1, dann ist
das Ergebnis identisch zum Zustand B.

Und das nutzen wir hier aus: Bei einer bitweisen UND
Verknüpfung kann ich mit einer Maske steuern, welche
Bits einer Zahl übrig bleiben sollen: Setze ich in der
Maske eine 0, dann wird im Ergebnis an genau dieser Stelle
ebenfalls eine 0 auftauchen. Setze ich in der Maske eine 1,
dann bleibt im Ergebnis das ursprüngliche Bit in der zu
untersuchenden Zahl erhalten.

Bsp:  Angenommen vom Port wurde eingelesen:  0b10110100
Und ich interessiere mich für den Zustand vom Bit 3 (Achtung:
Wie üblich werden Bitpositionen bei 0 zu zählen angefangen).
Dann lautet meine Maske 0b00001000

Mache ich die bitweise UND Verknüpfung

     0b10110100      (einfach untereinanderstehende
  &  0b00001000       Bits UND verknüpfen)
     ----------
     0b00000000

Im Ergebnis sind alle Stellen bis auf Bit 3 auf jeden Fall 0.
Da in der interessierenden Zahl an Bitposition 3 ebenfalls eine
0 war, ist auch im Ergebnis eine 0 und damit ist das Ergebnis
insgesamt 0.

Angenommen es interessiert der Zustand von Bit 2. Dann
lautet die Maske 0b00000100

    0b10110100
  & 0b00000100
    ----------
    0b00000100

Wieder: Alles bis auf Bit 2 ist mit Sicherheit 0 (weil ja
in der Maske in dieser Stelle 0en sind). Die Und Verknüpfung
von Bit 2 der Zahl und Bit 2 der Maske ergibt aber eine 1 und
daher taucht diese 1 an dieser Stelle auch im Ergebnis wieder
auf -> Das Ergebnis ist insgesamt nicht 0.


Sagen wir, der Taster liegt auf Bitposition 6 am Port B.
Dann würde die Maske 0b01000000 lauten. Eine gleichwertige,
aber übersichtlichere Schreibweise dafür ist: 1 << 6 oder
aber, da wir vom Port B reden,  1 << PB6

  if ( PINB & ( 1 << PB6 ) ) {
    // Taster ist nicht gedrückt
  }

oder aber, da ja meistens interessiert, ob ein Taster
gedrückt wurde:

  if( (PINB & ( 1 << PB6 )) == 0 ) {
    // Taster ist gedrückt
  }

> Die Taster möchte ich zudem entprellen
Das ist dann wieder eine andere Geschichte. Da schaust du
dir am besten (nachdem du mit obigen experimentiert hast
und deine ersten Schritte mit Timern gemacht hast) das
hier mal an:

http://www.mikrocontroller.net/articles/Entprellung

von Timo (Gast)


Lesenswert?

Vielen dank ... dass hilft mir sehr weiter ...
Noch eine ganz kurze Frage:

Und zwar habe ich ja interne Pullup´s aktiviert ... bönötige ich nun die 
externen trotzdem, oder ersetzen die internen diese komplett?

Mit freundlichen Grüßen Timo

von Karl H. (kbuchegg)


Lesenswert?

Timo wrote:
> Vielen dank ... dass hilft mir sehr weiter ...
> Noch eine ganz kurze Frage:
>
> Und zwar habe ich ja interne Pullup´s aktiviert ... bönötige ich nun die
> externen trotzdem, oder ersetzen die internen diese komplett?
>

Du brauchst keine externen mehr.
Deswegen bevorzugt man ja meist low-active Taster: Ausser
dem Taster ist keine weitere Hardeware mehr nötig.

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.