Forum: Mikrocontroller und Digitale Elektronik Zeiger auf Bitfeld, 11 Bit in unsigned char Feld wandeln


von Henning S. (xtsi)


Lesenswert?

Hallo zusammen, ich komme zu keiner schnellen sinnvollen Lösung:

Problem:

ATTiny2313, AVR-GCC, TI TLC5940 über SPI angeschlossen

Der TI möchte gerne PWM bzw DotCorrection Values in 6 bzw 12 Bit haben. 
Über SPI wird dann ein zusammenhängender Block rausgeschoben, also 96 
bzw 192 Byte.
Nun suche ich nach einer Möglichkeit, den rauszuschiebenden Block 
möglichst ohne große Umwege zu "erstellen".
1
void TLC5940_SPISendBuffer(unsigned char *ucBuffer, unsigned char ucLen);

Nun könnte man sich vorstellen, die Variablen als Bitfelder abzulegen, 
also z.B.
1
typedef struct
2
    {
3
        unsigned int uiPWMValue:12;
4
    } TPWMValue;
5
6
TPWMValue       g_PWM[16];
7
8
g_PWM[0].uiPWMValue = 0x0;
9
g_PWM[1].uiPWMValue = 0x10;
10
11
TLC5940_SPISendBuffer((unsigned char*)g_PWM, sizeof(g_PWM));
Nun kommen aber beim Zugriff immer wieder die Einzelbytes raus.

Gewünscht:
1
Zielbuffer[0] = 0x0
2
Zielbuffer[1] = 0x0
3
Zielbuffer[2] = 0x10
und nicht
1
Zielbuffer[0] = 0x0
2
Zielbuffer[1] = 0x10
3
[...]
Irgendwelche spontanen Ideen? Klar, so geht es nicht, aber irgendwelche 
Ideen, wie das schnell gemacht werden könnte?

Gruss,

Henning

von Henning S. (xtsi)


Lesenswert?

Meinte natürlich 12 Bit im Betreff :(

von Klaus H. (Gast)


Lesenswert?

Geht das nicht mir einer "union"?

von Henning S. (xtsi)


Lesenswert?

Theoretisch schon, hab dann folgendes gebaut (Frei nach der 
Codesammlung, nach einigem Suchen):
1
union DotCorrection {
2
  struct Dots {
3
    unsigned char Dot0 : 6;
4
    unsigned char Dot1 : 6;
5
    unsigned char Dot2 : 6;
6
    unsigned char Dot3 : 6;
7
    unsigned char Dot4 : 6;
8
    unsigned char Dot5 : 6;
9
    unsigned char Dot6 : 6;
10
    unsigned char Dot7 : 6;
11
    unsigned char Dot8 : 6;
12
    unsigned char Dot9 : 6;
13
    unsigned char Dot10 : 6;
14
    unsigned char Dot11 : 6;
15
    unsigned char Dot12 : 6;
16
    unsigned char Dot13 : 6;
17
    unsigned char Dot14 : 6;
18
    unsigned char Dot15 : 6;
19
  } d;
20
  unsigned char Dots[12];
21
} z;
22
23
function Test()
24
{
25
     unsigned char ucInt0;
26
     unsigned char ucInt1;
27
     unsigned char ucInt2;
28
     unsigned char ucInt3;
29
30
     z.d.Dot0 = 0x01;
31
     z.d.Dot1 = 0x10;
32
     z.d.Dot2 = 0x01;
33
     z.d.Dot3 = 63;
34
     z.d.Dot4 = 63;
35
     z.d.Dot5 = 63;
36
     z.d.Dot6 = 63;
37
     z.d.Dot7 = 63;
38
     z.d.Dot8 = 63;
39
     z.d.Dot9 = 63;
40
     z.d.Dot10 = 63;
41
     z.d.Dot11 = 63;
42
     z.d.Dot12 = 63;
43
     z.d.Dot13 = 63;
44
     z.d.Dot14 = 63;
45
     z.d.Dot15 = 63;
46
47
    ucInt0 = z.Dots[0];
48
    ucInt1 = z.Dots[1];
49
    ucInt2 = z.Dots[2];
50
    ucInt3 = z.Dots[3];
51
}

Wenn ich nicht völlig falsch gerechnet habe, müsste ich die Werte
1
ucInt0 = 0x05
2
ucInt1 = 0x00
3
ucInt2 = 0x7F
4
ucInt3 = 0xFF
rausbekommen,

allerdings bekomme ich folgendes:
1
ucInt0 = 0x01
2
ucInt1 = 0x14
3
ucInt2 = 0xFC
4
ucInt3 = 0xFF

also
1
00000001 00010100 11111100 11111111
statt
1
00000101 00000000 01111111 11111111

Wo steckt der Dreher???

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
Noch kein Account? Hier anmelden.