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.
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
}BusTransfervolatileBusSpiOutput[MaxBusSpiInOut];
Ist "BusTransfer" eine compilerspezifische Erweiterung? Oder wolltest Du
den Union-Typ so nennen?
(analog zum von mir eingeführten Typ union BUS )
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