Union Bitfield
Mittwoch, 23. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Entwicklungswerkzeuge  |  Compiler  |  Union Bitfield « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Union Bitfield  (Gelesen 2496 mal)
 
Max Pohl
Jr. Member
**
Offline Offline

Beiträge: 65



Profil anzeigen
« am: September 06, 2011, 10:28:27 »

Hallo Zusammen,
ich möchte eine 32bit Integer Zahl mittels eines Bitfields zerstückeln, dazu habe ich mal folgenen Code geschrieben.
Leider funktioniert das überhaupt nicht.
Was mache ich falsch? Weinen

Compiler: C30

Gruß Max
Code:
union GYRO
{
struct GyroValue
{
unsigned int P1:1;
unsigned int CHK:1;
unsigned int CST:1;
unsigned int PWR:1;
unsigned int POR:1;
unsigned int NVM:1;
unsigned int Q:1;
unsigned int PLL:1;
unsigned int empty:2;
unsigned int Daten:16;
unsigned int ST:2;
unsigned int P0:1;
unsigned int SQ:3;
} SensorData;
unsigned long Data;
}Gyro1;

Gyro1.Data = 0x3D5557AD;

« Letzte Änderung: September 06, 2011, 10:44:05 von Max Pohl » Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #1 am: September 06, 2011, 11:38:20 »

Hi,

mal als Beispiel:

Code:
// Summary: The format of an HDD_STATUS response
/* IDE Status Register:
;  bit 7: Busy 1=busy, 0=not busy
;  bit 6: Ready 1=ready for command, 0=not ready yet
;  bit 5: DF 1=fault occured inside drive
;  bit 4: DSC 1=seek complete
;  bit 3: DRQ 1=data request ready, 0=not ready to xfer yet
;  bit 2: CORR 1=correctable error occured
;  bit 1: IDX vendor specific
;  bit 0: ERR 1=error occured */

typedef union
{
    BYTE _byte;                         // Byte-wise access
    // This structure allows bitwise access of the response
    struct
    {
        unsigned ERR:1;                // 1=error occured
        unsigned IDX:1;          // vendor specific
        unsigned CORR:1;          // 1=correctable error occured
        unsigned DRQ:1;        // 1=data request ready, 0=not ready to xfer yet
        unsigned DSC:1;              // 1=seek complete
        unsigned DF:1;          // 1=fault occured inside drive
        unsigned READY:1;          // 1=ready for command, 0=not ready yet
        unsigned BUSY:1;        // 1=busy, 0=not busy
    };
}HDD_STATUS;

typedef union
{
struct
{
CHAR model_number[40];
QWORD LBA_48;
};
    struct
    {
        unsigned LBA_48_SUPPORT_BIT:1;  // 1= 48Bit LBA is supported
unsigned SMART:1; // 1=SMART is supported
    };
}HDD_IDENTIFY_RESPONSE;

Gruß
Stefan
Gespeichert

Max Pohl
Jr. Member
**
Offline Offline

Beiträge: 65



Profil anzeigen
« Antworten #2 am: September 06, 2011, 11:48:15 »

Dies ist mein aktueller Code,
wenn ich nun der variable Data einen 32bit wert zuweise und z.B Daten überprüfe stimmt nichts.
Code:
typedef struct GYRODATA_struct
{
union
{
unsigned long Data;
struct
{
unsigned P1:1;
unsigned CHK:1;
unsigned CST:1;
unsigned PWR:1;
unsigned POR:1;
unsigned NVM:1;
unsigned Q:1;
unsigned PLL:1;
unsigned empty:2;
unsigned Daten:16;
unsigned ST:2;
unsigned P0:1;
unsigned SQ:3;
};
};
}GYRO1;
Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #3 am: September 06, 2011, 12:04:01 »

Hi,

daher ist auch dieser BYTE access mit drin (geht natürlich auch für andere DAtentypen). Dann kannst du drauf zugreifen:
Zitat
HDDStatus._byte = (PMDIN&0xFF);   // read

