Forum: Mikrocontroller und Digitale Elektronik Bit Bezeichnungen in enum eintragen?!


von Jan H. (janiiix3)


Angehängte Dateien:

Lesenswert?

Guten Morgen!
1
enum dspCr1Bits
2
{
3
  DSP_CR1_CLRSS_TO1  = 1<<0,
4
  DSP_CR1_CLEARSS1  = 1<<4,  
5
  DSP_CR1_ENVREF1    = 1<<5,
6
  DSP_CR1_TC1    = 1<<6,
7
};
Wie man laut Bild oben sieht, hat dieses Register (32 Bit, okay das kann 
man im Bild jetzt nicht erkennen, egal) [0..3] 4 Bit´s.
Dies wollte Ich nun mit "enum" niederschreiben.(die anderen Bits sollen 
folgen..)

Ist das so optimal wie Ich das vor habe?

: Bearbeitet durch User
von Mark (Gast)


Lesenswert?

Im Prinzip kann man das so machen. enums oder defines sind typisch zum 
Definieren von Konstanten.

Aber, DSP_CR1_CLRSS_TO1 in deinem Beispiel ist wahrscheinlich falsch. 
Das umfast 4 Bits und vermutlich macht eine Definition als Bit-Maske 
oder mehrere individuelle Werte (maximal 8) mehr Sinn.

von Jan H. (janiiix3)


Lesenswert?

Mark schrieb:
> Im Prinzip kann man das so machen. enums oder defines sind typisch
> zum
> Definieren von Konstanten.
>
> Aber, DSP_CR1_CLRSS_TO1 in deinem Beispiel ist wahrscheinlich falsch.
> Das umfast 4 Bits und vermutlich macht eine Definition als Bit-Maske
> oder mehrere individuelle Werte (maximal 8) mehr Sinn.
Wie würdest du das machen?

von Mark (Gast)


Lesenswert?

Mehr als

>> Bit-Maske oder mehrere individuelle Werte

kann ich nicht sagen. Zu mehr müsste man die Funktion und Anwendung 
besser kennen.

von A. S. (Gast)


Lesenswert?

1
struct sConfigReg
2
{
3
    uint32 CLRSS_TO1 : 4;
4
    uint32 ClearSS1  : 1;
5
    uint32 ENVREF1   : 1;
6
    uint32 TC1       : 3;
7
};
8
9
...
10
/* Mapping einer Variable auf das HW-Register,  */
11
volatile struct sConfigReg ConfigReg @ 0x800200;
12
/* keine Ahnung, wie es bei Dir geht */
13
...
14
15
    ...
16
    ConfigReg.CLRSS_TO1 = 3;
17
    ConfigReg.ClearSS1  = 0;
18
    ...

von Jan H. (janiiix3)


Lesenswert?

Der Chip hat mega viele Register mit vielen unterschiedlichen Bits.
1
typedef struct
2
{
3
  /*
4
  *  DSP Control Register
5
  */
6
  uint32_t dspCRx[12];
7
  
8
  /* 
9
  *  DFE Control Register 
10
  */
11
  uint32_t dfeCRx[2]; 
12
  
13
  /* 
14
  *  DSP IRQ (Interrupt Control Mask) Register
15
  */
16
  uint32_t dspIRQx[2]; 
17
18
  /* 
19
  *  DSP Status Register
20
  */
21
  uint32_t dspSREGx[2]; 
22
  
23
  /*
24
  *  UART/SPI control register
25
  */
26
  uint32_t usREGx[3];
27
  
28
  /*
29
  *  DSP live event
30
  */
31
  uint32_t dspEVx[2];
32
  
33
}stpm32_t;
Kann man die Bitfelder auch auf Array´s anwenden?

von Jan H. (janiiix3)


Lesenswert?

