Forum: Mikrocontroller und Digitale Elektronik enum Konstanten


von Remo H. (remoeggel)


Lesenswert?

Hallo Zusammen

Ich habe folgender code in einer Header Datei test.h:
1
enum SWC_RH_SWButtons
2
{
3
  CAN_ID      = 0x131726C,
4
  DataByte    = 7,
5
  NoKEY      = 0x3F,
6
  Bit_KEY_Rev    = 0,
7
  Bit_KEY_Fwd    = 1,
8
  Bit_KEY_VolDn  = 2,
9
  Bit_KEY_VolUp  = 3,
10
  Bit_KEY_Yes    = 4,
11
  Bit_KEY_No    = 5
12
};

Nun möchte ich in der main.c folgendes machen:
1
MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons.CAN_ID),    // Filter 0
2
MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons.CAN_ID),    // Filter 1

Leider sagt mir Atmel Studio 7 beim compillieren:
'SWC_RH_SWButtons' undeclared here (not in a function)

Was habe ich nicht beachtet?
Wie kann ich das Lösen, damit ich die "Konstanten" in einer Gruppe zur 
verfügung habe?

Danke und freundliche Grüsse
Remo

von holger (Gast)


Lesenswert?

>Was habe ich nicht beachtet?

enums sind keine Strukturen.

von Remo H. (remoeggel)


Lesenswert?

Hallo Holger

Kannst du mir einen Tipp geben, wie ich da mit einer Struktur lösen 
kann?
Hab dies eben auch schon versucht, bin aber nicht weiter gekommen.

Gruss
Remo

von Remo H. (remoeggel)


Lesenswert?

...ein enum ist doch eine Aufzählung von Konstanten oder nicht?

von Dr. Sommer (Gast)


Lesenswert?

Remo H. schrieb:
> MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons.CAN_ID)

Einfach nur:
MCP2515_FILTER_EXTENDED(CAN_ID)

Ein enum definiert einfach nur eine Reihe "globalen" Konstanten.

In C++ kannst du "enum class" statt "enum" schreiben und dann:

MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons::CAN_ID),

von laspalmas (Gast)


Lesenswert?

meinst du sowas? macht wahrscheinlich kein Sinn aber was solls.

typedef struct
{
   int CAN_ID;
   char DataByte;
   char NoKEY;
   char Bit_KEY_Rev;
   char Bit_KEY_Fwd;
   char Bit_KEY_VolDn;
   char Bit_KEY_VolUp;
   char Bit_KEY_Yes;
   char Bit_KEY_No;
}SRSB;

SRSB SWC_RH_SWButtons =
{
    0x131726C,
    7,
    0x3F,
    0,
    1,
    2,
    3,
    4,
    5
};

MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons.CAN_ID),    // Filter 0
MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons.CAN_ID),    // Filter 1

viel Glück.
Gruß
Laspalmas

von Remo H. (remoeggel)


Lesenswert?

Hallo Laspalmas

Genau, aber ohne dass ich die Konsatnten Werte in einem 2. Schritt 
übergeben muss.

Am liebsten wäre mir die Folgende Struktur:
1
struct
2
{
3
  const uint32_t CAN_ID = 0x131726C;
4
  
5
  struct
6
  {
7
    struct  
8
    {
9
      const uint8_t DataByte       = 8;
10
      const uint8_t Bit_KEY_VolUp  = 0;
11
      //usw.
12
    }RH;
13
    
14
    struct  
15
    {
16
      const uint8_t DataByte = 7;
17
      const uint8_t Bit_Key1 = 0;
18
      //usw.
19
    }LH;
20
    
21
  }SW_Buttons;
22
  
23
}SWC_Module;

Kann ich nicht quasi eine konstante Struktur haben und dieser ja auch 
gleich den konstanten Wert mitgeben (wie bei meinem beispiel oben)?

Grüsse
Remo

: Bearbeitet durch User
von c+++ (Gast)


Lesenswert?

in C++ wäre es:
MCP2515_FILTER_EXTENDED(SWC_RH_SWButtons::CAN_ID),    // Filter 0

