www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik union / struct löschen


Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Habe folgende Zeilen. (abgeleidet von einem Beispiel)

union
{
  struct
  {
    unsigned RunProg:8;           //  Run Programm
//    unsigned Run:1;           //  ???
//    unsigned Run:1;           //  ???
    unsigned ConnectService:5;  //  Connect Service
//    unsigned Run:1;           //  ???
//    unsigned Run:1;          //  ???
    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  unsigned char Byte;
} GLOBAL ProzessStatus;

In der Routine main() möchte ich die union/struct komplett lösche.
Muß ich dafür pro Bit eine Zeile schreiben z.B. 
ProzessStatus.Bit.ConnectBusSpi = 0;
oder kann man dies in einem Befehl erledigen?
Gruß Siegfried

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Siegfried,

Wie stellst du dir das denn vor?
Was willst du löschen?
Die struct/union alleine belegt ja keinen Speicher. Das ist nur eine 
Typdefinition.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Freizeitbastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Siegfried,

solange es Dir reicht, alle Bits auf 0 zu setzen tut es das spätestens 
in C++ verpönte

memset( &ProzessStatus, 0, sizeof ProzessStatus )

.

@Micha: Er hat aber einen Namen hinter die namenlose Typdefinition 
geschrieben. Dass definiert dann schon eine Variable (mal abgesehen von 
dem fehlenden "}".

Schöne Grüße

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freizeitbastler wrote:
>> @Micha: Er hat aber einen Namen hinter die namenlose Typdefinition
> geschrieben. Dass definiert dann schon eine Variable (mal abgesehen von
> dem fehlenden "}".

Hm stimmt, hab ich übersehen.
Hinzu kommt, dass Siegfried ein PIC-Programmierer ist, demzufolge C++ 
flach fällt.
Für solche Zwecke habe ich der Union immer eine SHORT-Variable 
hinzugefügt, die das ganze Byteweise zurückgibt.
Diese kann man dann sehr wohl mit =0 überschreiben.
Das ist ja der Sinn einer union, dass nur einmal Speicherplatz 
reserviert wird.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe versehentlich ein Teil des Code gelöscht.
Hier nochmals der aktuelle

union
{
  struct
  {
    unsigned RunProg:8;           //  Run Programm
//    unsigned Run:1;           //  ???
//    unsigned Run:1;           //  ???
    unsigned ConnectService:5;  //  Connect Service
//    unsigned Run:1;           //  ???
//    unsigned Run:1;          //  ???
    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  } Bit;
  unsigned char Byte;
} GLOBAL ProzessStatus;

wie schon geschrieben, der code ist von einem Beispiel abgeleidet.
Kann den "Bits" eine 1 oder 0 zuweisen und kann abfragen ob 1 oder 0.
Möchte wenn möglich in der Main alle 8 Bits gleichzeit auf 0 setzen.

Hier das Beispiel.

union
{
  struct
  {
    unsigned Timeout:1;         //flag to indicate a TMR0 timeout
    unsigned None:7;
  } Bit;
  unsigned char Byte;
} Flags;

und

  while (1)
    {
      if (Flags.Bit.Timeout == 1)
        {                                  //timeout?
          Flags.Bit.Timeout = 0;           //clear timeout indicor
          LATBbits.LATB7 = LATBbits.LATB0; //copy LED state from RB0 to 
RB7
        }
    }

oder

  if (INTCONbits.TMR0IF)
    {                                   //check for TMR0 overflow
      INTCONbits.TMR0IF = 0;            //clear interrupt flag
      Flags.Bit.Timeout = 1;            //indicate timeout
      LATBbits.LATB0 = !LATBbits.LATB0; //toggle LED on RB0
    }


Gruß Siegfried

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ProzessStatus dummy; // Variable definieren

dummy.byte = 0; // alle Bits 0
dummy.byte = 255; // alle Bits 1

Wobei die Union keinen richtigen Sinn macht. Da da "unsigned char Byte;" 
nicht alle Bits der Struct beinhaltet.

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm...
du musst einfach nur schreiben:

Flags.Byte = 0x00;

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Micha R. wrote:

> Flags.Byte = 0x00;

Das funktioniert nicht. Da Bit größer ist als Byte, werden dadurch 
nicht alle Bits auf 0 gesetzt.
(Ob dieser Größenunterschied irgendeinen Sinn macht, ist eine andere 
Frage)

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> werden dadurch nicht alle Bits auf 0 gesetzt

Das ist doch der Sinn der Sache.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Letzten Beitrag streichen :-)

Aber wie meinst du das "Da Bit größer ist als Byte" ?

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Stefan hat recht. Es wird nur dieses "ProzessStatus.Bit.RunProg" auf 0 
gesetzt.

Versuche es dann die C++ Anweisung  "memset( &ProzessStatus, 0, sizeof 
ProzessStatus );" Dieses funktioniert, aber der ASM Code ist größer als 
bei 8 Einzelzeilen.

möchte zwar keine Durcheinander von C und C++, aber wenn es nicht 
anderst geht, dann muß es sein.

ProzessStatus.Bit.RunProg = 1;
ProzessStatus.Bit.ConnectService = 1;
ProzessStatus.Bit.ConnectBusSpi = 1;
ProzessStatus.Bit.TransferError = 1;

ProzessStatus.Byte = 0;

if (ProzessStatus.Bit.RunProg == 1)
{
ProzessStatus.Bit.RunProg = 1;
}

if (ProzessStatus.Bit.ConnectBusSpi == 1)
{
ProzessStatus.Bit.ConnectBusSpi = 1;
}

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Union ProzessStatus hat 20 Bits und nur ein Byte überlägert.

MW

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:

> Aber wie meinst du das "Da Bit größer ist als Byte" ?

Der Union-Member Bit belegt mehr Speicher, als der Union-Member 
Byte. Mit "Flags.Byte = 0x00;" wird daher nur ein Teil der Union auf 
Null gesetzt.

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan Ernst wrote:
> Micha R. wrote:
>
>> Flags.Byte = 0x00;
>
> Das funktioniert nicht. Da Bit größer ist als Byte, werden dadurch
> nicht alle Bits auf 0 gesetzt.
> (Ob dieser Größenunterschied irgendeinen Sinn macht, ist eine andere
> Frage)

Wir sollten erst mal klar darüber werden, um was es hier geht.
Geht es um die Union "Flags" oder geht es um die Union "ProcessStatus"?

So wie ich das verstanden habe, hat Siegfried nur von "ProcessStatus" 
abgekupfert.!?

Bei der Union "Flags" geht das mit dem .Byte=0x00 sehr wohl.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh sorry, da habe ich doch glatt übersehen, dass sich deine Antwort auf 
etwas anderes bezog, als die Frage.

> So wie ich das verstanden habe, hat Siegfried nur von "ProcessStatus"
> abgekupfert.!?

Nein, ProcessStatus ist das Ergebnis des Abkupferns:

> wie schon geschrieben, der code ist von einem Beispiel abgeleidet.
> ...
> Hier das Beispiel.
> ...
> } Flags;

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Micha,
genau umgekehrt. Die Union "Flag" ist das Beispiel.
Meine Zeilen sind die Union "ProcessStatus". Hier habe ich gegenüber dem 
Beispiel die Namen der Bits abgeändert.
Gruß Siegfried

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der Union-Member Bit belegt mehr Speicher, als der Union-Member
> Byte. Mit "Flags.Byte = 0x00;" wird daher nur ein Teil der Union auf
> Null gesetzt.

