Port setzen in Binärschreibweise

OP #3301134
Lesenswert?

Hallo

Nutze die IAR Workbench und wollte soeben beim Setzen eines Ports 
anstatt
1
PORT = 0x0E
 einfach mal
1
PORT = 0b00001110

benutzen, aber da meckerte mir der Compiler rum.
Geht das einfach nur nicht, oder muss ich da bei der Syntax was 
Spezielles beachten?

Danke
Gast #3301185
Lesenswert?

Die Binärschrbeiweise kennt IAR nicht. Aber du kannst dir auf der 
Homepgae Files runterladen, in denen die Makros für 8, 16 und 32 Bit 
definiert sind. Musste nur einbinden, dann geht es. Sparste dir das 
selber anlegen der 65536 Makros bei 16Bit... vielleicht war ja auch 
32Bit dabei :-) ?
Persönliche Seite #3301269
Lesenswert?

Dennis schrieb:
> Aber du kannst dir auf der Homepgae Files runterladen, in denen die
> Makros für 8, 16 und 32 Bit definiert sind.

Man könnte sich ja auch mal drei Tage nacheinander jeweils 10 Minuten 
lang hinsetzen und die 16 Bitwerte für ein Nibble lernen.

Dann kann man Hexzahlen lesen, und muss nicht auf fehlerträchtige 
Binärdarstellungen ausweichen.

Fehlerträchtig, ja:

0b000010000000001 ist halt nicht das gleiche wie 0b0000100000000001.

Da muss man schön viele Nullen zählen, um den Unterschied zu sehen.

0x0401 und 0x0801 sind irgendwie auffälliger unterschiedlich, nicht?
Moderator #3301309
Lesenswert?

Such im Netz nach
1
c binary constants macro

Da findest du entsprechende Makros zur Umrechnung. Man braucht übrigens 
für 16-Bit-Konstanten keine 2**16 Makros, ein einziges genügt schon.

Aber wie schon geschrieben wurde: Binärkonstanten bringen mehr Nachteile 
als Vorteile, und kein halbwegs erfahrener Embedded-Programmierer will 
sie. Deswegen sind sie nicht einmal im allerneuesten C-Standard (C11) 
vorgesehen.

Hexadezimal- und (in selteneren Fällen) Oktaldarstellung sind vollkommen 
ausreichend.
Moderator Persönliche Seite #3301383
Lesenswert?

Yalu X. schrieb:
> Aber wie schon geschrieben wurde: Binärkonstanten bringen mehr Nachteile
> als Vorteile, und kein halbwegs erfahrener Embedded-Programmierer will
> sie.

Naja.  Man soll nie „nie“ sagen … ich habe sie auch schon benutzt:
1
/*
2
 * Diagnostic patterns.
3
 */
4
static const segment_bits sbits[] PROGMEM =
5
{
6
  //         a    aaaaaaaa    aaaa        aaaaaaaa    aaaaa
7
  //    aaaaa1    11112222    2333   a    33322222    11111aaa
8
  //  xx135791    35791357    9135xxx2    42086420    86420864
9
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }, /* all off */
10
  { 0b00111111, 0b11111111, 0b11110001, 0b11111111, 0b11111111 }, /* all on */
11
  { 0b00000000, 0b00000000, 0b00000001, 0b11111111, 0b11111111 }, /* checker */
12
  { 0b00111111, 0b11111111, 0b11110000, 0b00000000, 0b00000000 }, /* checker */
13

14
  { 0b00100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }, /* 1 */
15
  { 0b00000000, 0b00000000, 0b00000001, 0b00000000, 0b00000000 },
16
  { 0b00010000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 },
17
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000001 },
18
  { 0b00001000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 },
19

20
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000010 }, /* 6 */
21
  { 0b00000100, 0b00000000, 0b00000000, 0b00000000, 0b00000000 },
22
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000100 },
23
  { 0b00000010, 0b00000000, 0b00000000, 0b00000000, 0b00000000 },
24
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001000 },
25

26
  { 0b00000001, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }, /* 11 */
27
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000 },
28
  { 0b00000000, 0b10000000, 0b00000000, 0b00000000, 0b00000000 },
29
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00100000 },
30
  { 0b00000000, 0b01000000, 0b00000000, 0b00000000, 0b00000000 },
31

32
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01000000 }, /* 16 */
33
  { 0b00000000, 0b00100000, 0b00000000, 0b00000000, 0b00000000 },
34
  { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b10000000 },
35
  { 0b00000000, 0b00010000, 0b00000000, 0b00000000, 0b00000000 },
36
  { 0b00000000, 0b00000000, 0b00000000, 0b00000001, 0b00000000 },
37

38
  { 0b00000000, 0b00001000, 0b00000000, 0b00000000, 0b00000000 }, /* 21 */
39
  { 0b00000000, 0b00000000, 0b00000000, 0b00000010, 0b00000000 },
40
  { 0b00000000, 0b00000100, 0b00000000, 0b00000000, 0b00000000 },
41
  { 0b00000000, 0b00000000, 0b00000000, 0b00000100, 0b00000000 },
42
  { 0b00000000, 0b00000010, 0b00000000, 0b00000000, 0b00000000 },
43

44
  { 0b00000000, 0b00000000, 0b00000000, 0b00001000, 0b00000000 }, /* 26 */
45
  { 0b00000000, 0b00000001, 0b00000000, 0b00000000, 0b00000000 },
46
  { 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b00000000 },
47
  { 0b00000000, 0b00000000, 0b10000000, 0b00000000, 0b00000000 },
48
  { 0b00000000, 0b00000000, 0b00000000, 0b00100000, 0b00000000 },
