"expression must have a constant value" umgehen

OP #2420884
Lesenswert?
• ▲
▼
Hallo!

Momentan arbeite ich als Praktikum in einem Betrieb, der elektronische 
Vorschaltgeräte im hochleistungsbetrieb baut und ich bin für die 
erweiterung der Firmware zuständig.

Ich programmiere einen PIC18F458 mit C. Intern läuft alles über CAN.

Meine Aufgabe war es erst, die 7 transmit (TX) und die 7 reicive (RX) 
messages so zu erweitern, dass zukünftig 16 Geräte gleichzeitig über 
einen Bus betrieben werden können, wobei über einen dreh-codierschalter 
eine eindeutige ID zugewiesen werden kann.

Mit den TX habe ich es scho geschafft.
Auszüge:
im header:
1
#define TX1_DLC            8
2
#define TX1_ID_0              0x030
dazu beim initialisieren:
1
   if(DIP_POS == 0x0) //device 1
2
    {
3
      TX1_ID = TX1_ID_0;
4
      TX2_ID = TX2_ID_0;
5
      TX3_ID = TX3_ID_0;
6
      TX4_ID = TX4_ID_0;
7
      TX5_ID = TX5_ID_0;
8
      TX6_ID = TX6_ID_0;
9
      TX7_ID = TX7_ID_0;
10
      TX8_ID = TX8_ID_0;
11
    }
12
   else if(DIP_POS == 0x1) //device 2
13
    {
14
      TX1_ID = TX1_ID_0 + 0x040;
15
      TX2_ID = TX2_ID_0 + 0x040;
16
      TX3_ID = TX3_ID_0 + 0x040;
17
      TX4_ID = TX4_ID_0 + 0x040;
18
      TX5_ID = TX5_ID_0 + 0x040;
19
      TX6_ID = TX6_ID_0 + 0x040;           
20
      TX7_ID = TX7_ID_0 + 0x040;
21
      TX8_ID = TX8_ID_0 + 0x040;     
22
    }
und so weiter...
dies funktioniert einwandfrei. Deshalb wollte ich das selbe mit den RX 
machen.
header:
1
  #define RX1_DLC          3
2
  #define RX1_ID_0          0x010  
3

4
  #define CAN_RX_MSG1        RX1_DLC + (RX1_ID&0x007)*(unsigned short)0x2000 + (RX1_ID>>3)*(unsigned long)0x10000
Nun wird aber je nachdem welche Message in empfang genommen wird, beim 
switch ein anderer case ausgelöst:
1
      switch(SJA_FRAME_INFO_AND_ID_SFF)
2
      {
3
         case CAN_RX_MSG1:  
4
               ...
5
         break;

Nun kommt aber bei jedem case die fehlermeldung:
1
Error[Pe028]: expression must have a constant value

Jetzt wüsste ich gerne:
was kann ich tun, damit es funktioniert, ohne dass ich den switch 
weglassen muss.

Hoffe jemand kann mir helfen und ich hoffe meine Angaben reichen für das 
Verständnis meiner Frage.

MFG
-Ben
#2420892
Lesenswert?
• ▲
▼
Ben Hub schrieb:
>   #define CAN_RX_MSG1        RX1_DLC + (RX1_ID&0x007)*(unsigned
> short)0x2000 + (RX1_ID>>3)*(unsigned long)0x10000   [/c]

Bisschen Ästhetik: (unsigned long)0x2000 == 0x2000uL

> was kann ich tun, damit es funktioniert, ohne dass ich den switch
> weglassen muss.

Wie der Compiler schon sagt ist als "case" Ausdruck nur eine Konstante 
erlaubt. Da die RX1_xxx Dinger keine Konstanten sondern I/O-Register 
sind geht das so nicht.
OP #2420928
Lesenswert?
• ▲
▼
A. K. schrieb:
> Wie der Compiler schon sagt ist als "case" Ausdruck nur eine Konstante
>
> erlaubt. Da die RX1_xxx Dinger keine Konstanten sondern I/O-Register
>
> sind geht das so nicht.

ja das is mir klar.

Davor war ja RXx_ID konstant belegt. Jetzt ändert sich der Wert je nach 
Schalterstellung.
Meine Frage bleibt daher weiterhin offen: Kann ich da noch irgendwas 
machen, ohne den switch zu löschen? Oder was für möglichkeiten habe ich 
überhaupt? (Ich bin noch recht amateurhaft im Bezug auf microcontroller 
und programmierung :x )
Gast #2420947
Lesenswert?
• ▲
▼
Du hast Dir eine Makroberechnung programmiert.

Meine Kollege sind von so etwas ebenfalls schwer begeistert. Ich finde 
sie Verwirrung stiftend. Deshalb halte ich mich mit so etwas zurück.

Der Preprozessor ersetzt Deine Berechnung stumpf und setzt es in die 
case-Anweisung.

Versuche Dein Define einem anderen vorher zuzuweisen, wie

Ben Hub schrieb:
> #define RX1_ID_0          0x010
>
>
>
>   #define CAN_RX_MSG1        RX1_DLC + (RX1_ID&0x007)*(unsigned short)0x2000 + 
(RX1_ID>>3)*(unsigned long)0x10000

#define CAN_RX_MSG_COPY CAN_RX_MSG1


switch( ...

case CAN_RX_MSG_COPY:

wenn das auch nicht geht, dann mußt Du es halt ausrechnen und Dich 
festlegen. D. h. Nein es gibt dann keine andere Möglichkeit.

...

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.