Berechnungsfehler Baudrate mit Makro

Gast #570426
Lesenswert?
• ▲
▼
Hallo zusammen,

ich bastel mit einem ATMega32 und Peter Fleury's uart lib herum. Dabei 
kommt es zu einem folgeschweren Rechenfehler bei der Berechnung der 
Baudrate. Ein UART_BAUD_RATE von 9600 wird zu dem Wert, der die 
vierfache Baudrate von 38400 (UBRR = 6 @ 4MHz) einstellt, 2400 wird zu 
9600 Baud (UBRR = 25 @ 4MHz) etc.
Eine doppelte Vergabe von Namen kann ich ausschliessen, lediglich XTAL 
und xtalCpu werden verwendet.

Nun meine Fragen:
1. Wie kann ich dem Compiler bei der Arbeit zusehen, um festzustellen, 
wie der Rechenfehler zustande kommt?
2. Hat jemand einen heissen Tip, wo ich noch suchen kann?


Den Codeausschnitt habe ich angehängt (allesamt aus der Fleury-lib):
1
#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)
2

3

4
#ifndef F_CPU
5
#define F_CPU 4000000UL
6
#endif
7

8
/* 9600 baud */
9
#define UART_BAUD_RATE      9600
10

11
void UsartInit(){
12
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

Bin gespannt auf eure Ratschläge!

Gruß,
Christian
#570463
Lesenswert?
• ▲
▼
> 1. Wie kann ich dem Compiler bei der Arbeit zusehen, um festzustellen,
> wie der Rechenfehler zustande kommt?
Fällt mir grad noch auf: Der Compiler hat damit im Prinzip überhaupt 
nichts zu tun, da der Präprozessor die Berechnungen ausführt. Und wenn 
F_CPU und UART_BAUD_RATE korrekt angegeben sind, besteht überhaupt kein 
Grund, warum das Ergebnis falsch sein sollte. Tu Dir selbst nen Gefallen 
und nimm das #ifndef und das #endif weg. Wenn dann das richtige 
rauskommt, dann ist es woanders definiert.
Gast #570527
Lesenswert?
• ▲
▼
> Fällt mir grad noch auf: Der Compiler hat damit im Prinzip überhaupt
> nichts zu tun, da der Präprozessor die Berechnungen ausführt.

Nein. Der Präprozessor führt hier nur eine Makrosubstitution durch, 
sonst gar nichts. Das heißt, er macht aus:
1
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

ein:
1
((4000000UL)/((9600)*16l)-1)

Und das geht dann so an den eigentlichen Compiler weiter.
Gast #570828
Lesenswert?
• ▲
▼
Ich denke auch, dass F_CPU anderswo definiert worden ist. Hast du z.B. 
die delay.h eingebunden? Nimm #ifndef mal raus, beim compilieren wird 
wahrscheinlich die Warnung 'F_CPU redefined' o.ä. ausgeworfen. Ist das 
nicht der Fall hilft vorerst nur noch die Glaskugel.

pumpkin
Gast #571036
Lesenswert?
• ▲
▼
Hallo zusammen,

vielen Dank für die hilfreichen Tips. Verzwackte Sache, das. Es war die 
Definition von F_CPU in der delay.h - Pumpkin hat den Nagel auf den Kopf 
getroffen, aber alle haben in die richtige Richtung gesucht.
Die Redefinition von F_CPU ist leider nie aufgefallen, da in der delay.h 
auch ein #ifndef verwendet wird (hatte schon probiert eine redefinition 
so zu finden - das projekt dann aber nicht in den chip gebrutzelt).
Die falsche Zeitkonstante ist nicht aufgefallen, da mein Atmel in der 
Testphase noch über den internen Oszi mit 1MHz lief (da habe ich den 
delay überprüft und für gut befunden) - in der delay.h wird die Frequenz 
mit 1MHz dewfiniert in der besagten F_CPU.
Geknallt hat's dann erst am Ende, als alles zusammen wursteln sollte

Lösung? Demnächst kommt die Prozessorgeschwindigkeit ins Makefile.

Vielen Dank für eure Hilfe!

Gruß,
Christian
Gast #571267
Lesenswert?
• ▲
▼
In meiner AVR-libc (1.4.4) spuckt delay.h eine
1
  warning: #warning "F_CPU not defined for <util/delay.h>"
aus, wenn F_CPU nicht schon vor dem Includieren definiert ist.

Ich frage mich allerdings,

- warum nur eine Warnung und kein Fehler ausgegeben wird, die
  insbesondere bei redseligen Makefiles schnell mal übersehen wird,
  und

- warum delay.h überhaupt einen Defaultwert setzt, der bei den vielen
  Prozessortaktoptionen, die die AVRs bieten, fast immer falsch sein
  wird.

In meinen Augen würde ein lauter und deutlicher Error den
Programmierer schneller zur Ursache des Problems führen.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.