Hallo,
versuche es mal einfach zu beschreiben.
hier definiere ich die zu bearbeite Adresse und dessen Bit fest.
hier das Array "BusSpiOutput[0]"
und hier die Bitnummer "FifoBit = 0"
#define WeSbh_01g() { FifoZeiger = (unsigned
int*)(void*)&BusSpiOutput[0]; FifoBit = 0; }
Die Adresse von "BusSpiOutput[0]" sowie die Bitnummer wird zwischen
gespeichert.
hiermit lese ich aus dem Array "FifoAdresse / FifoBit" die Adresse und
die Bytenummer aus.
FifoZeiger = FifoAdresse[ProzessCount];
FifoBit = FifoByte[ProzessCount];
Bis hier funktioniert alles einwandfrei.
Wenn ich nachher auf diese Speicherzelle zugreife,
so
*FifoZeiger = SET_BIT BitVariable[FifoBit];
oder
*FifoZeiger |= 1 << FifoBit;
z.B. Wenn im FifoBit der wert 0 enthalten ist, wird statt Bit 0 Bit 7
bearbeitet.
Bit
0 = 7
1 = 6
2 = 5
3 = 4
4 = 3
5 = 2
6 = 1
7 = 0
Gruß Siegfried
Hallo,
schade, habe noch keinen Zapfhahn am Rechner.
Die Zeile "SET_BIT BitVariable[0 .. 7];" nutze ich mehrmals im Programm
ohne Probleme.
Sollte es hieran liegen, Reihenfolge ?
union BusOutput
{
struct
{
unsigned Bit7:1; // Bit 7
unsigned Bit6:1; // Bit 6
unsigned Bit5:1; // Bit 5
unsigned Bit4:1; // Bit 4
unsigned Bit3:1; // Bit 3
unsigned Bit2:1; // Bit 2
unsigned Bit1:1; // Bit 1
unsigned Bit0:1; // Bit 0
};
unsigned char Byte;
};
Reihenfolge darf sich nicht ändern, da mein Programm die Byte komlett
bearbeitet.
Gruß Siegfried
> ...Anordnung von Bits in einem Bitfeld implementierungsabhängig ist.> Ein virtuelles Bier!
Was heißt da eines? Da brauche ich viele, viele Biere,
um den Schmerz nicht so deutlich zu spüren.
Leute, tut euch und der Nachwelt einen Gefallen und verwendet keine
Unions mit Bits. Der Code ist für Aussenstehende absolut unerklärlich.
Und ob jeder Compiler das so gut packt, wage ich zu bezweifeln.
Darüber hinaus sind Unions keine impliziten Casts für die Umwandlung
von einem Format in das Andere (z.B. Bit->Byte, Byte->Long, usw. usf.).
Eine Union wird Zielsystemabhängig implementiert.
Ihr macht den Siegfried klug und weise,
denn Bits in Unions, die sind schei..,
doch da er jetzt weiß, wie mans macht,
wird er auch nicht mehr ausgelacht.
Lothar Miller wrote:
> Leute, tut euch und der Nachwelt einen Gefallen und verwendet keine> Unions mit Bits. Der Code ist für Aussenstehende absolut unerklärlich.> Und ob jeder Compiler das so gut packt, wage ich zu bezweifeln.
So pauschal würde ich das nicht sagen.
Nahezu bei jedem Compiler den ich kenne, wird sowas für die IO Register
gemacht, um einzelne Portpins usw. ansprechen zu können.
Dies hat den Vorteil, dass man z.B.
#define LED PORTD.0
machen kann und dann später im Code
LED=1;
und
LED=0;
schreiben kann, was meiner Meinung nach den Code sehr viel besser lesbar
(und vor allem wartbar) macht, als
PORD|=(1<<LED);
und
PORD&=~(1<<LED);
Ein weiterer Vorteil davon ist, dass die Unions von den meisten
Compilern direkt in Bitoperationen übersetzt werden (falls es sowas in
der Harware gibt), während PORTD|=(1<<LED) oft so übersetzt wird, wie es
dasteht, nämlich in eine Lese, oder und Schreib Operation, was etwas
langsamer ist.
Benedikt K. wrote:
> #define LED PORTD.0
Dann bitte wenigstens PORTD.bit0 oder so.
Besonders effektiv macht das Microchip. Da steht dann nämlich sowas
ähnliches wie PortDbits.PortDbit0. Wenn man bei solchen Definitionen
global die Modulkonfiguration einstellen will, wie in
#define LED_PORT D
#define LED_E_BIT 4
und dies mit entsprechenden Präprozessor-Makros wie
PORTBIT(LED_PORT,LED_E) dann in PORTDbits.PORTDbit4 unwandeln will, dann
lernt man ziemlich viel über die Vor- und vor allen die Nachteile der
Arbeitsweise des C-Präprozessors.
> Nahezu bei jedem Compiler den ich kenne, wird sowas für die IO Register> gemacht, um einzelne Portpins usw. ansprechen zu können.
Richtig, aber genau dieser Teil eines Programms (IO) ist sowieso am
schlechtesten zu portieren. Diese Stelle ist Hardware- und
Compilerabhängig.
Denn der eine Prozessor hat einen PORTA, beim anderen ist das Port0 usw.
Zudem heißt es beim einen Compiler PORT_A, beim anderen PORTA...
D.h. genau an dieser Stelle muss ich sowieso was tun.
Wo es mich dann vollkommen unerwartet aus der Kurve wirft, ist wenn im
'normalen' Programmablauf Datenkonvertierungen über Unions gemacht
werden.
Hallo,
habe festgestellt, das es keine Rolle spielt, wie man dieses schreibt.
union BusOutput
{
struct
{
unsigned Bit7:1; // Bit 7
....
unsigned Bit0:1; // Bit 0
};
unsigned char Byte;
};
oder
union BusOutput
{
struct
{
unsigned Bit0:1; // Bit 0
....
unsigned Bit7:1; // Bit 7
};
unsigned char Byte;
};
Der Compiler erkennt die erste Zeile als Bit 0 und die achte als Bit 7.
Übernehme wegen der besseren Übersicht das zweite Beispiel.
Hier kann ich die von Benedikt K. geschriebene Zeilen begrüßen.
Dies hat den Vorteil, dass man z.B.
#define LED PORTD.0
machen kann und dann später im Code
LED=1;
und
LED=0;
damit "#define WeSbh_01g() { FifoZeiger = (unsigned
int*)(void*)&BusSpiOutput[0]; FifoBit = 0; }" habe ich mich einige Zeit
beschäftigt, um den Ein- oder Ausgang Pin im Klartext ansprechen zu
können.
@Lothar Miller
nicht für ungut. Wie soll ich mit "PORD|=(1<<LED);" die übersicht über
in der ersten Ausbaustufe mit 320 Ein- oder Ausgang PIN behalten.
Gruß Siegfried
Lothar Miller wrote:
> Richtig, aber genau dieser Teil eines Programms (IO) ist sowieso am> schlechtesten zu portieren. Diese Stelle ist Hardware- _und_> Compilerabhängig.
Gut, dann sind wir einer Meinung. Ich habe mir nämlich für den AVR auch
solche Bitmakros für die Pins gebaut, denn nahezu jeder andere Compiler
hat das schon integriert und da ist es etwas nervig beim Portieren, wenn
man es ausgerechnet beim AVR anders machen muss.
Siegfried Saueressig wrote:
> Der Compiler erkennt die erste Zeile als Bit 0 und die achte als Bit 7.> Übernehme wegen der besseren Übersicht das zweite Beispiel.
Oh mann, der Compiler erkennt gar nichts. Nur werden Bitfelder, je nach
Endianess, entweder in die eine Richtung, oder in die andere abgebildet.
> @Lothar Miller> nicht für ungut. Wie soll ich mit "PORD|=(1<<LED);" die übersicht über> in der ersten Ausbaustufe mit 320 Ein- oder Ausgang PIN behalten.
Wo ist das Problem? Es ist auf jeden Fall "sauberer" (im Sinne von mehr
standardkonform) Code.
> Wie soll ich mit "PORD|=(1<<LED);" die übersicht über> in der ersten Ausbaustufe mit 320 Ein- oder Ausgang PIN behalten.
Meinst Du allen Ernstes, daß das übersichtlicher wird, wenn Du den
Dingern 320 verschiedene Namen gibst?