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
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.
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.)
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.
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.
Michael A. schrieb:> Was hält dich davon ab, dir entsprechende Makros zu definierten
he, das war mein Vorschlag :-)
Muttu auch bis "andererseits" lesen!
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
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. :-(
>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...
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. ;-)