Unterstützung C Code + union

OP #7413842
Lesenswert?

Hallo und guten Morgen,

für meine Mikrocontroller Anwendung habe ich folgendes Problem vorliegen:

Ich habe als Eingangsparameter ein union. Dieses union besteht aus 8 Bit (uint8_t). Jedes Bit steht für ein bestimmtest Symbol. Nun soll dieser union Wert verwendet werden, um die entsprechenden Symbole auf dem Display darzustellen.

1
typedef union
2
{
3
  uint8_t rawByte;
4
  struct
5
  {
6
    uint8_t date : 1;
7
    uint8_t warning : 1;
8
    uint8_t lowBattery : 1;
9
    uint8_t temp : 1;
10
    uint8_t pressure : 1;
11
  }st_displaySymbols;
12
}un_displaySymbols;

Für die Darstellung eines Symbols wird eine Funktion verwendet:

1
typedef enum
2
{
3
  DISPLAY_SYMBOL_DATE,
4
  DISPLAY_SYMBOL_WARNING,
5
  DISPLAY_SYMBOL_LOW_BATTERY,
6
  DISPLAY_SYMBOL_TEMP,
7
  DISPLAY_SYMBOL_PRESSURE,
8
} en_displaySymbols;
1
void Display_SetSymbol(en_displaySymbols symbol, bool on)
OP #7413856
Lesenswert?

Ist schwer das zu formulieren. Ich versuche es mal. Ich erhalte einen 8 Bit Wert. In diesen 8 Bits entspricht dann jedem Bit ein bestimmtes Symbol. Nun soll in der Weiterverarbeitung die Symbole auf das Display angezeigt werden. Ein einzelnes Symbol zu aktivieren auf dem Display ist kein Problem. Wenn ich aber einen 8 Bit Wert habe, wo jedes Bit einem Symbol entspricht, das bereitet mir Probleme wie ich das in Software umsetzen könnte.

Beispiel: uin8_t = 0xA0 ==> bit: 1010 0000

Hier soll das entsprechende Symbol von der Bitstelle 7 und auch von der Bitstelle 5 auf dem Display dargestellt werden. Alle anderen Symbol sollen nicht angezeigt werden.

#7413888
Lesenswert?

He S. schrieb:

Hallo und guten Morgen,

für meine Mikrocontroller Anwendung habe ich folgendes Problem vorliegen:

Ich habe als Eingangsparameter ein union. Dieses union besteht aus 8 Bit (uint8_t). Jedes Bit steht für ein bestimmtest Symbol. Nun soll dieser union Wert verwendet werden, um die entsprechenden Symbole auf dem Display darzustellen.

Evtl. so:

1
     un_displaySymbols v = ...;
2
     Display_SetSymbol(DISPLAY_SYMBOL_DATE, v.st_displaySymbols.date == 1); 
3
     Display_SetSymbol(DISPLAY_SYMBOL_WARNING, v.st_displaySymbols.warning);
4
     // ...

Ich nehme an, dass Du immer einen vollständige Zustandsupdate benötigst.

Ich hoffe, dir ist bewusst, dass das Dekodieren einer Leitungscodierung mit Hilfe einer union ein wenig gute Idee ist.

Du kannst den Namen der struct in der union auch weglassen, dann geht es eleganter:

1
     un_displaySymbols v = ...;
2
     Display_SetSymbol(DISPLAY_SYMBOL_DATE, v.date == 1); 
3
     Display_SetSymbol(DISPLAY_SYMBOL_WARNING, v.warning);
4
     // ...
#7413943
Lesenswert?

He S. schrieb:

Hallo Wilhelm was meinsrt du mit ohne struct?

Den Namen(!) des struct weglassen, wie geschrieben. Also so:

1
typedef union
2
{
3
  uint8_t rawByte;
4
  struct
5
  {
6
    uint8_t date : 1;
7
    uint8_t warning : 1;
8
    uint8_t lowBattery : 1;
9
    uint8_t temp : 1;
10
    uint8_t pressure : 1;
11
  };
12
}un_displaySymbols;

P.S.: Der Präfix "un_" ist unnötig im Typ-Namen.

#7414020
Lesenswert?

Peter D. schrieb:

Quasi nen Knopf an die Backe nähen.