Nur leider sind enums in Konstanten kacke in C, namespaces (Gruppierung) 
gibt es erst in C++.

von A. S. (Gast)


Lesenswert?

Nimm  SWC_RH_SWButtons als Präfix, also

SWC_RH_SWButtons_CAN_ID  = 0x131726C
SWC_RH_SWButtons_DataByte    = 7,
...

von Patrick C. (pcrom)


Lesenswert?

Weiteres noch nicht genenntes problem : in eine enum structure kann 
jeder wert nur einmal vorkommen.

Also der 'normale' weg in C um globale konstanten zu benutzen :
1) const int databyte 7;
2) #define DATABYTE 7

Braucht nicht unbedingt mit BUCHSTABEN aber wird meistens gemacht bei 
#define.

Wenn moeglich ist es am besten 1) zu benutzen, wenn nicht moeglich dann 
2)
Mit struct koennte es auch wie beschrieben durch laspalmas aber wie 
schon gesagt nicht uebersichtlich.

von Remo H. (remoeggel)


Lesenswert?

Hallo Zusammen

Sehr schade. :-(
Dann werde ich das halt vergessen müssen und mich mit langen 
unstrukturierten, unhandlichen Konstantennamen rumschlagen müssen.

Freundliche Grüsse
Remo

von Johannes S. (Gast)


Lesenswert?

so ein enum ist ja auch nicht dazu gedacht Konstanten für eine 
kunterbunte Struktur mit verschiedenen Feldern zu halten.
Typisches Beispiel ist ja eine Variable 'Ampelfarben' die dann 'rot, 
gelb, grün' sein kann. In C kann man das mit einem enum so lesbar machen 
das man sofort erkennt was der Autor möchte und ein smarter Editor kann 
die passenden Möglichkeiten bei einer Zuweisung anbieten.
In C ist das aber kein echter Typ und Ampelfarbe=99 oder =Katze ist für 
den Compiler auch ok. In C++ wurde das stufenweise verbessert und 
typsicher gemacht.
Für dein Beispiel wären also je Feldtyp eigene enums angebracht, eines 
für die CAN IDs und eines für die verschiedenen Funktionsbits.

von Remo H. (remoeggel)


Lesenswert?

Was spricht eigentlich gegen C++?
Wenn ich solche sachen nutzen möchte?
Handle ich mir da sonstiges unnützes zeugs ein, das den Speicher unnötig 
verbraucht?

von Johannes S. (Gast)


Lesenswert?

dagegen spricht nichts solange man die 'teuren' Features wie Exceptions 
und RTTI weglässt. Aber das Thema ist eine ewige Diskussion hier.
Trotzdem sind enum in C auch brauchbar weil sie den Code eben besser 
lesbar machen und Intellisense weiss was es dir anbieten kann.

Und die CAN_ID kann ja sicher eine von mehreren sein. Dann würde ich das 
enum nutzen den IDs schönere Namen zu geben, also sowas wie 
'ID_SEND_BUTTONSTATE' oder sowas. Im enum kann man den Wert dieser IDs 
setzen, das war in deinem Beispiel ja auch schon drin. Nur eben ein enum 
alleine für IDs und nicht alles in einem.

von Remo H. (remoeggel)


Lesenswert?

Ich möchte das ganze aber eben in blöcke gruppieren, sonst kann ich ja 
gleich mit #defines arbeiten.

von Johannes S. (Gast)


Lesenswert?

Defines sind aber reine Konvention und ermöglichen höchstens sowas wie 
'#define CAN_ID_xy', da kann Intellisense nicht helfen. Bei enums sind 
die passenden Möglichkeiten eben in einer Gruppe aufgezählt, das ist 
schon etwas anderes.

von Remo H. (remoeggel)


Lesenswert?

Ja, aber nicht so Gruppiert wie ich es möchte und es auch sinn macht.

von Johannes S. (Gast)


Lesenswert?

dann wirfst du wohl immer noch Strukturen und enums durcheinander. Ein 
enum hat nix mit einer Struktur zu tun.
1
typedef enum  {
2
  ID1 = 0x12345678,
3
  ID2,
4
  ID3
5
} CAN_ID;
6
7
typedef enum {
8
  cat,
9
  dog
10
} ANIMAL;
11
12
13
void foo() {
14
  CAN_ID id;
15
16
  id = ID1;
17
  id = CAN_ID::ID1; // nur in cpp
18
  id = 99;
19
  id = dog;
20
}

in C ist obiges ok, in cpp (gcc c++11) bekommt man Fehler:
error: invalid conversion from 'int' to 'CAN_ID' [-fpermissive]
error: cannot convert 'ANIMAL' to 'CAN_ID' in assignment

das ist doch schon Grund genug den cpp zu benutzen.

von Remo H. (remoeggel)


Lesenswert?

Ok. Dann müsste ich also eine Struktur haben mit Konstanten.
Dies geht aber i C auch nicht, ohne kompliziertes und unübersichtliches 
zuweisen.

von Rolf M. (rmagnus)


Lesenswert?

Patrick C. schrieb:
> Weiteres noch nicht genenntes problem : in eine enum structure kann
> jeder wert nur einmal vorkommen.
>
> Also der 'normale' weg in C um globale konstanten zu benutzen :
> 1) const int databyte 7;
> 2) #define DATABYTE 7