Ja klar, das was ich oben auch schon angedeutet hatte. :-)

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig wrote:
> Hallo Micha,
> genau umgekehrt. Die Union "Flag" ist das Beispiel.
> Meine Zeilen sind die Union "ProcessStatus". Hier habe ich gegenüber dem
> Beispiel die Namen der Bits abgeändert.
> Gruß Siegfried

Dann habe ich das irgendwie überlesen. Sorry.
union
{
  struct
  {
    unsigned RunProg:8;           //  Run Programm
    unsigned ConnectService:5;  //  Connect Service
    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  }
  unsigned short Byte;
} GLOBAL ProzessStatus;

Deine Union müsste dann so aussehen, wenns funktionieren soll.
Hab ich weiter oben schon mal geschrieben.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Anzahl der Bits passt dort nicht.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wobei ich es dann aber nicht mehr unbedingt "Byte" nennen würde. ;-)
Ich würde sowieso irgendetwas größen-neutrales nehmen, wie z.B. 
"AllBits".

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So könnte es richtig sein.
union
{
  struct
  {
    unsigned RunProg:1;           //  Run Programm
    unsigned ConnectService:1;  //  Connect Service
    unsigned ConnectBusSpi:1;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  }
  unsigned short Byte;
} GLOBAL ProzessStatus;

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
spitze Leistung

in der " <<<<<<<--------- " Zeile fehlte noch das " Bit; ", da sonst ein 
syntax error kommt.

union
{
  struct
  {
    unsigned RunProg:8;           //  Run Programm
    unsigned ConnectService:5;  //  Connect Service
    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  } Bit;    <<<<<<<---------
  unsigned short Byte;
} GLOBAL ProzessStatus;

noch eine Frage. was bedeutet " :1 oder :8 " hinter dem Bit Label ?
Gruß Siegfried

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:
> So könnte es richtig sein.
>
>
union
> {
>   struct
>   {
>     unsigned RunProg:1;           //  Run Programm
>     unsigned ConnectService:1;  //  Connect Service
>     unsigned ConnectBusSpi:1;  //  Connect Bus Spi
>     unsigned TransferError:1;  //  Daten Transfer Error
>   }
>   unsigned short Byte;
> } GLOBAL ProzessStatus;

