Forum: Mikrocontroller und Digitale Elektronik 32Bit schieben.


von Atmega (Gast)


Lesenswert?

Hallo,

ich will eine 32Bit Variable aus mehreren Werten zusammensetzen.

#define A 5
#define B 10
#define C 2
#define D 20
#define E 25

Nun soll der Integer folgendermaßen aufgebaut sein:

MSB
7 Bit für A
9 Bit für B
3 Bit für C
5 Bit für D
8 Bit für E
LSB

uint32_t variable = (((uint32_t)A << 25) | (((uint32_t)B << 16) | 
(((uint32_t)C << 13) | (((uint32_t)D << 8) | (uint32_t)E))));

Das ganze klappt bei mir aber nicht.

Ich habe versucht ohne A und B (also nur 16Bit)

uint32_t variable = ((C << 13) | ((D << 8) | E));

Das klappt...

Kann mir jemand sagen, was ich falsch mache? Nutze einen 8Bit AVR...

von Jim M. (turboj)


Lesenswert?

Müsste eigentlich tun. Oft ist bei AVR das Problem beim flaschen 
printf(),
weil man für 32 Bits da was anderes als "%d" angeben muss.

von Atmega (Gast)


Lesenswert?

Sehr gut. Danke!

Lösung falls mal jemand hier guckt:

uint32_t x;

printf("%"PRId32"",x);

von mh (Gast)


Lesenswert?

Für uint32_t müsste es PRIu32 sein.

von Walter S. (avatar)


Lesenswert?

Atmega schrieb:
> uint32_t variable = (((uint32_t)A << 25) | (((uint32_t)B << 16) |
> (((uint32_t)C << 13) | (((uint32_t)D << 8) | (uint32_t)E))));

bevor ich Augenkrebs kriege würde ich mir da ein paar Klammern sparen

uint32_t variable = ((uint32_t)A << 25) | ((uint32_t)B << 16) |
                    ((uint32_t)C << 13) | ((uint32_t)D << 8)  | 
(uint32_t)E;

oder gleich
#define A 5UL
#define B 10UL
#define C 2UL
#define D 20UL
#define E 25UL

uint32_t variable = (A << 25) | (B << 16) |
                    (C << 13) | (D << 8)  | E;

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Für C gibt es Strukturen aus Bitfeldern (Variablenname mit Doppelpunkt 
und Bitanzahl dahinter -- wenn ich mich recht erinnere). Dann braucht 
man sich um solchen Kram normalerweise nicht mehr zu kümmern.

EDIT (Beispiel):
1
struct {
2
  uint32_t tag:5;
3
  uint32_t int monat:4;
4
  uint32_t int jahr:11;
5
  } wert;

Zugriff dann per wert.tag, wert.monat usw.

von Stefan F. (Gast)


Lesenswert?

Ich nehme dafür immer %ul

von holger (Gast)


Lesenswert?

>Ich nehme dafür immer %ul

Ääh, %lu?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> Ich nehme dafür immer %lu

Das ist aber für “unsigned long”, nicht für “uint32_t”.

Hatten wir doch gerade erst:

Beitrag "C: stdint und Formatkennzeichner"

Wenn man schon die portable Typnamen benutzt, dann sollte man auch
die portablen printf- und scanf-Formatbezeichner nehmen.

von Stefan F. (Gast)


Lesenswert?

>>Ich nehme dafür immer %ul
> Ääh, %lu?

Ja. Ich wollte %lu schreiben.

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.