Hallo leute, ich versuche ja die baud rate mit dem formel zu rechnen
aber das ergebnis in oscilloskop ist nicht richtig. Die Formel die ich
benutze ist
UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
aber wenn ich die werte zu den Registern zuweise habe ich im bildschirm
die Baud Rate das ich erwarte.
ich arbeite mit dem Atmega16 mit einem fosc von 1Mhz und ich will gerne
mit einer Baud Rate von 9600hz arbeiten
bitte helfen sie mir
Danke in voraus
> aber wenn ich die werte zu den Registern zuweise habe ich> im bildschirm die Baud Rate das ich erwarte.
Ich nehme an, daß hier ein linguistisches Problem vorliegt. Vermutlich
fehlt das Wort "nicht".
Obendrein lässt sich aus 1 MHz nicht ohne Fehler eine Baudrate von 9600
Baud erzeugen - das Thema "Baudratenquarz" wurde hier bereits ad nauseam
durchgehechelt.
Dann wäre noch zu klären, ob der Takt auch wirklich stimmt - die
berühmten "Fuses" kommen da ins Spiel.
Rufus t. Firefly wrote:
> Obendrein lässt sich aus 1 MHz nicht ohne Fehler eine Baudrate von 9600> Baud erzeugen
Brauchbar genau, wenn man das U2X-Bit setzt (und dann natürlich nur
durch 8 statt durch 16 teilt).
> Dann wäre noch zu klären, ob der Takt auch wirklich stimmt - die> berühmten "Fuses" kommen da ins Spiel.
Wobei 1 MHz die Werkseinstellung ist, zumindest falls der ATmega16
mit 5 V betrieben wird.
Ist F_CPU denn überhaupt korrekt definiert? Wenn das schon nicht stimmt,
dann kann die Baudrate noch nicht mal annähernd korrekt sein. Hinzu
kommt noch die Frage, ob Du einen externen Quarz oder den internen
RC-Oszillator nutzt. Im zweiten Fall ist funktionierende asynchrone
Datenübertragung eher Glückssache.
es ist ja klar das ich kein Deutscher Bin. aber was ich sagen will ist
das, wenn ich die werte Dierkt zu den register eigebe (die Registern
initialisieren) habe ich fast die Baud rate das ich erwarte (9,26khz).
Aber wenn ich die werte von den Registern mit der Formel berechnen
bekomme ich im bildschirm eine Baud rate von etwas 1,2khz. deswegen
frage ich mich ob ich die Richtige Formel benutzt habe
Das sieht dann eher danach aus, als ob F_CPU nicht korrekt ist
(möglicherweise ist es auf 8 MHz eingestellt, das würde mit den
angegebenen Werten einigermaßen übereinstimmen). Check mal Deine
Einstellungen im Makefile bzw. in der IDE (je nachdem, womit Du
arbeitest).
Pascal wrote:
> Aber wenn ich die werte von den Registern mit der Formel berechnen> bekomme ich im bildschirm eine Baud rate von etwas 1,2khz. deswegen> frage ich mich ob ich die Richtige Formel benutzt habe
Welche Formel, ich sehe nirgends eine.
Vielleicht steckt ja eine hinter dem Macro "UART_UBRR_CALC".
Aber das ist nirgends definiert.
Und die anderen Macros auch nicht.
Peter
Gut, jetzt wird es klarer.
Du berechnest Werte von Hand, die stimmen, aber die per Code berechneten
sind inkorrekt.
Das liegt an dieser Zeile:
#define F_CPU 1000000
Das muss eine long-Konstante sein, als int-Konstante lässt sich ein so
großer Wert nicht ausdrücken (int ist auf dem AVR nur 16 Bit groß).
Durch Anhängen eines "L" wird aus der Konstanten eine long-Konstante:
#define F_CPU 1000000L
und die Berechnung sollte jetzt stimmen.
Bei F_CPU 1000000 und BAUD 9600 wäre laut Formel ein Wert von 5,51 in
das Baudratenregister einzutragen.
Die Formel trägt nur ganzzahlige Werte ein, d.h. 5 (abgerundet). Damit
kommst du auf eine Baudrate von 10416,7, d.h. +8,5% gegenüber den
gewollten 9600.
Von Hand trägst du 6 ein (aufgerundet). Damit kommst du auf eine
Baudrate von 8928,6 , d.h. -7,0%. Ein etwas geringerer Fehler und
möglicherweise ausschlaggebend für eine doch gerade noch mögliche
Übertragung.
Beides zeigt, dass mit der F_CPU diese BAUD nur mit grossem Fehler
realisierbar sind. Ich würde eine andere BAUD probieren bzw. einen
andere F_CPU (Baudratenquarz)
Ich würde ausserdem mein Oszilloskop-Auslesung bzw. meine
Frequenzmessung kontrollieren, ob vielleicht eine 10er Stelle vom
Ergebnis verschoben ist.
Stefan B. wrote:
> Beides zeigt, dass mit der F_CPU diese BAUD nur mit grossem Fehler> realisierbar sind.
Nein, man muss U2X setzen (und dann durch 8 teilen), siehe oben.
Dann ist der Fehler bei 0,2 %.
> Die werte von 6 habe ich von das Formel die im Datenblatt steht undzwar> ubrr=fosc/(16*Baud) - 1 bekommen
Die Formel im Datenblatt (und demzufolge auch die in Deinem Programm)
berücksichtigt aber das U2X-Bit nicht! Deshalb gehts nicht.
Die 1,2 kHz sind allerdings eher ein Zeichen dafür, dass F_CPU irgendwo
außerhalb Deines Programms auf 8 MHz gesetzt wird. Nimm mal das "#ifndef
F_CPU" und das "#endif" raus.
Jörg Wunsch wrote:
> Stefan B. wrote:>>> Beides zeigt, dass mit der F_CPU diese BAUD nur mit grossem Fehler>> realisierbar sind.>> Nein, man muss U2X setzen (und dann durch 8 teilen), siehe oben.> Dann ist der Fehler bei 0,2 %.
Sorry Jörg, du hast natürlich recht und meine pauschale Aussage ist
Quatsch.
Bei U2X = "1" errechnet sich der genaue Wert für UBRR auf 12,02. Wenn
man stattdessen gerundet 12 verwendet, kommt man auf eine Baudrate von
9615,4, d.h. harmlose +0,2% Fehler (wie Jörg bereits angegeben hat).
Jörg Wunsch worte:
> Nein, man muss U2X setzen (und dann durch 8 teilen), siehe oben.> Dann ist der Fehler bei 0,2 %.
ich habe es gemacht aber wie ich erwartete es hat nur die Baud
verdoppelt (von 1,2khz zu 2,4khz)
wie bekommt ihr diese werte von 12,02 im UBRR kann jemand von euch mir
erklärt wie genau diesen gleichungen functionniert:
UBRRH = (uint8_t)( USART_UBRR_CALC( USART_BAUD_RATE, F_CPU ) >> 8 );
UBRRL = (uint8_t)USART_UBRR_CALC( USART_BAUD_RATE, F_CPU );
Pascal wrote:
> wie bekommt ihr diese werte von 12,02 im UBRR kann jemand von euch mir> erklärt wie genau diesen gleichungen functionniert:> UBRRH = (uint8_t)( USART_UBRR_CALC( USART_BAUD_RATE, F_CPU ) >> 8 );> UBRRL = (uint8_t)USART_UBRR_CALC( USART_BAUD_RATE, F_CPU );
Mach das, was der Präprozessor auch macht.
Setzte die #define ein
F_CPU ersetzt du durch 1000000UL
**
mach da mal statt L ein UL draus
USART_BAUD_RATE ersetzt du durch 9600
dann steht da
UBRRL = (uint8_t)USART_UBRR_CALC( 9600, 1000000UL );
und jetzt ersetzt du USART_UBRR_CALC durch im #define
angegebene Ersetzung, wobei du überall in der Ersetzung
9600 für BAUD_ einsetzt und 1000000UL für FREQ_
das war nochmal die Formel
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
eingesetzt ergibt sich
UBRRL = (uint8_t)((1000000UL)/((9600)*16L)-1);
und das tippst du jetzt in den Taschenrechner: macht 5.5104
Wenn du mit U2X arbeitest, dann muss nicht durch 16, sondern
durch 8 dividiert werden:
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*8L)-1)
und die Ersetzung ergibt daher:
UBRRL = (uint8_t)((1000000UL)/((9600)*8L)-1);
im Taschenrechner ausgerechnet ergibt sich: 12.0208
(aufpassen dass du dich nicht mit den Klammern verhaust.
In Mathe-Notation ist das
1000000
---------- - 1
9600 * 8