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).
so sieht mein Programm aus: #include <avr/io.h> #include <avr/io.h> #include <stdint.h> #include <avr/interrupt.h> #include <stdlib.h> #ifndef F_CPU #define F_CPU 1000000 /* Oszillator-Frequenz in Hz */ #endif // Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt) #define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1) #define UART_BAUD_RATE 9600 void USART_Transmit( unsigned char x) { while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */ { } UDR = x; /* schreibt das Zeichen x auf die Schnittstelle */ } int main(void) { //UCSRA |= (1<<U2X); UCSRB |= (1<<TXEN); // UART TX einschalten UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1 UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 ); UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ); //UBRRH = 0; //High Byte ist 0 //UBRRL = 6; //Low Byte ist 6 (dezimal) unsigned char x = 0xAA; USART_Transmit(x); }
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 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
Danke Karl für die erklärung. ich hoffe es muss jetzt functionnieren. wenn nicht melde mich noch wieder.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.