1) definiert eigentlich keine echte Konstante, sondern nur eine 
Variable, die man nicht ändern soll.

Remo H. schrieb:
> Hallo Zusammen
>
> Sehr schade. :-(
> Dann werde ich das halt vergessen müssen und mich mit langen
> unstrukturierten, unhandlichen Konstantennamen rumschlagen müssen.

Das ist in C immer ein bisschen das Problem. In C++ gibt's da einiges 
mehr wie Klassen und Namespaces, um solche Sachen zusammenzufassen. Aber 
ist es denn eigentlich so ein großer Unterschied, ob du schreibst:

Remo H. schrieb:
> SWC_RH_SWButtons.CAN_ID

oder

SWC_RH_SWButtons_CAN_ID?

von Patrick C. (pcrom)


Lesenswert?

Rolf M. schrieb:
>> Weiteres noch nicht genenntes problem : in eine enum structure kann
>> jeder wert nur einmal vorkommen.
>>
>> Also der 'normale' weg in C um globale konstanten zu benutzen :
>> 1) const int databyte 7;
>> 2) #define DATABYTE 7
>
> 1) definiert eigentlich keine echte Konstante, sondern nur eine
> Variable, die man nicht ändern soll.

Stimmt, aber meiner meinung ist dies meistens besser weil man bessere 
compiler-meldungen bekommt. Nur wenn man die constante benutzen woll als 
zB "int channels[MAXCHANNELS];" benutze ich #define, oder bei strings um 
memory zu besparen

von A. S. (Gast)


Lesenswert?

Das Problem bei Dir ist doch, dass die konstanten so überhaupt nicht 
gruppiert werden sollten. C bewährt dich vor einem gefährlichen Weg, 
der in C++ mit Guruvoodoo zwar möglich, aber katastrophal wäre.

Du solltest Dich mit Typisierung vertraut machen.

Die ID, Anzahl der Bytes und bestimmte Bedeutungen der nutzbytes in ein 
konstantenfeld zu quetschen ist wirklich schräg, weil sie thematisch 
nichts miteinander zu tun haben.

von guardian of memory (Gast)


Lesenswert?

Rolf M. schrieb:
> 1) definiert eigentlich keine echte Konstante, sondern nur eine
> Variable, die man nicht ändern soll.

und wie sieht es mit der Speicherbelegung aus? ;)

Da kommen jetzt solche schrecklichen Gedanken auf:

Patrick C. schrieb:
> benutze ich #define, oder bei strings um
> memory zu besparen

:(

von Stefan F. (Gast)


Lesenswert?

> Was spricht eigentlich gegen C++?
> Wenn ich solche sachen nutzen möchte?

Nichts. Das Arduino Framework macht uns vor, dass es durchaus Sinn 
machen kann, nur Teile von C++ zu verwenden.

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.