Jupp. Wobei ich das weniger sinnlos auch schon für einen primitiven priorisierten Scheduler genau so gemacht habe.

Aber der TO wollte doch unbedingt Switch/Case!

Es würde mich noch nicht einmal wundern, wenn der Optimizer daraus durch loop unrollig wieder eine Reihe von if( byte & (1<<bit) ){} machen würde.

OP #7414030
Lesenswert?

Ich habe es ohne switch/case realisiert. Ich übergebe der Funktion den Wert von der union.

1
typedef union
2
{
3
  uint8_t rawByte;
4
  struct
5
  {
6
    uint8_t date : 1;
7
    uint8_t warning : 1;
8
    uint8_t lowBattery : 1;
9
    uint8_t temp : 1;
10
    uint8_t pressure : 1;
11
  };
12
}un_displaySymbols;
13

14
un_displaySymbols displaySymbols;
15

16
displaySymbols = incomming_data;
17

18
Display_SetSymbol(DISPLAY_SYMBOL_DATE, displaySymbols.date);
19
Display_SetSymbol(DISPLAY_SYMBOL_WARNING, displaySymbols.warning);
20
...
21
...
#7414072
Lesenswert?

He S. schrieb:

Ich habe es ohne switch/case realisiert.

Das ist die Lösung, die ich oben beschrieben habe.

Ich übergebe der Funktion den Wert von der union.

Nicht ganz: Du benutzt eine impl. Typkonversion.

Es ist besser, wenn die Elemente des struct, die ja eigentlich Bool'sch sind, auch als solche deklariert werden.

Und wie gesagt: die Namen Deine DT sind Mist.

He S. schrieb:

un_displaySymbols displaySymbols; displaySymbols = incomming_data;

Das schreibt man so:

1
const un_displaySymbols displaySymbols = incomming_data;

Ich denke, Dir ist dann auch klar, warum.

#7414154
Lesenswert?

Ich würde das so machen:

1
#define USED_BITS  5
2

3
// Bit 0
4
void date(uint8_t val)
5
{
6

7
}
8

9
// Bit 1
10
void warning(uint8_t val)
11
{
12

13
}
14

15
// Bit 2
16
void lowBattery(uint8_t val)
17
{
18

19
}
20

21
// Bit 3
22
void temp(uint8_t val)
23
{
24

25
}
26

27
// Bit 4
28
void pressure(uint8_t val)
29
{
30

31
}
32

33
const void (*func[USED_BITS])(uint8_t val) =
34
{
35
  date,
36
  warning,
37
  lowBattery,
38
  temp,
39
  pressure
40
};
41

42
process_RawByte(uint8_t byte)
43
{
44
  for (int i = 0; i < USED_BITS; i++)
45
  {
46
    func[i](byte & 1);
47
    byte = byte >> 1;
48
  }
49
}
OP #7414634
Lesenswert?

1
typedef union
2
{
3
  uint8_t rawByte;
4
  struct
5
  {
6
    bool date;
7
    bool warning;
8
    bool lowBattery;
9
    bool temp;
10
    bool pressure;
11
  };
12
}un_displaySymbols;

Das mit bool lässt der Compiler zu. Nur das mit der uint8_t Variable funktioniert nicht mehr. Diese ist aber schon für mich notwendig.

Moderator Persönliche Seite #7414665
Lesenswert?

Irgend W. schrieb:

Achtung, C kennt keine echten Bit-Typen.

Eben. Das noch kombiniert mit Bitfeldern, welche in C weder plattformkapatibel noch sonstwas sind, setzt dem Ganzen noch die Krone auf. Man handelt sich ein Problem nach dem nächsten ein.

Meines Erachtens sind Bitfelder in C überflüssig. Man kann das auch klassisch aufziehen:

1
uint8_t symbol_mask;
2

3
#define DISPLAY_SYMBOL_DATE_MASK            0x01
4
#define DISPLAY_SYMBOL_WARNING_MASK         0x02
5
#define DISPLAY_SYMBOL_LOW_BATTERY_MASK     0x04
6
#define DISPLAY_SYMBOL_TEMP_MASK            0x08
7
#define DISPLAY_SYMBOL_PRESSURE_MASK        0x10

Rest siehe auch Artikel Bitmanipulation.

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