Forum: Compiler & IDEs Was bedeutet eigentlich das "PINA0"?


von kai (Gast)


Lesenswert?

Hallo,
was bedeutet eigentlich das "PINA0" beim Bit-Shiften in Ausdrücken wie
Code
1
if (( PINA & (1 << PINA0) == 0) {
2
// wird ausgeführt, wenn PinA0 auf LO gezogen wird
3
}
4
Code
?

Sind das einfach nur die jeweiligen Potenzen von 2, also
PINA0 = 2^0 = 1
PINA1 = 2^1 = 2
PINA2 = 2^2 = 4
etc.


Könnte man es dann auch einfach so schreiben?
Code
1
if (( PINA & (1 << 1) == 0) {  // "PINA0" durch "1" ersetzt
2
// wird ausgeführt, wenn PinA0 auf LO gezogen wird
3
}
4
Code



(Die Frage gilt natürlich analog auch für Ausdrücke wie PINB0, PIND7 
usw.)

von Norbert (Gast)


Lesenswert?

Es ist die Anzahl die eine ›1‹ geschoben werden muss damit sie an der 
richtigen Position ist. Also im einfachsten Fall entspricht PINA0…PINA7 
== 0…7

Sehr vereinfacht, bestimmt werden gleich eine Menge zorniger Kommentare 
auf Sonderfälle hinweisen… ;-)

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

kai schrieb:
> Könnte man es dann auch einfach so schreiben?
> Code
1
> if (( PINA & (1 << 1) == 0) {  // "PINA0" durch "1" ersetzt
2
> // wird ausgeführt, wenn PinA0 auf LO gezogen wird
3
> }
4
> Code

Nein, denn PINA0 ist mit großer Wahrscheinlichkeit 0 nicht 1. Kann aber 
auch was völlig anderes sein (sehr unwahrscheinlich).

So etwas wie
1
if (( PINA & (1 << PINA0) == 0) {

nennt man ein Idiom. https://en.wikipedia.org/wiki/Programming_idiom 
Etwas was man immer so hin schreibt - damit man eben nicht Fehler macht 
wie mal 0 und 1 verwechseln. Dinge die man so schreibt weil man sie so 
schreibt, weil "jeder" sie so schreibt und Jahrzehnte Erfahrung gezeigt 
haben dass es so am vernünftigsten ist. Ausnahmen gibt es bei 
Bullshit-Hipster-Programmiersprachen wo Leute sich unbedingt im 
persönlichen Ausdruckstanz üben möchten.

Ich würde es noch etwas anders schreiben
1
if(!(PINA & (1 << PINA0)) {
Das ist dann für Leute die wissen wie C funktioniert.

: Bearbeitet durch User
von Helmut -. (dc3yc)


Lesenswert?

PINA0 ist ein Literal und beschreibt die Wertigkeit des Bits im 
Portbyte. Es dient dazu, eine bequeme Maskierung des Bits zu erzielen, 
ohne wissen zu müssen, an welcher Stelle im Byte das Bit sitzt.

von Georg M. (g_m)


Angehängte Dateien:

Lesenswert?

Verständlich.

Beitrag #6978607 wurde vom Autor gelöscht.
von kai (Gast)


Lesenswert?

Also es stellt oft den jeweiligen Exponenten von 2 dar:

PINA0 = 0  -> 2^0
PINA1 = 1  -> 2^1
PINA2 = 2  -> 2^2
etc.



Georg M. schrieb:
> Verständlich.

Ja, danke!

von Oliver S. (oliverso)


Lesenswert?

kai schrieb:
> Also es stellt oft den jeweiligen Exponenten von 2 dar:

Da es sich hier (sehr vermutlich) um eine Frage zur avrlibc handelt, 
stellt das weder oft noch überhaupt irgendwelche Exponenten da.

IN dem zum Prozessor zugehörigen include-File, welches über #include 
<avr/io.h> letzedlich inkludiert wird, stehen die Definitionen, und die 
sehen so aus:
1
/* PINA */
2
#define PINA7   7
3
#define PINA6   6
4
#define PINA5   5
5
#define PINA4   4
6
#define PINA3   3
7
#define PINA2   2
8
#define PINA1   1
9
#define PINA0   0

Oliver

von Rolf M. (rmagnus)


Lesenswert?

Helmut -. schrieb:
> PINA0 ist ein Literal und beschreibt die Wertigkeit des Bits im
> Portbyte.

PINA0 ist ein Makro, dessen Nutzung der Präprozessor durch ein Literal 
ersetzt.

> Es dient dazu, eine bequeme Maskierung des Bits zu erzielen,
> ohne wissen zu müssen, an welcher Stelle im Byte das Bit sitzt.

Wobei das für die PIN-Bits jetzt nicht so viel bringt wie für die Bits 
in anderen I/O-Registern.

Oliver S. schrieb:
> kai schrieb:
>> Also es stellt oft den jeweiligen Exponenten von 2 dar:
>
> Da es sich hier (sehr vermutlich) um eine Frage zur avrlibc handelt,
> stellt das weder oft noch überhaupt irgendwelche Exponenten da.

Es stellt den Exponenten der Wertigkeit des Bits da_r_, gerade beim AVR. 
Der Wert des Bits für Pin A4 ist z.B. 2 hoch 4, und die 4, also der 
Exponent ist das, was in dem Makro steht.

> #define PINA4   4

: Bearbeitet durch User
von Anfänger (Gast)


Lesenswert?

Hallo

Als ein immer noch Anfänger darf ich sagen:
Fluch und Segen gleichzeitig.
- Fluch weil man eben als Anfänger verwirrt wird wenn die "Anleitung" 
(Tutorial, Schulung, Unterlagen,...) schlecht ist und nicht bei "Null" 
angefangen wird.
Das kommt leider oft vor wenn die "Anleitung" von einen langjährigen 
Programmierer mit viel Praxiserfahrung stammt, der aber seine eigenen 
Anfänge vergessen hat und didaktisch nicht allzuviel drauf hat.
- Segen weil es dann in der Praxis einfacher ist und man nicht wegen 
"billigen" Kleinigkeiten Fehler macht -wenn man es denn dann beherrscht 
und die eigentlich einfache Idee dahinter verstanden hat was "dank" in 
der Programmierwelt grundsätzlich maximal abgehobenen Sprache (Idiom... 
geht es noch und das ist ein Begriff den man eventuell noch kennt)und 
denn irgendwie "komischen" denken insgesamt über lange Zeit sehr 
schwierig ist - bis es mehr oder weniger auf einmal "Klick" macht.

Schade das die teilweise sehr guten Erklärungen die man hier in Forum 
lesen kann (dafür braucht es aber auch die entsprechenden Fragen) man so 
gut wie nie in Lehrbüchern, Onlinekursen usw. lesen kann...

Anfänger

von gfl (Gast)


Lesenswert?

Hallo

man sollte genauer erklären was hierbei
1
if (( PINA & (1 << PINA0) == 0) {
2
3
// wird ausgeführt, wenn PinA0 auf LO gezogen wird
4
5
}
passiert:

(1 << PINA0) erzeugt eine sogenannte Maske. Man könnte auch direkt 
0b00000001 hinschreiben. Diese Maske ist keine Zahl im herkömmlichen 
Sinn sonder ein bitweiser Operator und nicht aus einer Potenzierung 
erzeugt. Das hier eine Verschiebung stattfindet, die manchmal auch zum 
Potenzieren benutzt wird, ist eine rein optische Übereinstimmung und in 
diesem Zusammenhang völlig unnötig erwähnt und bringt den Anfänger auf 
eine vollkommen falsche Spur.

Würden die Pin[0-7] auf zwei Byte verteilt, dann würden die Makros z.B. 
wie folgt lauten
1
#define PINA7   15
2
#define PINA6   13
3
#define PINA5   11
4
#define PINA4   9
5
#define PINA3   7
6
#define PINA2   5
7
#define PINA1   3
8
#define PINA0   1
und dazwischen die DDRA-bits und schon ist es mit den Potenzen vorbei.

(1 << PINA0) statt 0b00000001 zu schreiben, hat nur den Vorteil, dass 
man sofort erkennt, um was es geht: PINA0 in Register PINA wird 
abgefragt, ob es HIGH ist. Das Ergebnis wird dann mit 0 verglichen.

Ich vermute stark, dass es einem Atmel-Ingenieur irgendwann zu doof 
wurde, die ganzen bits hinzuschreiben und aus Faulheit diese Makros 
schrieb. Die anderen fanden das zwar ganz nett, aber wirklich nötig ...? 
Und heute sind es wahrscheinlich die meistgebrauchten Makros in der 
Atmel-Welt.

Rolf M. schrieb:
> Es stellt den Exponenten der Wertigkeit des Bits da_r_, gerade beim AVR.

Es gibt keine verschiedenen Wertigkeiten zwischen den Pins, alle sind 
gleichviel Wert und haben nur vom Programm abhängig verschiedene 
Aufgaben.

Grüße

von Rolf M. (rmagnus)


Lesenswert?

gfl schrieb:
> (1 << PINA0) erzeugt eine sogenannte Maske. Man könnte auch direkt
> 0b00000001 hinschreiben. Diese Maske ist keine Zahl im herkömmlichen
> Sinn sonder ein bitweiser Operator und nicht aus einer Potenzierung
> erzeugt.

Der erzeugte Wert ist gleich dem einer Potenzierung. 1 << 4 ist das 
gleiche wie 2⁴. Dementsprechend könnte man stattdessen auch 16 
schreiben, mit der gleichen Auswirkung.

> Würden die Pin[0-7] auf zwei Byte verteilt, dann würden die Makros z.B.
> wie folgt lauten
> #define PINA7   15
> #define PINA6   13
> #define PINA5   11
> #define PINA4   9
> #define PINA3   7
> #define PINA2   5
> #define PINA1   3
> #define PINA0   1
> und dazwischen die DDRA-bits und schon ist es mit den Potenzen vorbei.

Und du sprichst davon, den Fragesteller nicht zu verwirren?
Abgesehen davon hat das mit den Potenzen nichts zu tun. 1 << 9 ist auch 
das selbe wie 2⁹.

> Rolf M. schrieb:
>> Es stellt den Exponenten der Wertigkeit des Bits da_r_, gerade beim AVR.
>
> Es gibt keine verschiedenen Wertigkeiten zwischen den Pins, alle sind
> gleichviel Wert und haben nur vom Programm abhängig verschiedene
> Aufgaben.

Bitte genauer lesen. Ich schrieb Bits, nicht Pins. Jedes Bit in dem 
Register hat natürlich eine Wertigkeit.

von Wolfgang (Gast)


Lesenswert?

kai schrieb:
> was bedeutet eigentlich das "PINA0" beim Bit-Shiften in Ausdrücken wie
> Codeif (( PINA & (1 << PINA0) == 0) {
> // wird ausgeführt, wenn PinA0 auf LO gezogen wird
> }
> Code
> ?
>
> Sind das einfach nur die jeweiligen Potenzen von 2, also
> PINA0 = 2^0 = 1
> PINA1 = 2^1 = 2
> PINA2 = 2^2 = 4
> etc.

Bestimmt nicht. Die Konstanten müssen wie folgt festgelegt sein:
PINA0 = 0
PINA1 = 1
PINA2 = 2
...
Sonst funktioniert die Abfrage nicht.

von W.S. (Gast)


Lesenswert?

Wolfgang schrieb:
> Sonst funktioniert die Abfrage nicht.

Vielleicht ist es hier erstmal hilfreicher, sich darüber klar zu werden, 
daß solche Bezeichner wie PINA0 einfach nur Namen sind. Man könnte das 
auch Ottokar nennen. Dem Compiler ist das egal, solange die zugehörige 
Definition stimmt.

Generell ist es für einen Menschen hilfreicher, mit Namen zu hantieren 
anstelle mit Anzahl von Verschiebungen, um eine Maske zu erzeugen, mit 
der man ein Bit aus einem Byte, Word oder sonstws isolieren kann. Aber 
die Kehrseite ist oftmals, daß die entsprechenden Definitionen bzw. 
Umsetzungen wie z.B.
#define Ottokar 3
oft in einer anderen Datei stehen. Um eine funktionierende Firmware zu 
erzeugen, muß man sich dann drauf verlassen, daß so eine Definition dann 
genau so wie gedacht dort steht. Das schafft eine Abhängigkeit, die auch 
ein Fehlergrund sein kann: Wenn die betreffende Datei eben NICHT zum 
aktuellen Projekt gehört, sondern zu dem Zeug, was man bei irgendeiner 
Toolchain eben so dabei hat, dann kann dort auch mal sowas stehen, wenn 
sich die Toolchains verschiedener Leute voneinander unterscheiden:
#define Ottokar (1<<3)

Was lehrt uns das? Nun, man sollte die Abhängigkeiten seines Projektes 
von anderen Dateien, die nicht zum aktuellen Projekt gehören, nicht 
unnötig groß machen. Also nicht ohne triftigen Grund Referenzen zwischen 
den Dateien des Projektes und anderen Dateien erzeugen. Ich halte da ST 
für ein ausnehmend negatives Beispiel. Dort werden in den 
Chip-Definitionen ganze Urwälder von Namen erzeugt und die 
entsprechenden .h Dateien sind dann riesengroß und recht unübersichtlich 
und gespickt mit Bezeichnern, die weitere Abhängigkeiten zu noch anderen 
Dateien erzeugen. Eben ein Urwald.

W.S.

von Zeit ist RUM! (Gast)


Lesenswert?

Define PINA COLADA

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.