Forum: Compiler & IDEs Warum ist PC7 == 7 und nicht (1 << 7) ?


von Tom K. (ez81)


Lesenswert?

Hallo zusammen,

gibt es irgendeinen Grund, warum man beim AVR-GCC die pin-Makros so 
definiert hat, wie sie sind und das shiften nicht gleich in das Makro 
gesteckt hat? Ich habe in meiner Bastelkarrriere wahrscheinlich hunderte 
Tastendrücke für Dinge wie
1
PORTC |= (1 << PC2) | (1 << PC5) | (1 << PC7);
verschwendet, statt einfach
1
PORTC |= PC2 | PC5 | PC7;
zu schreiben, die Bedeutung "7" für PC7 habe ich allerdings noch nie 
gebraucht. Beim mpsgcc scheint man das anders (für mich sinnvoller) 
gelöst zu haben, aber wer immer das beim AVR so entschieden hat, war 
sicher nicht so dämlich, wie es mir gerade vorkommt ;) .

Grüße,
Tom

von (prx) A. K. (prx)


Lesenswert?

Weil es damit wie bei der Zahnpasta ist. Man kriegt sie leichter aus der 
Tube raus als hinterher wieder zurück.

Manchmal wird die Bitnummer benötigt. So beispielsweise in Assembler bei 
den Befehlen CBI/SBI. Bitnummer zu Maske ist einfach (Shift), Maske zu 
Bitnummer nicht (Logarithmus). Es gibt Controller wie STM32 bei denen ST 
die Bits als Maske definiert hat und man folglich entsprechend Probleme 
hat, wenn man die Bitnummer benötigt.

von Klaus W. (mfgkw)


Lesenswert?

Das ist soweit richtig.

Da das aber bei AVR eher recht selten ist, frage ich ich mich einerseits 
warum Atmel nicht einfach beides anbietet.
Auf 8 Makros mehr, die zu den Bitnummern noch die Masken liefern, käme 
es auch nicht mehr drauf an. Vielleicht sogar nochmal 8 für die 
invertierten Masken.

Andererseits weiß ich nicht, warum immer wieder Leute darüber 
lamentieren. Wer (so wie ich) die dauernde Shifterei nervig findet, kann 
sich die Makros auch selbst machen, das sollte man noch hinbekommen.
(Wobei ich für meinen Teil sowieso lieber Bitfelder definiere, aber das 
ist wieder eine andere Geschichte.)

von (prx) A. K. (prx)


Lesenswert?

Klaus Wachtler schrieb:

> warum Atmel nicht einfach beides anbietet.

Das wäre eine Ansatz. Wobei sich das natürlich nicht auf die PORTx Bits 
beschränkt, sondern sämtliche Steuerbits in sämtlichen Steuerregistern 
ebenso betroffen sind.

Ich habe das in eigenen Definitionen für STM32 so ähnlich gemacht. 
Bitnummern wo es einzelne Bits sind - wegen Bitbanding - und syntaktisch 
unterscheidbare Masken, wo mehrere Bits zu einem Wert zusammengefasst 
sind. ST hat dort die hirnlose Meisterleistung vollbracht, für jedes 
einzelne Bit solcher Mehrbitstrukturen eine Maske zu definieren, ohne 
damit codierten Werten wie 0b0110 einen beschreibenden Namen wie 
XY_PRESCALE_BY_4 zu geben.

> Andererseits weiß ich nicht, warum immer wieder Leute darüber
> lamentieren.

Ich auch nicht. Zumal diese Methode Ausdrücke wie
    1<<XYEN | 0<<XYIE
nahelegt, um darzustellen, dass man IE nicht setzen will. Mit Maske 
würde dann sowas Schräges wie
    XYEN | 0*XYIE
draus.

von Michael A. (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Da das aber bei AVR eher recht selten ist, frage ich ich mich einerseits
> warum Atmel nicht einfach beides anbietet.

Was hält dich davon ab, dir entsprechende Makros zu definierten, die du 
immer einbindest oder den vorhandenen Makro _BV(PC2) - zugegeben auch 
nicht kürzer - an Stelle von (1 << PC2) zu verwenden.

von Klaus W. (mfgkw)


Lesenswert?

Michael A. schrieb:
> Was hält dich davon ab, dir entsprechende Makros zu definierten

he, das war mein Vorschlag :-)

Muttu auch bis "andererseits" lesen!

von Marius W. (mw1987)


Lesenswert?

Klaus Wachtler schrieb:
> Da das aber bei AVR eher recht selten ist, frage ich ich mich einerseits
> warum Atmel nicht einfach beides anbietet.

Bei den neuen XMegas ist das so.

Dort gibt es dann zB PIN5_bp, was als 5 definiert ist. Zusätzlich dann 
auch noch PIN5_bm, was einfach (1 << 5) ist.

MfG
Marius

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Da das aber bei AVR eher recht selten ist, frage ich ich mich einerseits
> warum Atmel nicht einfach beides anbietet.

Weil da jemand nicht konsequent bis zu Ende gedacht hat vor
reichlich 10 Jahren, und derjenige vermutlich auch kein
C-Programmierer gewesen ist.  Offenbar ist diese nervende
Kleinigkeit aber auch den Leuten von IAR nicht aufgestoßen,
die man ja zuvor extra noch konsultiert hat.

Ansonsten hätte man nämlich auch die CBI- und SBI-Befehle mit
einer Bitmaske definieren können:
1
    sbi PORTB, 0x80
2
    cbi PORTB, 0x80

Dem Assembler ist der etwas aufwändige Logarithmus von der Bitmaske
zur Bitnummer durchaus zuzumuten, d. h. der hätte aus der 0x80 die
7 für den Opcode berechnen können (und sich beschweren, wenn jemand
0xff übergibt, genauso, wie er sich jetzt beschweren muss, wenn
jemand statt einer Zahl von 0 bis 7 eine 42 übergibt).

Einmal vergeigt, immer vergeigt. :-(

von Matthias L. (Gast)


Lesenswert?

>wenn jemand statt einer Zahl von 0 bis 7 eine 42 übergibt).

Warum? Dann hätte man auch mehrere Bits mit einem Befehl setzen/löschen 
können. Man würde sich das IN/AND,OR/OUT sparen.

Aber ich vermute, ein Grund, die Bitnummern anzugeben, ist der 
Speicherplatz des asm-Befehls. Die Bitnummer benötigt nur drei Bit, 
sonst wären acht fällig...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Matthias Lipinsky schrieb:
>>wenn jemand statt einer Zahl von 0 bis 7 eine 42 übergibt).
>
> Warum?

Weil es dann nicht mehr zum entsprechenden Opcode gepasst hätte.

Ich wollte ja nur einen Weg aufzeigen, wie man den Opcode so, wie
er ist, hätte mit einer leicht geänderten Mnemonik "C-freundlicher"
auch im Assembler implementieren können.

> Aber ich vermute, ein Grund, die Bitnummern anzugeben, ist der
> Speicherplatz des asm-Befehls.

Ja, natürlich.  Schließlich musste man mit den 16 Bits des Opcode
ein wenig haushalten, und alles mit (weitgehend) fester Befehls-
länge und dadurch einem einfachen und schnellen Befehlsdecoder zu
bauen, war wohl ein Designziel.  Sonst wäre ja auch nur yet another
8051 rausgekommen. ;-)

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.