Forum: Mikrocontroller und Digitale Elektronik Taster Entprellung


von Stefan (Gast)


Lesenswert?

Guten Tag,

ich habe eine Frage bezüglich des Codes zur Tastenentprellung nach Peter 
Daneggger der hier auf der Seite beschrieben wird.

http://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29

Und zwar habe ich ein grundsätzliches Versständnissproblem was die 
folgenden Zeilen machen:


#define KEY_DDR         DDRB
#define KEY_PORT        PORTB
#define KEY_PIN         PINB
#define KEY0            0
#define KEY1            1
#define KEY2            2
#define ALL_KEYS        (1<<KEY0 | 1<<KEY1 | 1<<KEY2)

#define REPEAT_MASK     (1<<KEY1 | 1<<KEY2)       // repeat: key1, key2


Mir ist klar das hier die Tasten definiert werden um im späteren 
Programm den Status derer abzufragen. Was mir nicht klar ist, was in den 
einzelnen Variablen abgelegt wird.

Nach meinem Verständnis kann ich jeden Pin einfach über Portbuchstabe 
plus Pinnummer definieren. z.B. PIN B2

Sprich ich hätte einfach gesagt
#define KEY_PORT  PORTB
#define KEY1      PIN1
#define KEY2      PIN2


Im Beispiel wird aber wesentlich mehr deklariert.

Wäre dankbar wenn mir erklären könnte wiso das so ist.


Beste Grüße
Stefan

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


Lesenswert?

Stefan schrieb:
> Nach meinem Verständnis kann ich jeden Pin einfach über Portbuchstabe
> plus Pinnummer definieren. z.B. PIN B2
Diese Definition reicht für einen Menschen aus, um den Portpin zu 
finden. Der Compiler hat da eine etwas andere Sichtweise. Und man muss 
es eben so hinschreiben, wie er es versteht.

> Sprich ich hätte einfach gesagt
Wenn du einen Compiler schreibst, der damit klar kommt, dann kannst du 
das machen. Der GCC kann es nicht.

> Wäre dankbar wenn mir erklären könnte wiso das so ist.
Siehe Bitmanipulation

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Wäre dankbar wenn mir erklären könnte wiso das so ist.

Weil hinter den Begriffen DDRB, PORTB und PINB in Wirklichkeit die 
Adressen stehen, unter denen diese Register im µC angesprochen werden.

> Sprich ich hätte einfach gesagt
> #define KEY_PORT  PORTB

Damit ist aber noch nicht klar, wo im Adressraum das DDR Register zu 
diesem Port liegt. Es gibt zwar Abhängigkeiten, so dass man aus der 
Kentnis der Adresslage des einen die Adresslage aller anderen bestimmen 
kann, aber das ist leider nicht durchgängig. Auch wenn es bei 99% alle 
AVR Prozessoren bei allen Ports so ist, eine Ausnahme genügt, die das 
SChema dann zu Fall bringt.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Was mir nicht klar ist, was in den
> einzelnen Variablen abgelegt wird.

Das sind keine Variablen

von Stefan (Gast)


Lesenswert?

Vielen Dank für die rasche Hilfe.

Habe ich richtig verstanden das im DDRB nur deklariert wird ob der 
jeweilige Pin ein Ein- oder Ausgang ist.

Denn dann wäre mir wieder nicht klar warum man es hier definiert denn 
das wäre für das Entprellen ja nicht notwendig

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Vielen Dank für die rasche Hilfe.
>
> Habe ich richtig verstanden das im DDRB nur deklariert wird ob der
> jeweilige Pin ein Ein- oder Ausgang ist.

Ich empfehle dir DRINGEND, mit deinen Studien dort anzufangen, wo alle
angehenden Programmierer anfangen:

mit dem ein-/ausschalten einer LED. Dort lernst du bereits die 
zusammenhänge zwischen den 3 Registern.

> Denn dann wäre mir wieder nicht klar warum man es hier definiert denn
> das wäre für das Entprellen ja nicht notwendig

Weil irgendwer die Eingänge auf Eingang schalten muss, bzw. die Pullups 
aktivieren muss. Die dazu notwendigen INformationen (welches DDR 
Register ist zuständig, welches Port Register ist zuständig) will man 
aber programmiertaktisch nicht quer über das ganze Programm verstreut 
haben, sondern an einer Stelle gesammelt haben. Nämlich genau dort, wo 
man alle Informationen über die Tasten gesammelt beisammen hat.
Ist doch bei dir zu Hause auch nicht anders. Du verstreust ja deine 
Socken auch nicht quer durch die Wohnung, sondern 'sammelst' sie gezielt 
an einer einzigen Stelle. Damit du welche findest, wenn du welche 
brauchst.

Entprellen und die Kentniss, welche Eingänge an welchem Port eigentlich 
zu entprellen sind, gehören nun mal zusammen. Ohne Eingang macht ein 
Entprellen keinen Sinn. Zu dieser Information gehört aber auch das 
Register, mit dem ein Pin erst einmal auf Eingang geschaltet wird.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Stefan schrieb:
> Was mir nicht klar ist, was in den
> einzelnen Variablen abgelegt wird.

Das sind keine Variablen, sondern Textersetzungen.
Diese erfolgen, sobald im nachfolgenden Quelltext der linke Ausdruck 
steht.

Damit das einen Sinn ergibt, müssen alle rechten Ausdrücke dem Compiler 
bereits bekannt sein.
Bewährte Praxis ist, daß sie es schon zum Zeitpunkt des #define sind. 
Ausreichend ist aber, spätestens zu Zeitpunkt des Aufrufs.

von Stefan (Gast)


Lesenswert?

Natürlich das ist mir klar. LED´s ein und ausgeschalten habe ich schon 
bis zum Erbrechen :-). Habe einige Tutorials durchgearbeitet.

In diesen schrieb man halt zu beginn eines Programms in das DDR (z.B. 
DDRB) für alle PINS ob diese Ein- oder Ausgang sind.

Im weiteren Programm habe ich das DDR dann nicht mehr gebraucht.

Aber im Beispielcode von Herrn Danegger wird ja nirgends deklarierd ob 
es ein Ein- oder Ausgang ist.

Es steht ja lediglich da

#define KEY_DDR         DDRB

sprich welches Register es ist aber nicht welcher PIN 1 oder 0 ist.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Natürlich das ist mir klar. LED´s ein und ausgeschalten habe ich schon
> bis zum Erbrechen :-). Habe einige Tutorials durchgearbeitet.
>
> In diesen schrieb man halt zu beginn eines Programms in das DDR (z.B.
> DDRB) für alle PINS ob diese Ein- oder Ausgang sind.

Ja.
Und jetzt siehst du dir mal den Anfang von main() im Demoprogramm an.

> Aber im Beispielcode von Herrn Danegger wird ja nirgends deklarierd ob
> es ein Ein- oder Ausgang ist.

Doch.
Genau dort, wo es hingehört. Am Anfang von main()
1
int main( void )
2
{
3
  ....
4
 
5
  // Configure debouncing routines
6
  KEY_DDR &= ~ALL_KEYS;                // configure key port for input
7
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors
8
...

setze die durch die #define Makros definierten Texte ein, und du wirst 
einiges wiederkennen.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Oh das habe ich leider übersehen. Jetzt wird mir einiges klar.

Vielen Dank für die Hilfe!

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.