Achim S. schrieb:
> ...
> /* Mapping einer Variable auf das HW-Register,  */
> volatile struct sConfigReg ConfigReg @ 0x800200;
> /* keine Ahnung, wie es bei Dir geht */

> [/c]
Was genau soll das bezwecken? Was macht '@'?

von Klaus (Gast)


Lesenswert?

Bei den PICs machen die das so:
1
#define NVMCON NVMCON
2
extern volatile uint16_t  NVMCON __attribute__((__sfr__));
3
__extension__ typedef struct tagNVMCONBITS {
4
  union {
5
    struct {
6
      uint16_t NVMOP:4;
7
      uint16_t :8;
8
      uint16_t NVMSIDL:1;
9
      uint16_t WRERR:1;
10
      uint16_t WREN:1;
11
      uint16_t WR:1;
12
    };
13
    struct {
14
      uint16_t NVMOP0:1;
15
      uint16_t NVMOP1:1;
16
      uint16_t NVMOP2:1;
17
      uint16_t NVMOP3:1;
18
    };
19
  };
20
} NVMCONBITS;
21
extern volatile NVMCONBITS NVMCONbits __attribute__((__sfr__));

MfG Klaus

von Jan H. (janiiix3)


Lesenswert?

Werde es jetzt so lösen..
1
enum dspCr11Bits
2
{
3
  DSP_CR11_AH_UP2    = 1UL<<0,
4
  DSP_CR11_OFA2    = 1UL<<12,
5
  DSP_CR11_OFAF2    = 1UL<<22,
6
};
7
8
enum dspCr12Bits
9
{
10
  DSP_CR12_AH_DOWN_2  = 1UL<<0,
11
  DSP_CR12_OFR2    = 1UL<<12,
12
  DSP_CR12_OFS2    = 1UL<<22,  
13
};
14
15
enum dfeCR1Bits
16
{
17
  DFE_CR1_ENV1    = 1UL<<0,
18
  DFE_CR1_ENC1    = 1UL<<16,
19
  DFE_CR1_GAIN1    = 1UL<<26,
20
};
21
22
enum dfeCR2Bits
23
{
24
  DFE_CR2_ENV2    = 1UL<<0,
25
  DFE_CR2_ENC2    = 1UL<<16,
26
  DFE_CR2_GAIN2    = 1UL<<26,
27
};
28
29
enum dspIRQ1Bits
30
{
31
  DSP_IRQ1_PH1_PH2_IRQ_CR    = 1UL<<0,
32
  DSP_IRQ1_PH2_IRQ_CR      = 1UL<<4,
33
  DSP_IRQ1_PH1_IRQ_CR      = 1UL<<12,
34
  DSP_IRQ1_C1_IRQ_CR      = 1UL<<20,
35
  DSP_IRQ1_V1_IRQ_CR      = 1UL<<24,
36
  DSP_IRQ1_TAMPER        = 1UL<<30,
37
};
38
39
enum dspIRQ2Bits
40
{
41
  DSP_IRQ2_PH1_PH2_IRQ_CR    = 1UL<<0,
42
  DSP_IRQ2_PH2_IRQ_CR      = 1UL<<4,
43
  DSP_IRQ2_PH1_IRQ_CR      = 1UL<<12,
44
  DSP_IRQ2_C1_IRQ_CR      = 1UL<<20,
45
  DSP_IRQ2_V1_IRQ_CR      = 1UL<<24,
46
  DSP_IRQ2_TAMPER        = 1UL<<30,
47
};
48
49
enum dspSR1Bits
50
{
51
  DSP_SR1_PH1_PH2_STATUS    = 1UL<<0,
52
  DSP_SR1_PH2_IRQ_STATUS    = 1UL<<4,
53
  DSP_SR1_PH1_IRQ_STATUS    = 1UL<<12,
54
  DSP_SR1_C1_IRQ_STATUS    = 1UL<<20,
55
  DSP_SR1_V1_IRQ_STATUS    = 1UL<<24,
56
  DSP_SR1_TAMPER        = 1UL<<30,
57
};
58
59
enum dspSR2Bits
60
{
61
  DSP_SR2_PH1_PH2_STATUS    = 1UL<<0,
62
  DSP_SR2_PH2_IRQ_STATUS    = 1UL<<4,
63
  DSP_SR2_PH1_IRQ_STATUS    = 1UL<<12,
64
  DSP_SR2_C1_IRQ_STATUS    = 1UL<<20,
65
  DSP_SR2_V1_IRQ_STATUS    = 1UL<<24,
66
  DSP_SR2_TAMPER        = 1UL<<30,
67
};
68
69
enum usREG1
70
{
71
  US_REG1_CRC_POLYNOMINAL      = 1UL<<0,
72
  US_REG1_NOISE_DETECTION_ENABLE  = 1UL<<8,
73
  US_REG1_BREAK_ON_ERROR      = 1UL<<9,
74
  US_REG1_CRC_ENABLE        = 1UL<<14,
75
  US_REG1_LSB_FIRST        = 1UL<<15,
76
  US_REG1_TIME_OUT        = 1UL<<16,
77
};
78
79
enum usREG2
80
{
81
  US_REG2_BAUD_RATE        = 1UL<<0,
82
  US_REG2_FRAME_DELAY        = 1UL<<16  
83
};
84
85
typedef struct
86
{
87
  /*
88
  *  DSP Control Register
89
  */
90
  struct 
91
  {
92
    enum dspCr1Bits    bitsReg1;
93
    enum dspCr2Bits    bitsReg2;
94
    enum dspCr3Bits    bitsReg3;
95
    enum dspCr4Bits    bitsReg4;
96
    enum dspCr5Bits    bitsReg5;
97
    enum dspCr6Bits    bitsReg6;
98
    enum dspCr7Bits    bitsReg7;
99
    enum dspCr8Bits    bitsReg8;
100
    enum dspCr9Bits    bitsReg9;
101
    enum dspCr10Bits  bitsReg10;
102
    enum dspCr11Bits  bitsReg11;
103
    enum dspCr12Bits  bitsReg12;
104
    uint32_t reg[12];
105
  }dspControl;
106
  
107
  
108
  /* 
109
  *  DFE Control Register 
110
  */
111
  struct
112
  {
113
    enum dfeCR1Bits    bitsReg1;
114
    enum dfeCR2Bits    bitsReg2;
115
    uint32_t reg[2];
116
  }dfeControl;
117
  
118
  /* 
119
  *  DSP IRQ Register
120
  */
121
  struct  
122
  {
123
    enum dspIRQ1Bits bitsReg1;
124
    enum dspIRQ2Bits bitsReg2;
125
    uint32_t reg[2];
126
  }dspInterrupt;
127
128
  /* 
129
  *  DSP Status Register
130
  */
131
  struct  
132
  {
133
    enum dspSR1Bits  bitsReg1;
134
    enum dspSR2Bits  bitsReg2;    
135
    uint32_t reg[2];
136
  }dspStatus;
137
  
138
  /*
139
  *  UART/SPI control register
140
  */
141
  struct  
142
  {
143
    enum usREG1  bitsReg1;
144
    enum usREG2  bitsReg2;
145
    uint32_t reg[3];
146
  }uartSpiControl;
147
  
148
  /*
149
  *  DSP live event
150
  */
151
  struct  
152
  {
153
    uint32_t reg[2];
154
  }dspLiveEvent;
155
  
156
}stpm32_t;

