mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zeiger auf Array


Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Pete K. (pete77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bustransfer *Zeiger;

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
funktioniert leider nicht.
Gruß Siegfried

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig wrote:
> Hallo,
> funktioniert leider nicht.
> Gruß Siegfried

Tolle Fehlerbeschreibung. Fast so gut wie die Beschreibung des Problems.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal das hier:

union BUS
{
  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;
};


volatile union BUS BusSpiOutput[MaxBusSpiInOut];

union BUS *Zeiger;

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:
union
{
//...
} 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 )

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Machs doch so, das geht immer   ;-)
Zeiger = (unsigned int*)(void*)&BusSpiOutput[0];

Oder gib dem Zeiger den richtigen Typ:
union BusTransfer
{
  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 BusSpiOutput[4];
BusTransfer *Zeiger;

Zeiger = BusSpiOutput;
// oder
Zeiger = &BusSpiOutput[0];



EDIT: schade, Zweiter...

Autor: G. O. (aminox86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.