Fehlermeldung bei Benutzung des UART Codes aus GCC-Tutorial

Gast #772718
Lesenswert?

Hallo,

gcc gibt mir folgenden Fehler
1
wakeup.c:93:41: warning: the right operand of "<" changes sign when promoted
2
wakeup.c:94:5: error: #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
3
make: *** [wakeup.o] Fehler 1

bei Benutzung des Code-Fragments
1
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
2
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
3
#endif

aus dem UART Abschnitt des GCC-Tutorals.

Irgendeine Idee?

Danke
Gerhard
Moderator Persönliche Seite #772748
Lesenswert?

Die Makros sind so, wie sie da stehen, Mist.  BAUD_ERROR ist, bedingt
durch die anderen Teilausdrücke, aus denen er besteht, vom Typ
unsigned int.  Offenbar war das aber nicht beabsichtigt, sondern
eigentlich wollten den gern jemand als signed int haben -- geht aber
nicht, da der Präprozessor keine type casts kann.

Was passiert (und weshalb es die Warnung gibt) ist, dass in einem
Vergleich ein signed int und ein unsigned int gegenüber stehen.  Die
integer promotion rules besagen in diesem Falle, dass dann der komplette
Vergleich unsigned int wird.  Damit wird die -10 umgewandelt in eine
0xfff6 bzw. 65526.  Das war vermutlich nicht im Sinne des Erfinders...

Ich würde mittlerweile zu dem Makros aus <util/setbaud.h> raten.  Die
Doku findest du hier:

http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html
Gast #772754
Lesenswert?

Oszillatorfrequenz = 12000000
Baudrate 9600

daraus folgt:

UBRR_VAL = 77,625 (wird wohl auf 77 abgeschnitten)
BAUD_REAL = 9615
BAUD_ERROR = 1.5625 Promille

also deutlich kleiner als 10.

Gerhard
#772809
Lesenswert?

@ Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>Die Makros sind so, wie sie da stehen, Mist.  BAUD_ERROR ist, bedingt

Nanana. Vor Öffnung des Mundwerks Hirn einschalten. Sofern vorhanden.

>durch die anderen Teilausdrücke, aus denen er besteht, vom Typ
>unsigned int.  Offenbar war das aber nicht beabsichtigt, sondern
>eigentlich wollten den gern jemand als signed int haben -- geht aber
>nicht, da der Präprozessor keine type casts kann.

Doch, man öffne die Augen und lese.

1
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
2
#define F_CPU 4000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! 
3
#endif
4
 
5
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
6
 
7
// Berechnungen
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
11
 
12
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
13
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
14
#endif

MFG
Falk
#772828
Lesenswert?

@ Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>OK, wenn du alles als signed long machst.  Ist aber unüblich, AVR Studio
>hängt das UL von allein da dran, und schon haste den Salat.

???
Ist mit AVR Studio fehlerfrei getestet.

>Mittlerweile finde ich die Arbeiten in <util/setbaud.h> wirklich
>besser.

Muss neu sein. Ich hab nur ne alte WINAVR-Version von anno 2006?

MFG
Falk
Gast #772860
Lesenswert?

Hatte im Makefile

CDEFS = -DF_CPU=12000000UL

stehen, das hat offensichtlich zu dem Fehler geführt. Nach Änderung im 
Makefile auf:

CDEFS = -DF_CPU=12000000L

compiliert der Code anstandslos. So ganz verstehe ich es leider noch 
nicht.

Danke
Gerhard
#772963
Lesenswert?

@ Gerhard (Gast)

>CDEFS = -DF_CPU=12000000L

>compiliert der Code anstandslos. So ganz verstehe ich es leider noch
>nicht.

ist doch sonnenklar.

Endung UL = Unsigned long
Endung L = signed long

Da ein Vergleich mit negativen Zahlen gemacht wird, muss logischerweise 
ein signed long verwendet werden.

MFG
Falk
Moderator Persönliche Seite #772967
Lesenswert?

Gerhard wrote:

> CDEFS = -DF_CPU=12000000UL
>
> stehen, das hat offensichtlich zu dem Fehler geführt.

Ja, und das ist genau das, was mir daran nicht gefällt: die Makros im
Tutorial hängen davon ab, dass F_CPU vorzeichenbehaftet ist.  Da es
keine negativen CPU-Frequenzen gibt, ist das natürlich eher
widernatürlich.

> So ganz verstehe ich es leider noch
> nicht.

Nur durch konsequentes Deklarieren aller beteiligten Teilkonstanten
bleibt der Typ des Gesamtausdrucks (so wie vom Autor beabsichtigt)
selbst vorzeichenbehaftet.  Die Vorzeichenhaftigkeit ist wiederum
aber Bedingung dafür, dass man am Ende einen Vergleich gegen positive
und negative Zahlen durchführen kann.  Damit hängen die Makros aber
von der Nutzereingabe ab und sind folglich nicht gerade das, was ich
als stabil bezeichnen würde.  Die bereits genannten Makros aus
<util/setbaud.h> dagegen kommen auch mit vorzeichenlosen Zahlen gut
klar, da sie intern sowieso vorzeichenlos rechnen.  Die Fehlerberechnung
wird dort geringfügig anders gemacht.

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