49

50
  { 0b00000000, 0b00000000, 0b01000000, 0b00000000, 0b00000000 }, /* 31 */
51
  { 0b00000000, 0b00000000, 0b00000000, 0b01000000, 0b00000000 },
52
  { 0b00000000, 0b00000000, 0b00100000, 0b00000000, 0b00000000 },
53
  { 0b00000000, 0b00000000, 0b00000000, 0b10000000, 0b00000000 },
54
  { 0b00000000, 0b00000000, 0b00010000, 0b00000000, 0b00000000 },
55
};

Wäre hexadezimal nicht so übersichtlich.

> Deswegen sind sie nicht einmal im allerneuesten C-Standard (C11)
> vorgesehen.

Das ist eher Ignoranz des C-Standard-Gremiums gegenüber popeligen
Embedded-Programmierern.  Im C99 Rationale steht dazu lapidar, dass
der entsprechende Vorschlag “due to lack of precedence and
application” nicht mit aufgenommen worden war.  Nun, da GCC das
offziell übernommen hat, können sie zumindest keinen “lack of
precedence” mehr konstatieren, wenn das mal wieder jemand aufs
Tablett legt.
Gast #3301592
Lesenswert?

Yalu X. schrieb:
> Da findest du entsprechende Makros zur Umrechnung. Man braucht übrigens
> für 16-Bit-Konstanten keine 2**16 Makros, ein einziges genügt schon.

Das ist ok, es gibt aber auch Lösungen im Netz per h.file, da werden 256 
Konstanten definiert - aber dann muss man sich ganz genau an die 
Schreibweise halten, und 16 Bit gibts eh nicht.

Gruss Reinhard
Moderator #3301599
Lesenswert?

Jörg Wunsch schrieb:
> Wäre hexadezimal nicht so übersichtlich.

Mag sein. Allerdings (vielleicht liegt an meinen Augen) fällt es mir 
schwer, mit einem Blick zu erkennen, wo denn nun überall die 1-Bits 
sind. Insofern ist der Vorteil für mich persönlich eher gering, da ich, 
um diese Bitmuster zu verstehen, sowieso Zeile für Zeile abscannen 
müsste.

Man könnte das Ganze auch ohne Verwendung von Binär- und Hexzahlen so 
schreiben:
1
#define BITS(b) {       \
2
  (uint8_t)((b) >> 32), \
3
  (uint8_t)((b) >> 24), \
4
  (uint8_t)((b) >> 16), \
5
  (uint8_t)((b) >>  8), \
6
  (uint8_t)((b) >>  0) }
7

8
#define BIT(n)           BITS(1ULL << (n))
9
#define BIT_RANGE(b, n)  (((1ULL << n) - 1) << b)
10

11
#define BITS_NONE        BIT_RANGE( 0,  0)
12
#define BITS_ALL_EVEN    BIT_RANGE( 0, 17)
13
#define BITS_ALL_ODD     BIT_RANGE(20, 18)
14
#define BITS_ALL         (BITS_ALL_EVEN | BITS_ALL_ODD)
15

16
static const segment_bits sbits[] PROGMEM = {
17
  BITS(BITS_NONE),     BITS(BITS_ALL),
18
  BITS(BITS_ALL_EVEN), BITS(BITS_ALL_ODD),
19
  BIT(37), BIT(16),
20
  BIT(36), BIT( 0),
21
  BIT(35), BIT( 1),
22
  BIT(34), BIT( 2),
23
  BIT(33), BIT( 3),
24
  BIT(32), BIT( 4),
25
  BIT(31), BIT( 5),
26
  BIT(30), BIT( 6),
27
  BIT(29), BIT( 7),
28
  BIT(28), BIT( 8),
29
  BIT(27), BIT( 9),
30
  BIT(26), BIT(10),
31
  BIT(25), BIT(11),
32
  BIT(24), BIT(12),
33
  BIT(23), BIT(13),
34
  BIT(22), BIT(14),
35
  BIT(21), BIT(15),
36
  BIT(20) 
37
};

Für meine (schlechten) Augen wird dadurch auch die Systematik etwas auch 
deutlicher.
Moderator Persönliche Seite #3301608
Lesenswert?

Yalu X. schrieb:
> Für meine (schlechten) Augen wird dadurch auch die Systematik etwas auch
> deutlicher.

Ja, das ist gut zu lesen.

Der wesentliche Punkt der Binärschreibweise war, dass ich von den
Kommentaren darüber ausgehend die Einsen gesetzt habe.  Also erstmal
im Editor ein Array angelegt, in dem alle Konstanten als 0b00000000
drin standen, und dann Zeile für Zeile die Einsen entsprechend der
Anodenreihenfolge (es geht um eine VFD-Ansteuerung) im Kommentar
gesetzt.

Es ging also eher um Schreibbarkeit denn Lesbarkeit. ;-)
Moderator #3301620
Lesenswert?

Jörg Wunsch schrieb:
> Es ging also eher um Schreibbarkeit denn Lesbarkeit. ;-)

Ok :)

Die Binärschreibweise ist aus dem gleichen Grund auch ganz praktisch zur 
Definition von Zeichensätzen für Matrix-Displays. Besser lesbar wäre das 
Ganze allerdings, wenn man statt 0b11001010 auch 0b11__1_1_ o.ä. 
schreiben könnte.

In C++ kann man auch ein Stringliteral (z.B. "##--#-#-") von einem Makro 
in eine Integerzahl umwandeln lassen. In C geht das leider (noch) nicht, 
weil dort "##--#-#-"[3] nicht als konstanter Ausdruck angesehen wird.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren