Hallo, Habe folgendes Array angelegt. unsigned int *Zeiger; union { 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; } BusTransfer volatile BusSpiOutput[MaxBusSpiInOut]; nun möchte ich mit einem Zeiger auf das Array zugreifen. Zeiger = BusSpiOutput; oder Zeiger = BusSpiOutput[]; oder Zeiger = BusSpiOutput[0]; leider funktioniert dieses nicht. Gruß Siegfried
Siegfried Saueressig wrote: > Hallo, > funktioniert leider nicht. > Gruß Siegfried Tolle Fehlerbeschreibung. Fast so gut wie die Beschreibung des Problems.
Hallo, Zeiger = BusSpiOutput; -> Error [1131] type mismatch in assignment Zeiger = BusSpiOutput[]; -> Error: syntax error Zeiger = BusSpiOutput[8]; -> Error [1131] type mismatch in assignment Gruß Siegfried
Versuch mal das hier:
1 | union BUS |
2 | {
|
3 | struct
|
4 | {
|
5 | unsigned Bit7:1; // Bit 7 |
6 | unsigned Bit6:1; // Bit 6 |
7 | unsigned Bit5:1; // Bit 5 |
8 | unsigned Bit4:1; // Bit 4 |
9 | unsigned Bit3:1; // Bit 3 |
10 | unsigned Bit2:1; // Bit 2 |
11 | unsigned Bit1:1; // Bit 1 |
12 | unsigned Bit0:1; // Bit 0 |
13 | };
|
14 | unsigned char Byte; |
15 | };
|
16 | |
17 | |
18 | volatile union BUS BusSpiOutput[MaxBusSpiInOut]; |
19 | |
20 | union BUS *Zeiger; |
21 | |
22 | Zeiger = BusSpiOutput; |
Du solltest versuchen, nicht zu viele Deklarationen und Definitionen in einem Rutsch zu erledigen. Obiges deklariert zunächst mal den Typen union BUS, dann ein Array aus Elementen dieses Typs (als volatile deklariert, weil Du's anscheinend brauchst) und dann einen Pointer auf diesen Typ. Und dann wird dem Pointer die Anfangsadresse des Arrays zugewiesen. Was genau bezweckst Du hiermit:
1 | union
|
2 | {
|
3 | //...
|
4 | } BusTransfer volatile BusSpiOutput[MaxBusSpiInOut]; |
Ist "BusTransfer" eine compilerspezifische Erweiterung? Oder wolltest Du den Union-Typ so nennen? (analog zum von mir eingeführten Typ union BUS )
Machs doch so, das geht immer ;-)
1 | Zeiger = (unsigned int*)(void*)&BusSpiOutput[0]; |
Oder gib dem Zeiger den richtigen Typ:
1 | union BusTransfer |
2 | {
|
3 | struct
|
4 | {
|
5 | unsigned Bit7:1; // Bit 7 |
6 | unsigned Bit6:1; // Bit 6 |
7 | unsigned Bit5:1; // Bit 5 |
8 | unsigned Bit4:1; // Bit 4 |
9 | unsigned Bit3:1; // Bit 3 |
10 | unsigned Bit2:1; // Bit 2 |
11 | unsigned Bit1:1; // Bit 1 |
12 | unsigned Bit0:1; // Bit 0 |
13 | };
|
14 | unsigned char Byte; |
15 | } ; |
16 | |
17 | BusTransfer BusSpiOutput[4]; |
18 | BusTransfer *Zeiger; |
19 | |
20 | Zeiger = BusSpiOutput; |
21 | // oder
|
22 | Zeiger = &BusSpiOutput[0]; |
EDIT: schade, Zweiter...
Siegfried Saueressig wrote: > Hallo, > > Habe folgendes Array angelegt. > > unsigned int *Zeiger; > > union > { > 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 > }; --------------- Komponentenname fehlt ------ > unsigned char Byte; > } BusTransfer volatile BusSpiOutput[MaxBusSpiInOut]; > > nun möchte ich mit einem Zeiger auf das Array zugreifen. > > Zeiger = BusSpiOutput; > oder > Zeiger = BusSpiOutput[]; > oder > Zeiger = BusSpiOutput[0]; > > leider funktioniert dieses nicht. > > Gruß Siegfried 1)In der union BusTransfer ist nur eine Komponente benannt. 2)Ein Zeiger auf das Array BusSpiOutput muss vom Typ BusTransfer sein, zB BusSpiOutput *BusTransferzgr. 3) Die Zuweisung von BusSpiOutput an Zeiger funktioniert nicht, da *Zeiger den Typ int hat, s.o. mfg
Hallo, guten morgen, mußte gestern kurzfristig abbrechen. Vorab vielen Dank für alle Informationen. ->"BusTransfer" eine compilerspezifische Erweiterung<- ist eine von mir frei gewählte Bezeichnung. Dieses ergibt sich aus #ifndef BusTransfer #define BusTransfer extern #endif ->volatile<- habe ich genutzt, da in einem anderem Beitrag dieses mir geraten wurde. Möchte mal kurz mein Programm beschreiben. BusSpiOutput[..] ist der Buffer(Master) für die über SPI verbunde Slave Board Jedes Slave Board hat eine Kapazität von 4 Byte / 32 Bits. Um im Proramm die Übersicht zu behalten habe ich in einer *.h diesen Code angelegt. union { struct { unsigned Bit7:1; // Bit 7 ....... unsigned Bit0:1; // Bit 0 }; unsigned char Byte; } BusTransfer volatile BusSpiOutput[MaxBusSpiInOut]; in einer weiteren *.h habe ich diesen Code angelegt #define Lampe_7 BusSpiOutput[0].Bit7 #define Lampe_0 BusSpiOutput[0].Bit0 In der *.c ist dann folgendes. Lampe_7 = 1; Lampe_1 = 1; Nach meiner Sicht habe ich somit mehr Kontrolle im Programm, denn ich brauche nicht immer zu überlegen, an welchem Bit und Byte Lampe_1 "angeschlossen ist. Soweit funktioniert es prima. Nachträglich habe ich folgendes eingefügt, um an die Adresse zu gelangen, unter der die Variable "BusSpiOutput[..]" steht. Leider waren meine Anläufe erfolglos. Den Zeiger benötige ich, um meine Befehle in ein separaten Speicher "Stabel" abzulegen. Möchte damit erreichen, das Lampe_1 30 sek. eingeschaltet ist, danach ausschaltet und erst dann Lampe_7 für 20 sek. eingeschaltet wird. Mit einer delay schleife kann ich das nicht machen (hoffe das ich es richtig darstelle) der PIC in der Schleife sich drehen würde, bis die Zeit abgelaufen ist, und somit andere Programmteile nicht bearbeitet würden. Es fehlt mir noch einen Gedanken, wie ich genau definiere, das "Lampe_7" an "BusSpiOutput[0].Bit7" ist. Der Zeiger Liefert mir nur die erste Adresse des Array (BusSpiOutput) zurück. Werde jetzt mal die Beispiele einsetzen, und sehen wie weit ich komme. Für weitere Info's bin ich sehr aufgeschlossen. Gruß Siegfried
> Es fehlt mir noch einen Gedanken, wie ich genau definiere, das "Lampe_7" > an "BusSpiOutput[0].Bit7" ist. > Der Zeiger Liefert mir nur die erste Adresse des Array (BusSpiOutput) > zurück. Es gibt keine Möglichkeit, Elemente eines Bitfeldes über Pointer anzusprechen. Es gibt nur Pointer auf das gesamte Bitfeld, aber nicht welche auf Elemente des Bitfeldes. Wenn man sich aber mal 'ne halbe Stunde Zeit nimmt, und sich mit logischen Operationen und Bitmasken beschäftigt, stellt man fest, daß man für die einfache Abbildung einzelner Bits auch gar kein Bitfeld benötigt. Wenn Du Dir eh' nur ein Element des Bitfeldes merken möchtest, reicht es auch, dessen Nummer aufzuheben. Die kann dann mit dem bei AVR-C-Programmieren ubiquitären Shift-Operatoren verwendet werden. Bei allen Varianten wird bei 0 angefangen zu zählen, die 8 Bits eines Bytes werden von 0 bis 7 und nicht von 1 bis 8 numeriert. Bit setzen: Port |= 1 << Bitnummer; Bit löschen: Port &= ~(1 << Bitnummer); Bit abfragen: Port & (1 << Bitnummer) Hier bool'sche Auswertung anwenden, also auf Null bzw. nicht Null testen. Also: if (Port & (1 << Bitnummer)) { // bit ist gesetzt } else { // bit ist nicht gesetzt } oder if (Port & (1 << Bitnummer) == 0) { // bit ist nicht gesetzt } oder if (!(Port & (1 << Bitnummer)) { // bit ist nicht gesetzt } Aber nicht if (Port & (1 << Bitnummer) == 1) { // bit ist gesetzt } Das schlägt fehl, wenn Bitnummer nicht 0 ist. Wenn man das verinnerlicht hat, braucht man keine Bitfelder mehr, um auf einzelne Bits zuzugreifen. Und schon gar keine unions aus Bitfeldern und anderen Typen.
Hallo, @Rufus t. Firefly (rufus) (Moderator) Danke für die schnelle Antwort. Ein Schritt bin ich weiter. Habe deine Code eingesetzt. Soweit ist alles in Ordnung. Habe bewust diesen Weg mit den Bit/Byte gewählt (wenn auch erfahrene Programmier dieses anderst lösen würden) um ein Bit unter einem Namen ansprechen können. Derzeitige Ausbaustufe ist 1 Master Board und 10 Slave Board. Das wären bei allen Slave Boards 320 Bit's. Die Bit's werden einzeln abgearbeitet. Ich denke, das ich hier mit mehr überblick habe. Es ist schon ein großer Vorteil für mich, das ich zumindest die Adresse des ersten Byte's bekomme. Mit den Bit's Bezeichnungen muß ich noch überlegen, wie ich das bewältige. Gruß Siegfried
Nun, wenn Du mit Bitnummern arbeitest, kannst Du die natürlich auch unter einem Namen ansprechen, da gäbe es verschiedene Möglichkeiten. Einerseits könntest Du die Bitnummern als Präprozessor-#define mit Namen versehen #define LAMPE_GRUEN 1 #define LAMPE_GELB 2 #define LAMPE_ROT 3 und diese Namen anstelle der Nummern verwenden: Port |= 1 << LAMPE_GRUEN; Du kannst natürlich auch den Bit_wert_ definieren #define LAMPE_GRUEN (1 << 0) #define LAMPE_GELB (1 << 1) #define LAMPE_ROT (1 << 2) und den dann verwenden: Port |= LAMPE_GRUEN;
Hallo, @Rufus t. Firefly (rufus) (Moderator) ein guter Ansatz für mich. Du hast mir viel Arbeit abgenommen. eine bescheidene Frage. Besteht die Möglichkeit, auch die Byte Nummer einzubauen? #define LAMPE_GRUEN (1 << 0) #define LAMPE_GELB (1 << 1) #define LAMPE_ROT (1 << 2) Gruß Siegfried
Hallo, @Rufus t. Firefly (rufus) (Moderator) @Lothar Miller (lkmiller) habe jetzt folgendes gemacht. *.h #ifndef List #define List extern #endif List unsigned int *FifoZeiger; List unsigned int FifoBit; #define LAMPE_XY_01() { FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[3]; FifoBit=1; } #define LAMPE_XY_02() { FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[3]; FifoBit=2; } #define LAMPE_XY_03() { FifoZeiger = (unsigned int*)(void*)&BusSpiOutput[3]; FifoBit=3; } *.c LAMPE_XY_01(); FifoAdresse[FifoCount] = FifoZeiger; FifoByte[FifoCount++] = FifoBit; .. LAMPE_XY_03(); FifoAdresse[FifoCount] = FifoZeiger; FifoByte[FifoCount++] = FifoBit; hoffe, das ich das mein Ziel erreicht habe. Jetzt kann ich in der "define" festlegen, an welcher Adresse ich das Bit X bearbeiten will. Ich möchte/muß die "Befehle" zwischenspeichern und diese über einen Timer-Interrupt schrittweise abarbeiten. Gruß Siegfried
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.