Forum: Mikrocontroller und Digitale Elektronik mit Präprozessor ausrechnen und mit #warning ausgeben


von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Hallo,

ich schlag mich gerad mit Präprozessor rum :-)))
warum kann man kein Wert mit Präprozessor (MC C18 Compiler) anzeigen:
1
#if defined (SYS_FREQ) && (BAUD) 
2
3
#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
4
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
5
#define Error       (E_Baudrate - BAUD) / BAUD
6
7
      SPBRG = SPBRG_;
8
#if Error == 0
9
  #warning "baud rate error more Error %" 
10
#endif
11
#endif


Das wird mit Warning ausgegeben:
Warning [2105] "baud rate error more (200000L  / (4 * ((40000000L / 
(200000L  * 4) ) -1  + 1))  - 200000L ) / 200000L   %"


Ich benötige aber den ausgerechneten Wert und keine Formel.
Wie kann ich es machen???

Danke!

von yalu (Gast)


Lesenswert?

M.W. berechnet der Präprozesor nur die Ausdrücke in den #if- und
#elif-Direktiven. In allen anderen Fällen macht er lediglich Text-
ersetzung (Expansion) und das auch nur außerhalb von Präprozessor-
direktiven (also im normalen C-Code).

Was der Compiler im #warning-Text ersetzt, ist Compiler-spezifisch, da
die #warning-Direktive nicht zum Standard gehört. Bei der verwandten
(und standardisierten) #error-Direktive wird nichts expandiert, schon
gar nicht, wenn Anführungszeichen wie in deinem Beispiel verwendet
werden.

Dass beim C18-Compiler das "Error" in der #warning expandiert wird, ist
also schon verwunderlich. Dass der Ausdruck auch noch ausgewertet wird,
ist einfach zuviel verlangt ;-)

Es sei denn, der C18-Compiler hat ein spezielles Feature, das dies
erlaubt. Das sollte dann aber im Handbuch beschreiben sein.

von (prx) A. K. (prx)


Lesenswert?

@yalu: Die Präprozessorersetzungsregeln sind beim C18 ohnehin nicht ganz 
korrekt implementiert. Merkt man, wenn man sich vergeblich an GLUE / ## 
Makros für IO-Ports abkämpft und erst hinterher in die Release-Notes 
reinschaut.

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

mir fällt nicht mehr ein, so habe ich es gemacht
1
#if defined (SYS_FREQ) && (BAUD) 
2
3
#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
4
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
5
#define Error       (E_Baudrate - BAUD) / BAUD
6
7
      SPBRG = SPBRG_;
8
9
#if Error == 0
10
  //no warning
11
#elif (Error <= 0.1) && (Error >= -0.1)
12
  #warning "BAUT RATE error less than or equal 0.1 %"
13
14
#elif (Error <= 0.2) && (Error >= -0.2)
15
  #warning "BAUT RATE error less than or equal 0.2 %"
16
17
#elif (Error <= 0.3) && (Error >= -0.3)
18
  #warning "BAUT RATE error less than or equal 0.3 %"
19
20
#elif (Error <= 0.4) && (Error >= -0.4)
21
  #warning "BAUT RATE error less than or equal 0.4 %"
22
23
#elif (Error <= 0.5) && (Error >= -0.5)
24
  #warning "BAUT RATE error less than or equal 0.5 %"
25
26
#elif (Error <= 0.6) && (Error >= -0.6)
27
  #warning "BAUT RATE error less than or equal 0.6 %"
28
29
#elif (Error <= 0.7) && (Error >= -0.7)
30
  #warning "BAUT RATE error less than or equal 0.7 %"
31
32
#elif (Error <= 0.8) && (Error >= -0.8)
33
  #warning "BAUT RATE error less than or equal 0.8 %"
34
35
#elif (Error <= 0.9) && (Error >= -0.9)
36
  #warning "BAUT RATE error less than or equal 0.9 %"
37
38
#elif (Error <= 1) && (Error >= -1)
39
  #warning "BAUT RATE error less than or equal 1 %"
40
41
#elif (Error <= 1.5) && (Error >= -1.5)
42
  #warning "BAUT RATE error less than or equal 1.5 %"
43
44
#elif (Error <= 100) && (Error >= -100)
45
  #error "BAUT RATE error greater than 1.5 %"
46
#endif
47
#endif

von Simon K. (simon) Benutzerseite


Lesenswert?

Wofür musst du den Fehler denn so genau wissen? Schreib doch einfach, 
dass er zu groß ist ;)

Es heißt übrigens baudrate und nicht baut rate.

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

>Es heißt übrigens baudrate und nicht baut rate.
Ja die [Ratte], stimmt :-) gar nicht gesehen

>Wofür musst du den Fehler denn so genau wissen?
ich wollte, aber genauer wissen ;-)

Jetzt aber:
1
#if defined (SYS_FREQ) && (BAUD) 
2
3
#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
4
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
5
#define Error       (E_Baudrate - BAUD) / BAUD   // +1.27 testen
6
7
      SPBRG = SPBRG_;
8
9
#if Error == 0
10
  //no warning
11
#elif (Error <= 0.1) && (Error >= -0.1)
12
  #warning "Baudrate error less than or equal 0.1 %"
