Forum: Mikrocontroller und Digitale Elektronik Umstig von PN auf VAR Studio - Baudrate Fehler


von Matthias R. (matsch)


Lesenswert?

Moin und Hallo,
ich habe ein Projekt bisher immer mit 'Programmers Notepad' (PN) 
bearbeitet, und aus dem PN auch die Hex Files erzeugt (Tool/[WinAVR] 
Make All).

Nun habe ich das gleiche Projekt in AVR Studio 4 angelegt. Unter den 
Projekt Options habe ich meine F_CPU auf 11059200 Hz eingestellt.

Die Baudrate berechne ich wie im Tutorial beschrieben:
1
#ifndef F_CPU
2
   #define F_CPU 11059200L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
3
#endif
4
 
5
#define UART_BAUD_RATE 19200L 
6
#define UBRR_VAL (F_CPU+UART_BAUD_RATE*8)/(UART_BAUD_RATE*16)-1)    // clever runden
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))                  // Reale Baudrate
8
#define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD_RATE-1000)        // Fehler in Promille
9
 
10
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
11
   #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
12
#endif
Wenn ich nun ein Build erstellen möchte, bekomme ich diesen Fehler:
1
../src/prjdef.c:267:41: warning: the right operand of "<" changes sign when promoted
2
../src/prjdef.c:268:4: error: #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
3
make: *** [prjdef.o] Error 1
4
Build failed with 1 errors and 1 warnings...
Der Fehler zeigt auf die Baudrate Berechnung.

Der Fehler ist beim Kompilieren über PN nicht aufgetreten. Warum meldet 
das AVR Studio diesen Fehler, und wie bekomme ich ihn weg?
Hat jemand einen Tipp?
Gruß
matsch

von Matthias R. (matsch)


Lesenswert?

Hat keiner eine Idee?

Wenn ich die Fehlerabfrage auskommentiere läuft das Programm 
einwandfrei. Das kann doch aber nicht der Sinn sein, oder?

Gruß
Matsch

von Hc Z. (mizch)


Lesenswert?