Gruß
Stefan
Gespeichert

Max Pohl
Jr. Member
**
Offline Offline

Beiträge: 65



Profil anzeigen
« Antworten #4 am: September 06, 2011, 12:17:16 »

Ja das habe ich drin, wie ich eben festegestellt habe stimmt das meiste nur die letzten 6bits machen was sie wollen;).
Hier nochmal der ganze Code.
Code:
typedef union GYRODATA
{
unsigned long Data;
struct
{
unsigned int P1:1;
unsigned int CHK:1;
unsigned int CST:1;
unsigned int PWR:1;
unsigned int POR:1;
unsigned int NVM:1;
unsigned int Q:1;
unsigned int PLL:1;
unsigned int empty:2;
unsigned int Daten:16;
unsigned int ST:2;
unsigned int P0:1;
unsigned int SQ:3;
};
}GYRO1;

GYRO1 test;
test.Data =   0xFFFFFFFF;
printf("\n\n\r");
printf("Data%lu\n\n\r",test.Data);
printf("SQ:%u\n\r",test.SQ);
printf("P0:%u\n\r",test.P0);
printf("ST:%u\n\r",test.ST);
printf("Data:%u\n\r",test.Daten);
printf("empty:%u\n\r",test.empty);
printf("PLL:%u\n\r",test.PLL);
printf("Q:%u\n\r",test.Q);
printf("NVM:%u\n\r",test.NVM);
printf("POR:%u\n\r",test.POR);
printf("PWR:%u\n\r",test.PWR);
printf("CST:%u\n\r",test.CST);
printf("CHK:%u\n\r",test.CHK);
printf("P1:%u\n\r",test.P1);

« Letzte Änderung: September 06, 2011, 12:20:56 von Max Pohl » Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #5 am: September 06, 2011, 18:02:08 »

Der ANSI-C-Standard garantiert nicht, dass Strukturen und Bitfelder an aufeinanderfolgenden Adressen lückenlos im Speicher abgelegt werden (Stichwort „padding“).

Konkret wird in Deinem Beispiel das Bitfeld wie folgt im Speicher abgelegt:

1. 16-Bit-Word: P1 bis empty (10 Bits) und 6 unbenutzte Bits
2. 16-Bit-Word: Daten
3. 16-Bit-Word: ST bis SQ

Der Compiler verwendet diese Anordnung, um den Zugriff auf das Element "Daten" zu optimieren (liegt dann an einer Word-Grenze im Speicher).

Im C30 (gcc) gibt es die Möglichkeit, das Padding über __attribute__ ((packed)) zu deaktivieren. Ob dann aber der Zugriff auf "Daten" noch korrekt funktioniert, kann ich nicht garantieren.


Viele Grüße

Bernd  
Gespeichert

Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #6 am: September 06, 2011, 22:20:05 »

Aus Interesse eben gerade mal mit dem C30 v3.30b ausprobiert:

Code:
typedef union GYRODATA
{
    unsigned long Data;
    struct
    {
        unsigned int P1:1;
        unsigned int CHK:1;
        unsigned int CST:1;
        unsigned int PWR:1;
        unsigned int POR:1;
        unsigned int NVM:1;
        unsigned int Q:1;
        unsigned int PLL:1;
        unsigned int empty:2;
        unsigned int Daten:16;
        unsigned int ST:2;
        unsigned int P0:1;
        unsigned int SQ:3;
    } __attribute__ ((packed)); // <--
} GYRO1;

Funktioniert wie erwartet und auch ein Zugriff auf „Daten“ bereitet kein Problem.


Viele Grüße

Bernd
Gespeichert

Max Pohl
Jr. Member
**
Offline Offline

Beiträge: 65



Profil anzeigen
« Antworten #7 am: September 07, 2011, 07:49:30 »

Vielen Dank Bernd,
funktioniert!

Gruß Max
Gespeichert
Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.039 Sekunden mit 18 Zugriffen.
 
Top! Top!