von A. S. (Gast)


Lesenswert?

Jan H. schrieb:
> Kann man die Bitfelder auch auf Array´s anwenden?

Ja.
1
struct sConfigReg ConfigReg[12];
 ist problemlos möglich.


Jan H. schrieb:
>> volatile struct sConfigReg ConfigReg @ 0x800200;
> Was genau soll das bezwecken? Was macht '@'?
naja, irgendwie muss der Compiler wissen, dass dieses Register an einer 
konkreten Stelle im Speicher steht. Dafür hat jeder Compiler seine 
eigene Notation.


Jan H. schrieb:
> struct
>   {
>     enum dfeCR1Bits    bitsReg1;
>     enum dfeCR2Bits    bitsReg2;
>     uint32_t reg[2];
>   }dfeControl

Bist Du sicher, dass Du in Deinem Code struct, Union und Bitfelder 
auseinander hälst? Ich fürchte, Du möchtest Das Array jeweils alternativ 
zu den enums, oder?

von Jan H. (janiiix3)


Lesenswert?

Achim S. schrieb:
> Jan H. schrieb:
>>> volatile struct sConfigReg ConfigReg @ 0x800200;
>> Was genau soll das bezwecken? Was macht '@'?
> naja, irgendwie muss der Compiler wissen, dass dieses Register an einer
> konkreten Stelle im Speicher steht. Dafür hat jeder Compiler seine
> eigene Notation.
Ich programmiere mit Atmel Studio 7, wie mache Ich das dort?

