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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Naj H. (janiiix3)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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. (achs)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Naj H. (janiiix3)


Bewertung
0 lesenswert
nicht 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)..

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.