www.mikrocontroller.net

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


Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich schlag mich gerad mit Präprozessor rum :-)))
warum kann man kein Wert mit Präprozessor (MC C18 Compiler) anzeigen:
#if defined (SYS_FREQ) && (BAUD) 

#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
#define Error       (E_Baudrate - BAUD) / BAUD

      SPBRG = SPBRG_;
#if Error == 0
  #warning "baud rate error more Error %" 
#endif
#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!

Autor: yalu (Gast)
Datum:

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

Autor: A. K. (prx)
Datum:

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

Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mir fällt nicht mehr ein, so habe ich es gemacht
#if defined (SYS_FREQ) && (BAUD) 

#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
#define Error       (E_Baudrate - BAUD) / BAUD

      SPBRG = SPBRG_;

#if Error == 0
  //no warning
#elif (Error <= 0.1) && (Error >= -0.1)
  #warning "BAUT RATE error less than or equal 0.1 %"

#elif (Error <= 0.2) && (Error >= -0.2)
  #warning "BAUT RATE error less than or equal 0.2 %"

#elif (Error <= 0.3) && (Error >= -0.3)
  #warning "BAUT RATE error less than or equal 0.3 %"

#elif (Error <= 0.4) && (Error >= -0.4)
  #warning "BAUT RATE error less than or equal 0.4 %"

#elif (Error <= 0.5) && (Error >= -0.5)
  #warning "BAUT RATE error less than or equal 0.5 %"

#elif (Error <= 0.6) && (Error >= -0.6)
  #warning "BAUT RATE error less than or equal 0.6 %"

#elif (Error <= 0.7) && (Error >= -0.7)
  #warning "BAUT RATE error less than or equal 0.7 %"

#elif (Error <= 0.8) && (Error >= -0.8)
  #warning "BAUT RATE error less than or equal 0.8 %"

#elif (Error <= 0.9) && (Error >= -0.9)
  #warning "BAUT RATE error less than or equal 0.9 %"

#elif (Error <= 1) && (Error >= -1)
  #warning "BAUT RATE error less than or equal 1 %"

#elif (Error <= 1.5) && (Error >= -1.5)
  #warning "BAUT RATE error less than or equal 1.5 %"

#elif (Error <= 100) && (Error >= -100)
  #error "BAUT RATE error greater than 1.5 %"
#endif
#endif

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

Bewertung
0 lesenswert
nicht 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:
#if defined (SYS_FREQ) && (BAUD) 

#define SPBRG_      (SYS_FREQ/ (BAUD * 4) ) -1 
#define E_Baudrate  BAUD / (4 * (SPBRG_ + 1)) 
#define Error       (E_Baudrate - BAUD) / BAUD   // +1.27 testen

      SPBRG = SPBRG_;

#if Error == 0
  //no warning
#elif (Error <= 0.1) && (Error >= -0.1)
  #warning "Baudrate error less than or equal 0.1 %"

#elif (Error <= 0.2) && (Error >= -0.2)
  #warning "Baudrate error less than or equal 0.2 %"

#elif (Error <= 0.3) && (Error >= -0.3)
  #warning "Baudrate error less than or equal 0.3 %"

#elif (Error <= 0.4) && (Error >= -0.4)
  #warning "Baudrate error less than or equal 0.4 %"

#elif (Error <= 0.5) && (Error >= -0.5)
  #warning "Baudrate error less than or equal 0.5 %"

#elif (Error <= 0.6) && (Error >= -0.6)
  #warning "Baudrate error less than or equal 0.6 %"

#elif (Error <= 0.7) && (Error >= -0.7)
  #warning "Baudrate error less than or equal 0.7 %"

#elif (Error <= 0.8) && (Error >= -0.8)
  #warning "Baudrate error less than or equal 0.8 %"

#elif (Error <= 0.9) && (Error >= -0.9)
  #warning "Baudrate error less than or equal 0.9 %"

#elif (Error <= 1) && (Error >= -1)
  #warning "Baudrate error less than or equal 1 %"

#elif (Error <= 1.5) && (Error >= -1.5)
  #warning "Baudrate error less than or equal 1.5 %"

#elif (Error > 1.5) || (Error < -1.5)
  #error "Baudrate error greater than 1.5 %"
#endif
#endif

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

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

///...

#if (F_CPU % (PRESCALE * IRQS)) != 0 
#   warning Timer2 arbeitet ungenau
#endif

///...

static void 
timer2_init (void)
{
    // Mode #2 (CTC) und PRESCALE=8
    TCCR2A = (1 << WGM21);
    TCCR2B = (1 << CS21);

    // OutputCompare für gewünschte Timer2 Frequenz
    OCR2A = (unsigned short) ((unsigned long) F_CPU / PRESCALE / IRQS-1);

    // OutputCompare-Interrupt A für Timer 2
    TIMSK2 = (1 << OCIE2A);
}

Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

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

oder
#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!

Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht jetzt:
/** Baudrate & Error calculation *****************************************/
#if defined (SYS_FREQ) && defined (BAUD) 

#define SPBRG_        (SYS_FREQ/ (BAUD * 4) ) -1 
#define E_Baudrate_   SYS_FREQ / (4 * (SPBRG_ + 1)) 
#define Error         (10000 *(E_Baudrate_ - BAUD)) / BAUD 


 
#if Error == 0
  //no warning
#elif (Error <= 10) && (Error >= -10)
  #warning "Baudrate error less than or equal 0.1 %"

#elif (Error <= 20) && (Error >= -20)
  #warning "Baudrate error less than or equal 0.2 %"

#elif (Error <= 30) && (Error >= -30)
  #warning "Baudrate error less than or equal 0.3 %"

#elif (Error <= 40) && (Error >= -40)
  #warning "Baudrate error less than or equal 0.4 %"

#elif (Error <= 50) && (Error >= -50)
  #warning "Baudrate error less than or equal 0.5 %"

#elif (Error <= 60) && (Error >= -60)
  #warning "Baudrate error less than or equal 0.6 %"

#elif (Error <= 70) && (Error >= -70)
  #warning "Baudrate error less than or equal 0.7 %"

#elif (Error <= 80) && (Error >= -80)
  #warning "Baudrate error less than or equal 0.8 %"

#elif (Error <= 90) && (Error >= -90)
  #warning "Baudrate error less than or equal 0.9 %"

#elif (Error <= 100) && (Error >= -100)
  #warning "Baudrate error less than or equal 1 %"

#elif (Error <= 150) && (Error >= -150)
  #warning "Baudrate error less than or equal 1.5 %"

#elif (Error > 150) || (Error < -150)
  #error "Baudrate error greater than 1.5 %"
#endif
#endif

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.