Achim S. schrieb:
> Jan H. schrieb:
>> struct
>>   {
>>     enum dfeCR1Bits    bitsReg1;
>>     enum dfeCR2Bits    bitsReg2;
>>     uint32_t reg[2];
>>   }dfeControl
>
> Bist Du sicher, dass Du in Deinem Code struct, Union und Bitfelder
> auseinander hälst? Ich fürchte, Du möchtest Das Array jeweils alternativ
> zu den enums, oder?
Ich möchte zu dem jeweiligen Register vom Chip die Bits haben. Daher 
habe Ich in jedem struct das dafür geschriebene "enum" mit in die 
jeweilige struct mit eingeführt.

von Jan H. (janiiix3)


Lesenswert?

Achim S. schrieb:
> Jan H. schrieb:
>> Kann man die Bitfelder auch auf Array´s anwenden?
>
> Ja.struct sConfigReg ConfigReg[12]; ist problemlos möglich.
Und wie?

von Eric B. (beric)


Lesenswert?

Achim S. schrieb:
>
1
> struct sConfigReg
2
> {
3
>     uint32 CLRSS_TO1 : 4;
4
>     uint32 ClearSS1  : 1;
5
>     uint32 ENVREF1   : 1;
6
>     uint32 TC1       : 3;
7
> };
8
...

Und dann hoffen/wissen ob der Compiler das Bitfield CLRSS_TO1 in den 
höchsten oder niedrigsten vier Bits im Register legt.

von Jan H. (janiiix3)


Lesenswert?

Eric B. schrieb:
> Achim S. schrieb:
>>> struct sConfigReg
>> {
>>     uint32 CLRSS_TO1 : 4;
>>     uint32 ClearSS1  : 1;
>>     uint32 ENVREF1   : 1;
>>     uint32 TC1       : 3;
>> };
> ...
> Und dann hoffen/wissen ob der Compiler das Bitfield CLRSS_TO1 in den
> höchsten oder niedrigsten vier Bits im Register legt.
Wie genau funktioniert das? Wenn ich 12 Arrayelemente habe?
Oder wird so das ganze "Array Struct" definiert? Dann hätten ja alle 12 
Arraymitglieder diese Zuordnung?

von A. S. (Gast)


Lesenswert?

Eric B. schrieb:
> Und dann hoffen/wissen ob der Compiler das Bitfield CLRSS_TO1 in den
> höchsten oder niedrigsten vier Bits im Register legt

Nein. Das stellt man sicher, indem man
- die Anleitung des Compilers dazu liest
- es exemplarisch ausprobiert
- es per assert überwacht

Und wer bitfelder nicht mag, weil sie nicht portabel sind, lässt es. 
Wobei ich das Argument bei den Registern eines Prozessors nicht 
wirklich stichhaltig finde.