Hier
1
#define UBRR_VAL (F_CPU+UART_BAUD_RATE*8)/(UART_BAUD_RATE*16)-1)
fehlt eine „(“.  Das müsste aber später eine andere Fehlermeldung geben, 
womit sich die Frage stellt, ob Du uns wirklich Deinen aktuellen Code 
gezeigt hast.  Bitte immer Copy&Paste verwenden, sonst werden Mitleser 
potentiell in die Irre geführt und suchen sich einen Wolf.

von Matthias R. (matsch)


Lesenswert?

Da hast du recht.
Hier daher noch einmal der Original-copy-and-paste code:
1
//-----------------------------------------------------------------------------
2
// UART initialisieren 
3
// es wird die Library von Peter Fleury benutzt.
4
//------1---------2---------3---------4---------5---------6---------7---------8 
5
  #ifndef F_CPU
6
  /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
7
    F_CPU im Makefile definiert werden, eine nochmalige Definition
8
    hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
9
    #ifndef/#endif 
10
  
11
    Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
12
    verwendet wird und dort eine andere, nicht zur Hardware passende 
13
    Taktrate eingestellt ist: Dann wird die folgende Definition 
14
    nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
15
    von AVRStudio */
16
 
17
    #define F_CPU 11059200L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
18
//    #define F_CPU  8000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
19
  #endif
20
 
21
  // #define UART_BAUD_RATE 2400L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
22
  // #define UART_BAUD_RATE 4800L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
23
  // #define UART_BAUD_RATE 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
24
  // #define UART_BAUD_RATE 14400L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
25
  #define UART_BAUD_RATE 19200L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
26
  // #define UART_BAUD_RATE 28800L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
27
  // #define UART_BAUD_RATE 38400L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
28
  // #define UART_BAUD_RATE 57600L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
29
  // #define UART_BAUD_RATE 76800L         // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
30
  // #define UART_BAUD_RATE 115200L        // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
31
  // #define UART_BAUD_RATE 230400L        // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
32
 
33
  // Berechnungen
34
  
35
  #define UBRR_VAL ((F_CPU+UART_BAUD_RATE*8)/(UART_BAUD_RATE*16)-1)    // clever runden
36
  #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))                  // Reale Baudrate
37
  #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD_RATE-1000)        // Fehler in Promille
38
 
39
40
  #if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
41
    #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
42
  #endif  
43
44
  uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
Ich habe beim Kommentare entfernen wohl die Klammer mit reduziert. 
Sorry.
Gruß
Matsch

von Matthias R. (matsch)


Lesenswert?

Ich vermute den Fehler auch eher in den Einstellungen vom AVR Studio als 
im Code. Ich finde da nur leider nichts.
AVR Studio: 4.18 Build 700
WinAVR: 20100110
Gruß
Matsch

von Hc Z. (mizch)


Lesenswert?

Obiges Codestück kompiliert ohne Fehler durch.  Es kommt aber Dein 
Fehler, wenn man F_CPU in 11059200UL ändert.  Wetten, Deine 
Kommandozeile enthält -DF_CPU=11059200UL?  Schau mal ins 
Compile-Fenster.

Die Abhilfe hängt davon ab, woher das „UL“ kommt.  Am einfachsten 
änderst Du im Macro selbst F_CPU in (long)F_CPU.

Das Problem ist nämlich, dass BAUD_ERROR durch die Promotionsregeln 
sonst unsigned long wird und deshalb das „-10“ im 
Fehlerüberprüfungs-Makro zu unsigned long promotet wird, zu einer 
riesigen Zahl (ULONG_MAX-9). Und da passt dann (fast) alles drunter.

von Matthias R. (matsch)


Angehängte Dateien:

Lesenswert?

Hc Zimmerer schrieb:
> Obiges Codestück kompiliert ohne Fehler durch.  Es kommt aber Dein
> Fehler, wenn man F_CPU in 11059200UL ändert.  Wetten, Deine
> Kommandozeile enthält -DF_CPU=11059200UL?  Schau mal ins
> Compile-Fenster.
>
> Die Abhilfe hängt davon ab, woher das „UL“ kommt.  Am einfachsten
> änderst Du im Macro selbst F_CPU in (long)F_CPU.

Moin,
ich habe mir schon so etwas gedacht.
In der Kommandozeile steht:
1
avr-gcc -I"D:\Projekte\Test\SoftwareMega16\src"  -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99                                    -DF_CPU=11059200UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main
Da findet sich das -DF_CPU=11059200UL.

In den 'Project Options' (siehe Bild) habe ich die Quarz-Frequenz 
eingestellt. Ein U bzw. ein UL anhängen geht in dem Dialog nicht.

In meinem alten MAKE File stehen folgende Zeilen:
1
# Processor frequency.
2
#     This will define a symbol, F_CPU, in all source code files equal to the 
3
#     processor frequency. You can then use this symbol in your source code to 
4
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
5
#     automatically to create a 32-bit value in your source code.
6
#     Typical values are:
7
#         F_CPU =  1000000
8
#         F_CPU =  1843200
9
#         F_CPU =  2000000
10
#         F_CPU =  3686400
11
#         F_CPU =  4000000
12
#         F_CPU =  7372800
13
#         F_CPU =  8000000
14
#         F_CPU = 11059200
15
#         F_CPU = 14745600
16
#         F_CPU = 16000000
17
#         F_CPU = 18432000
18
#         F_CPU = 20000000
19
F_CPU = 11059200
Binde ich das Makefile ein (gleicher Dialog wie Bild), ist der Fehler 
weg.
Es muss doch aber auch im AVR Studio einzustellen sein, bzw. wo muss ich 
welches Macro ändern?.
Gruß
Matsch

von Hc Z. (mizch)


Lesenswert?

Ich würde hier eingreifen:
1
#if ((BAUD_ERROR>10) || ((long)BAUD_ERROR<-10))
2
                         ^^^^^^

EDIT: Wenn ich mir's recht überlege, wäre es hier sauberer:
1
 #define BAUD_ERROR (((long)BAUD_REAL*1000)/UART_BAUD_RATE-1000)        // Fehler in Promille
2
                      ^^^^^^
Das ersetzt den oberen Vorschlag.

von Matthias R. (matsch)


Lesenswert?

Hallo,
wenn ich das (long) einfüge, bekomme ich folgenden Fehler:
1
../src/prjdef.c:268:33: error: missing binary operator before token "("
Habe in einem anderen Thread gelesen: "Der Präprozessor kennt weder 
'unsigned char' noch 'double'". Kann das auch für 'long' gelten?

Ich habe jetzt einmal eine andere UART Fehlerberechnung aus einem 
anderen Projekt verwendet:
1
#define UART_BAUD 19200L
2
3
// calculate real baud rate:
4
#define UBRR_VAL ((F_CPU+UART_BAUD*8)/(UART_BAUD*16)-1)            // round
5
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))                    // real baudrate
6
#define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD)                  // error in promille
7
8
#if ((BAUD_ERROR < 990) || (BAUD_ERROR > 1010))
9
#  error Error of baud rate of RS232 UART is more than 1%. That is too high!
10
#endif
11
12
  uart_init(UART_BAUD_SELECT(UART_BAUD,F_CPU));