13
14
#elif (Error <= 0.2) && (Error >= -0.2)
15
  #warning "Baudrate error less than or equal 0.2 %"
16
17
#elif (Error <= 0.3) && (Error >= -0.3)
18
  #warning "Baudrate error less than or equal 0.3 %"
19
20
#elif (Error <= 0.4) && (Error >= -0.4)
21
  #warning "Baudrate error less than or equal 0.4 %"
22
23
#elif (Error <= 0.5) && (Error >= -0.5)
24
  #warning "Baudrate error less than or equal 0.5 %"
25
26
#elif (Error <= 0.6) && (Error >= -0.6)
27
  #warning "Baudrate error less than or equal 0.6 %"
28
29
#elif (Error <= 0.7) && (Error >= -0.7)
30
  #warning "Baudrate error less than or equal 0.7 %"
31
32
#elif (Error <= 0.8) && (Error >= -0.8)
33
  #warning "Baudrate error less than or equal 0.8 %"
34
35
#elif (Error <= 0.9) && (Error >= -0.9)
36
  #warning "Baudrate error less than or equal 0.9 %"
37
38
#elif (Error <= 1) && (Error >= -1)
39
  #warning "Baudrate error less than or equal 1 %"
40
41
#elif (Error <= 1.5) && (Error >= -1.5)
42
  #warning "Baudrate error less than or equal 1.5 %"
43
44
#elif (Error > 1.5) || (Error < -1.5)
45
  #error "Baudrate error greater than 1.5 %"
46
#endif
47
#endif

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Man muss F_CPU bzw. SYS_FREQ und BAUD als zB 1000000 bzw. 9600 definen 
anstatt 1000000ul bzw. 9600ul.

Der Präprozessor kann mut dem L und UL nix anfangen. Stattdessen muss 
man dann die C-Ausdrücke passend casten mittels (unsigned long) et al.
1
///...
2
3
#if (F_CPU % (PRESCALE * IRQS)) != 0 
4
#   warning Timer2 arbeitet ungenau
5
#endif
6
7
///...
8
9
static void 
10
timer2_init (void)
11
{
12
    // Mode #2 (CTC) und PRESCALE=8
13
    TCCR2A = (1 << WGM21);
14
    TCCR2B = (1 << CS21);
15
16
    // OutputCompare für gewünschte Timer2 Frequenz
17
    OCR2A = (unsigned short) ((unsigned long) F_CPU / PRESCALE / IRQS-1);
18
19
    // OutputCompare-Interrupt A für Timer 2
20
    TIMSK2 = (1 << OCIE2A);
21
}

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

>^Der Präprozessor kann mut dem L und UL nix anfangen.
Bei mir schon sonst würde es kein Warning geben:
1
#define Error       (E_Baudrate - BAUD) / BAUD  +1.47
Warning [2105] "Baudrate error less than or equal 1.5 %"

oder
1
#define Error       (E_Baudrate - BAUD) / BAUD  +1.57
Error [1099] "Baudrate error greater than 1.5 %"

Mein Problem war eigentlich diesen Wert "Error" beim Warning auszugeben!

von Hermann U. (Firma: www.pcb-devboards.de) (gera82)


Lesenswert?

Das geht jetzt:
1
/** Baudrate & Error calculation *****************************************/
2
#if defined (SYS_FREQ) && defined (BAUD) 
3
4
#define SPBRG_        (SYS_FREQ/ (BAUD * 4) ) -1 
5
#define E_Baudrate_   SYS_FREQ / (4 * (SPBRG_ + 1)) 
6
#define Error         (10000 *(E_Baudrate_ - BAUD)) / BAUD 
7
8
9
 
10
#if Error == 0
11
  //no warning
12
#elif (Error <= 10) && (Error >= -10)
13
  #warning "Baudrate error less than or equal 0.1 %"
14
15
#elif (Error <= 20) && (Error >= -20)
16
  #warning "Baudrate error less than or equal 0.2 %"
17
18
#elif (Error <= 30) && (Error >= -30)
19
  #warning "Baudrate error less than or equal 0.3 %"
20
21
#elif (Error <= 40) && (Error >= -40)
22
  #warning "Baudrate error less than or equal 0.4 %"
23
24
#elif (Error <= 50) && (Error >= -50)
25
  #warning "Baudrate error less than or equal 0.5 %"
26
27
#elif (Error <= 60) && (Error >= -60)
28
  #warning "Baudrate error less than or equal 0.6 %"
29
30
#elif (Error <= 70) && (Error >= -70)
31
  #warning "Baudrate error less than or equal 0.7 %"
32
33
#elif (Error <= 80) && (Error >= -80)
34
  #warning "Baudrate error less than or equal 0.8 %"
35
36
#elif (Error <= 90) && (Error >= -90)
37
  #warning "Baudrate error less than or equal 0.9 %"
38
39
#elif (Error <= 100) && (Error >= -100)
40
  #warning "Baudrate error less than or equal 1 %"
41
42
#elif (Error <= 150) && (Error >= -150)
43
  #warning "Baudrate error less than or equal 1.5 %"
44
45
#elif (Error > 150) || (Error < -150)
46
  #error "Baudrate error greater than 1.5 %"
47
#endif
48
#endif

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.