Jan H. schrieb:
> Ja.struct sConfigReg ConfigReg[12]; ist problemlos möglich.
> Und wie?
Wenn du
1
     struct sConfigReg ConfigReg[12];
schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche 
Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).

Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.

Hast Du denn jeweils n gleiche Bitfelder?

von Helmut A. (Gast)


Lesenswert?

D

Achim S. schrieb:
> struct sConfigReg ConfigReg[12];
> schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche
> Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).
>
> Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.
>
> Hast Du denn jeweils n gleiche Bitfelder?
Das ist ja eben die Sache. Die Register haben alle andere Bits.
Dann klappt das so nicht oder?

von Jan H. (janiiix3)


Lesenswert?

Helmut A. schrieb:
> D
>
> Achim S. schrieb:
>> struct sConfigReg ConfigReg[12];
>> schreibst, werden 12 Register je 32 Bit angelegt, die alle die gleiche
>> Bitstruktur haben. (sofern max. 32Bit darin definiert wurden).
>>
>> Du kannst dann z.B. "ConfigReg[3].CLRSS_TO1 = 4;" schreiben.
>>
>> Hast Du denn jeweils n gleiche Bitfelder?
> Das ist ja eben die Sache. Die Register haben alle andere Bits.
> Dann klappt das so nicht oder?

Stehst du vor dem gleichen Problem?

von Heiko L. (zer0)


Lesenswert?

Achim S. schrieb:
> Wobei ich das Argument bei den Registern eines Prozessors nicht
> wirklich stichhaltig finde.

Naja, so ein volatiles Bitfeld kann glaube ich ganz, ganz übel nach 
hinten losgehen, was den generierten Code angeht. Wenn man einen 
uint32_t in Bits zerschnitten hat, soll der Compiler dann nur ein Byte 
davon updaten, wenn er kann oder immer alles auf einmal?

von Jan H. (janiiix3)


Lesenswert?

Heiko L. schrieb:
> Achim S. schrieb:
>> Wobei ich das Argument bei den Registern eines Prozessors nicht
>> wirklich stichhaltig finde.
>
> Naja, so ein volatiles Bitfeld kann glaube ich ganz, ganz übel nach
> hinten losgehen, was den generierten Code angeht. Wenn man einen
> uint32_t in Bits zerschnitten hat, soll der Compiler dann nur ein Byte
> davon updaten, wenn er kann oder immer alles auf einmal?
???
Wenn man es verODERt? Was geht das verloren?
Es soll nur das Bit gesetzt werden was gerade benötigt wird.

von Heiko L. (zer0)


Lesenswert?

1
struct S {
2
 uint32_t a : 8;
3
 uint32_t b : 24;
4
};
Man könnte z.B. auf die Idee kommen, einen Byte-Write daraus zu machen, 
wenn nur a geschrieben wird. Im Falle von Hardware-Registern kann es 
aber einen echten Unterschied machen, ob die restlichen Felder noch 
einmal mitgeschrieben werden oder nicht, bzw. können solche 1/4-Writes 
auf Register -Locations auch ganz verboten sein. Da muss man echt 
entweder seinem Compiler echt Vertrauen bzw. ihn im Griff haben oder 
Vorsichtig sein, was man mit solchen Variablen tut.

Zum Beispiel sollte
1
void f() {
2
 S s = *reg;
3
 s.a = 3;
4
 *reg = s;
5
}
relativ sicher sein, auch wenn man bei gcc das 
"-fstrict-volatile-bitfields" vergessen hat oder sich da mal wieder ein 
Fehler eingeschlichen hat.

von Jan H. (janiiix3)


Lesenswert?

Da bleibe Ich lieber bei den "enum´s" das macht glaube Ich weniger 
Fehler und ist später auch deutlich übersichtlicher (für mich 
jedenfalls)..

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.