Umstig von PN auf VAR Studio - Baudrate Fehler

OP #1925494
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
#1928884
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.
OP #1928900
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
#1929213
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.
OP #1930601
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
Angehängte Dateien:
#1930671
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.
OP #1933051
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
#1933878
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren