www.mikrocontroller.net

Forum: Compiler & IDEs Baud rate berechnen


Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ist UART_UBRR_CALC(a,b), UART_BAUD_RATE, F_CPU definiert?

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe die zeile korrigiert aber das ergebnis hat nicht geändert

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 %.

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die werte von 6 habe ich von das Formel die im Datenblatt steht undzwar 
ubrr=fosc/(16*Baud) - 1 bekommen

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  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)

Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 );

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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





Autor: Pascal (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Karl für die erklärung.  ich hoffe es muss jetzt functionnieren. 
wenn nicht melde mich noch wieder.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.