Mit der Berechnung bekomme ich keinen Fehler.

Die Unterschiede sind, soweit ich es erkenne
1
Fehler: #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD_RATE-1000)
2
    OK: #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD)
und
1
Fehler: #if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
2
    OK: #if ((BAUD_ERROR < 990) || (BAUD_ERROR > 1010))
Es fehlt das '-1000' und die Abfrage ist eine andere. Mathematisch 
gesehen ist es doch das gleiche, oder?

Wie kann ich mir die Werte von BAUD_ERROR, F_CPU, usw. vom AVR Studio 
anzeigen lassen?

Gruß
Matsch

von Hc Z. (mizch)


Lesenswert?

Matthias R. schrieb:
> wenn ich das (long) einfüge, bekomme ich folgenden 
Fehler:../src/prjdef.c:268:33: error: missing binary operator before token "("

Es passiert selten, aber es passiert: Ich habe übersehen, dass es sich 
um reine Präprozessor-Arithmetik handelt, und die versteht keine casts.

> Die Unterschiede sind, soweit ich es erkenne
> Fehler: #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD_RATE-1000)
>     OK: #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD)
> undFehler: #if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
>     OK: #if ((BAUD_ERROR < 990) || (BAUD_ERROR > 1010))
> Es fehlt das '-1000' und die Abfrage ist eine andere. Mathematisch
> gesehen ist es doch das gleiche, oder?

In Präprozessor-Mathematik (oder auch C) ist es nicht genau das gleiche: 
Die jeweils zweite Version bleibt im unsigned-long-Zahlenbereich, 
negative Zahlen sind ausgeschlossen.  Deshalb funktioniert sie.

> Wie kann ich mir die Werte von BAUD_ERROR, F_CPU, usw. vom AVR Studio
> anzeigen lassen?

Nur indem Du sie in einer C-Zeile verwendest, z.B.
1
ultoa(BAUD_ERROR, puffer, 10);
und das dann ausgibst.

von Matthias R. (matsch)


Lesenswert?

Hc Zimmerer schrieb:
> Nur indem Du sie in einer C-Zeile verwendest, z.B.
>
1
> ultoa(BAUD_ERROR, puffer, 10);
2
>
> und das dann ausgibst.

Manche Dinge sind so einfach, da sieht man den Code vor lauter Zeichen 
nicht ;-)
Danke für die Ausführungen und Hilfe.
Gruß
Matsch

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.