Es geht schon so:
union
{
  struct
  {
    unsigned RunProg:8;           //  Run Programm
    unsigned ConnectService:5;  //  Connect Service
    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
    unsigned TransferError:1;  //  Daten Transfer Error
  } ;
  unsigned short Byte;
} ProzessStatus;

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siegfried Saueressig wrote:
> in der " <<<<<<<--------- " Zeile fehlte noch das " Bit; ", da sonst ein
> syntax error kommt.

Das war bewusst weggelassen. Somit kannst du nämlich dann einfach 
schreiben:
ProzessStatus.TransferError = 1;

> noch eine Frage. was bedeutet " :1 oder :8 " hinter dem Bit Label ?

Das fragst du jetzt erst??? ;-)
Die Zahl gibt an, wieviele Bits für den Wert reserviert werden.

Also wenn du nur Flags repräsentieren willst, die alle nur 0/1 annehmen 
können, dann mach es so ähnlich, wie Martin es gesagt hat. Dann reicht 
auch wieder das Byte.
union
 {
   struct
   {
     unsigned RunProg:1;           //  Run Programm
     unsigned ConnectService:1;  //  Connect Service
     unsigned ConnectBusSpi:1;  //  Connect Bus Spi
     unsigned TransferError:1;  //  Daten Transfer Error
   }
   unsigned char Byte;
 } GLOBAL ProzessStatus;

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Funktioniert einwandfrei. Weis noch nicht alles, daher frage ich ab und 
zu.

@ Micha in der 9. Zeile fehlt das " ; " sonst "syntax error"
aber trotzdem spitze.

Danke an alle.
Gruß Siegfried

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Micha R.

> Es geht schon so:
>union
>{
>  struct
>  {
>    unsigned RunProg:8;           //  Run Programm
>    unsigned ConnectService:5;  //  Connect Service
>    unsigned ConnectBusSpi:2;  //  Connect Bus Spi
>    unsigned TransferError:1;  //  Daten Transfer Error
>  } ;
>  unsigned short Byte;
>} ProzessStatus; 

Ja sicher geht es so (mehrere Bits), aber ist dies auch gewünscht?

@ Siegfried
In diesem Beispiel hier könnte z.B. ConnectService Zahlen im Bereich von 
0 bis 31 aufnehmen, da für diesen Wert 5 Bit reserviert sind.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe weiter gearbeitet. Weicht etwas von Betreff ab.
einmal dieses

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 short Byte;
} GLOBAL TestStatus[8];

und noch dieses

TestStatus[0].Byte = 0;
TestStatus[1].Byte = 0;
TestStatus[2].Byte = 0;
TestStatus[3].Byte = 0;
TestStatus[4].Byte = 0;
TestStatus[5].Byte = 0;
TestStatus[6].Byte = 0;
TestStatus[7].Byte = 0;

bzw.

TestStatus[0].Bit7 = 1;
TestStatus[0].Bit6 = 1;
TestStatus[0].Bit5 = 1;
TestStatus[0].Bit4 = 1;
TestStatus[0].Bit3 = 0;
TestStatus[0].Bit2 = 0;
TestStatus[0].Bit1 = 0;
TestStatus[0].Bit0 = 0;


Compiler und Linker arbeiten einwandfrei.

ist dieses so in Ordnung ?

in Assembler belegt diese Zeile "TestStatus[0].Byte = 0; 4 Bytes
und diese Zeile TestStatus[0].Bit6 = 1;  2 Bytes.

Gruß Siegfried

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist die Reihenfolge der Bitnummern nicht andersherum? Also mit 0 
beginnend.

Den 2. Teil könntest du in eine Zeile zusammen fassen. Du kannst ja 
"TestStatus[0].Byte = 0;" einen beliebigen Wert zuweisen, er muss ja 
nicht Null sein.

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum nimmst du einen unsigned short und kein unsigned char?

MW

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:
> Ja sicher geht es so (mehrere Bits), aber ist dies auch gewünscht?

Das habe ich mich auch gewundert, aber Siegfried hatte es ja so 
geschrieben. Wäre die Frage von ihm "was bedeuten die Zahlen dahinter" 
schon eher gekommen, wäre es klar gewesen, dass natürlich NICHT so 
gewünscht war.

@Siegfried
Ich würde auch meinen, dass mit Bit 0 begonnen wird.

Da deine Union nur 8 Bitdefinitionen enthält, kannst du das "unsigned 
short" durch "unsigned byte" ersetzen.
Dies ist sicher auch der Grund für die unterschiedlichen 
Assemblercode-Längen.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe "unsigned short" durch "unsigned byte" ersetzt. Funktioniert.

Beitrag vom "Datum: 12.08.2008 20:15 " ist nur ein Beispiel zum testen 
gewesen.

@Micha
"Ich würde auch meinen, dass mit Bit 0 begonnen wird."

Haffe, das ich nicht falsch liege.
Ich habe mit Bit 7 angefangen, da in dem Byte enthaltene Bits einzel 
gesetzt, gelöscht und getestet werden, aber auch das Byte (alle 8 Bits) 
komplett gelesen oder beschrieben wird.

super Leistung für alle Infos.
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.