Forum: Mikrocontroller und Digitale Elektronik Atmega328 UART 1'000'000 Baud


von Mathias (Gast)


Lesenswert?

Mit folgendem Code probiere ich eine Serielle Datenübertragung.
Schon mit 115'000 Baud gibt es beim Einlesen ab und zu einen Abreisser, 
schreiben geht fehlerfrei. Aber will ich mit 1'000'000Bad übertragen, 
scheint es gar nicht zu funktionieren.
1
#define TAKT 16000000UL
2
3
void Init_UART(unsigned long baud) {
4
  unsigned int teiler;
5
6
  teiler = TAKT / (2UL * baud) - 1;
7
8
  UBRR0L = teiler;
9
  UBRR0H = (teiler >> 8);
10
11
  UCSR0A |= (0 << U2X0);
12
  UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
13
  UCSR0C |= (1 << UMSEL00) | (1 << UCSZ01) | (1 << UCSZ00);
14
15
  DDRD |= (1 << PD4);
16
}
17
18
unsigned char Read_UART(void) {
19
  while (!(UCSR0A & (1 << RXC0))) {
20
  }
21
  return UDR0;
22
}
23
24
void Write_UART(unsigned char c) {
25
  while (!(UCSR0A & (1 << UDRE0))) {
26
  }
27
  UDR0 = c;
28
}

Nehme ich aber die original Arduino Befehle
1
Serial.begin(1000000);
2
Serial.readBytes(serialIn.buf, 4);
3
Serial.write(adc.buf, 4);
Dann klappt die Übertragung fehlerfrei.
Was mache ich mit den direkten Registerbefehlen falsch ?

Ich wies nicht ob es relevant ist, der I²C-Bus wird auch benutzt.

von Jim M. (turboj)


Lesenswert?

Deine Baudratenberechnung stimmt nicht. Mit U2X0=0 ist der Teiler 16 und 
nicht 2, d.h. UBRR0L und UBRR0H sind jeweils im Ergebnis null.

von Mathias (Gast)


Lesenswert?

Jim M. schrieb:
> Deine Baudratenberechnung stimmt nicht. Mit U2X0=0 ist der Teiler
> 16 und
> nicht 2, d.h. UBRR0L und UBRR0H sind jeweils im Ergebnis null.
Und was muss ich das ändern ?

von H.Joachim S. (crazyhorse)


Lesenswert?

Mathias schrieb:
> UCSR0A |= (0 << U2X0);

Das ist falsch.

von Nico W. (nico_w)


Lesenswert?

Mathias schrieb:
>> Mit U2X0=0 ist der Teiler 16 und
>> nicht 2, d.h. UBRR0L und UBRR0H sind jeweils im Ergebnis null.
> Und was muss ich das ändern ?

Hat er direkt geschrieben. UBRR0L/H = 0


Und eben auch UCSR0A = 0.


Kannst dir den Zauber auch hier mal ansehen.
https://github.com/Traumflug/Teacup_Firmware/blob/master/serial-avr.c

Beitrag #5100272 wurde von einem Moderator gelöscht.
von Mathias (Gast)


Lesenswert?

Nico W. schrieb:
> Mathias schrieb:
>>> Mit U2X0=0 ist der Teiler 16 und
>>> nicht 2, d.h. UBRR0L und UBRR0H sind jeweils im Ergebnis null.
>> Und was muss ich das ändern ?
>
> Hat er direkt geschrieben. UBRR0L/H = 0
>
> Und eben auch UCSR0A = 0.
>
> Kannst dir den Zauber auch hier mal ansehen.
> https://github.com/Traumflug/Teacup_Firmware/blob/...


Ich habe nun folgendes probiert, geht aber nicht, auch nicht mit 115200 
Baud.
1
void Init_UART(unsigned long baud) {
2
3
  UCSR0A = (1 << U2X0);
4
  UBRR0 = (((F_CPU / 8) / baud) - 0.5);
5
6
  UCSR0B = (1 << RXEN0) | (1 << TXEN0);
7
  UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
8
9
  UCSR0B |= (1 << RXCIE0) | (1 << UDRIE0);
10
}



>Mathias schrieb:
>> Aber will ich mit 1'000'000Bad übertragen,
>
>Bei 16 MeV wird das nichts im Bad.
>
>Mal sehen
Irgendwie muss es gehen, ansonsten würde es mit den Arduino-Befehlen 
Serial.begin auch nicht gehen.

von Alexander S. (alex998)


Lesenswert?

Mathias schrieb:
> UBRR0 = (((F_CPU / 8) / baud) - 0.5);

0.5?? Denk nochmal drüber nach.

von spess53 (Gast)


Lesenswert?

Hi

>Irgendwie muss es gehen, ansonsten würde es mit den Arduino-Befehlen
>Serial.begin auch nicht gehen.

Ich würde einfach mal das Datenblatt vom ATMega lesen. Da steht alles 
drin.

MfG Spess

von Mathias (Gast)


Lesenswert?

Alexander S. schrieb:
> Mathias schrieb:
>> UBRR0 = (((F_CPU / 8) / baud) - 0.5);
>
> 0.5?? Denk nochmal drüber nach.

Die hat mich auch etwas verwundert, dies habe ich beim obige, Link 
https://github.com/Traumflug/Teacup_Firmware/blob/master/serial-avr.c 
abgeguckt.
1
void serial_init() {
2
3
  #if BAUD > 38401
4
    UCSR0A = MASK(U2X0);
5
    UBRR0 = (((F_CPU / 8) / BAUD) - 0.5);
6
  #else
7
    UCSR0A = 0;
8
    UBRR0 = (((F_CPU / 16) / BAUD) - 0.5);
9
  #endif
10
11
  UCSR0B = MASK(RXEN0) | MASK(TXEN0);
12
  UCSR0C = MASK(UCSZ01) | MASK(UCSZ00);
13
14
  UCSR0B |= MASK(RXCIE0) | MASK(UDRIE0);
15
}

von Frank K. (fchk)


Lesenswert?

Mathias schrieb:
> Alexander S. schrieb:
>> Mathias schrieb:
>>> UBRR0 = (((F_CPU / 8) / baud) - 0.5);
>>
>> 0.5?? Denk nochmal drüber nach.
>
> Die hat mich auch etwas verwundert, dies habe ich beim obige, Link
> https://github.com/Traumflug/Teacup_Firmware/blob/master/serial-avr.c
> abgeguckt.
>
>
1
void serial_init() {
2
> 
3
>   #if BAUD > 38401
4
>     UCSR0A = MASK(U2X0);
5
>     UBRR0 = (((F_CPU / 8) / BAUD) - 0.5);
6
>   #else
7
>     UCSR0A = 0;
8
>     UBRR0 = (((F_CPU / 16) / BAUD) - 0.5);
9
>   #endif
10
> 
11
>   UCSR0B = MASK(RXEN0) | MASK(TXEN0);
12
>   UCSR0C = MASK(UCSZ01) | MASK(UCSZ00);
13
> 
14
>   UCSR0B |= MASK(RXCIE0) | MASK(UDRIE0);
15
> }

Da sind sowohl BAUD als auch F_CPU direkte numerische Konstanten, die 
per #define im Präprozessor ersetzt werden. Damit wird die Konstante für 
UBRR0 zur Compilezeit berechnet, nicht zur Laufzeit. Das macht den 
Unterschied.

C sollte man schon können.

fchk

von M. K. (sylaina)


Lesenswert?

Frank K. schrieb:
> C sollte man schon können.

Datenblatt lesen kann auch helfen. Da steht immerhin auch drin wie man 
den UART für 1 Mbps einstellen muss bei 16 MHz Systemtakt ;)

von Rene K. (xdraconix)


Lesenswert?

M. K. schrieb:
> den UART für 1 Mbps einstellen

Nur so als Hinweis: die richtige Definition ist: 1 MBd :-)

von M. K. (sylaina)


Lesenswert?

Rene K. schrieb:
> M. K. schrieb:
>> den UART für 1 Mbps einstellen
>
> Nur so als Hinweis: die richtige Definition ist: 1 MBd :-)

Nur so als Hinweis: Hab ich "Baud" gemeint oder "bits per second"? ;)

von Stefan F. (Gast)


Lesenswert?

Ich verstehe nicht, warum hier immer wieder Leute die Formel für das 
Baudraten-Register neu erfinden.

Benutzt doch einfach 
http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html

von Rene K. (xdraconix)


Lesenswert?

M. K. schrieb:
> Nur so als Hinweis: Hab ich "Baud" gemeint oder "bits per second"? ;)

Na eine Datenübertragung über eine Modulation gibt man ja in den 
seltensten Fällen als "bits per second" an ;-) Das ist sehr untypisch. 
Und wenn dann wenigstens als "bMbps".

von Ganz Zahl (Gast)


Lesenswert?

Frank K. schrieb:
> ...
>>     UBRR0 = (((F_CPU / 8) / BAUD) - 0.5);
> ...
> Da sind sowohl BAUD als auch F_CPU direkte numerische Konstanten, die
> per #define im Präprozessor ersetzt werden. Damit wird die Konstante für
> UBRR0 zur Compilezeit berechnet, nicht zur Laufzeit. Das macht den
> Unterschied.

Mich würde schon diese Float-Konstante mitten in der Ganzzahl-Rechnung 
stutzig machen.

> Die hat mich auch etwas verwundert, dies habe ich beim obige, Link
> https://github.com/Traumflug/Teacup_Firmware/blob/master/serial-avr.c
> abgeguckt.

Was erwartest du - ...\Traumflug\... eben ...

von M. K. (sylaina)


Lesenswert?

Rene K. schrieb:
> M. K. schrieb:
>> Nur so als Hinweis: Hab ich "Baud" gemeint oder "bits per second"? ;)
>
> Na eine Datenübertragung über eine Modulation gibt man ja in den
> seltensten Fällen als "bits per second" an ;-) Das ist sehr untypisch.
> Und wenn dann wenigstens als "bMbps".

Noch ein Hinweis: Schau ins Datenblatt eines AVRs, z.B. dem vom 
Atemga328p ;)

Übrigens: Mein LAN-Port hier am Rechner wird auch mit 1 Gbps angegeben. 
Bei meinem DSL heißt es auch "bits per second". Soso selten erscheint 
mir die Angabe also mal überhaupt nicht. ;)

Ganz Zahl schrieb:
> Mich würde schon diese Float-Konstante mitten in der Ganzzahl-Rechnung
> stutzig machen.

Ich glaub, die ist nur fürs Runden drin damit der "Fehler" später unter 
ein Prozent oder so bleibt. Ich kenn das aber auch gesamt nur als 
Makro-Funktion welche später in einen Error läuft wenn der Fehler auf 
über ein Prozent ansteigt.

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Mathias schrieb:
> UBRR0 = (((F_CPU / 8) / baud) - 0.5);

Der Compiler rechnet mit Integer, wenn er keine andere Anweisung 
bekommt. Zwinge ihn, mit long zu rechnen und lass die 0.5 weg.

Beispiel: (F_CPU/(baud*8l)-1)

Beitrag #5101575 wurde vom Autor gelöscht.
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mathias schrieb:
> Schon mit 115'000 Baud gibt es beim Einlesen ab und zu einen Abreisser
In welcher Form? Keine Zeichen, zu wenige, falsche?

> Ich wies nicht ob es relevant ist, der I²C-Bus wird auch benutzt.
Aber nicht im geposteten Programm...
Mach doch einfach mal einen Drei nur mit der seriellen Schnitte. Wenn 
das auch nicht geht, dann hast du einen Fehler dort drin. Wenn es dann 
aber geht, dann hast du einen Fehler anderswo...

von Detlev T. (detlevt)


Lesenswert?

Ich nehme an, dass das Programm Timing-Probleme hat. Bei 16MHz und 
1MBit/s hat man nur 160 Takte pro Zeichen. Da muss man die 
Einlese-Routine gut optimieren, sonst geht's nicht. Interrupts in der 
Zeit sind auch tabu.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mathias schrieb:
> Nehme ich aber die original Arduino Befehle
> ...
> Dann klappt die Übertragung fehlerfrei.
> Was mache ich mit den direkten Registerbefehlen falsch ?


Könnte es sein, daß die Arduino-Variante interruptgesteuert arbeitet? 
Deine "direkten Registerbefehle" arbeiten mit polling, d.h. Du musst 
ständig aktiv nachsehen, ob Zeichen gekommen sind.

von Mathias (Gast)


Lesenswert?

>Könnte es sein, daß die Arduino-Variante interruptgesteuert arbeitet?

Sieht fast so aus. Wen ich die Source von Arduino angucke, steht immer 
was von Puffer, einen Ausschnitt von HardwareSerial.cpp.
1
int HardwareSerial::read(void)
2
{
3
  // if the head isn't ahead of the tail, we don't have any characters
4
  if (_rx_buffer_head == _rx_buffer_tail) {
5
    return -1;
6
  } else {
7
    unsigned char c = _rx_buffer[_rx_buffer_tail];
8
    _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
9
    return c;
10
  }
11
}

Lothar M. schrieb:
> Mathias schrieb:
>> Schon mit 115'000 Baud gibt es beim Einlesen ab und zu einen Abreisser
> In welcher Form? Keine Zeichen, zu wenige, falsche?
Schreiben geht, aber beim Lesen gibt es Fehler (falsche Werte).

>> Ich wies nicht ob es relevant ist, der I²C-Bus wird auch benutzt.
> Aber nicht im geposteten Programm...
> Mach doch einfach mal einen Drei nur mit der seriellen Schnitte. Wenn
> das auch nicht geht, dann hast du einen Fehler dort drin. Wenn es dann
> aber geht, dann hast du einen Fehler anderswo...
Dies müsste ich mal probieren.

von Mathias (Gast)


Lesenswert?

Mathias schrieb:
>>> Ich wies nicht ob es relevant ist, der I²C-Bus wird auch benutzt.
>> Aber nicht im geposteten Programm...
>> Mach doch einfach mal einen Drei nur mit der seriellen Schnitte. Wenn
>> das auch nicht geht, dann hast du einen Fehler dort drin. Wenn es dann
>> aber geht, dann hast du einen Fehler anderswo...
> Dies müsste ich mal probieren.

Habe dies unterdessen probiert, aber geholfen hat es nicht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mathias schrieb:
> Habe dies unterdessen probiert, aber geholfen hat es nicht.
Mit welchem Programm hast du es probiert? Was hast du probiert? Was hast 
du dabei erwartet und was ist stattdessen passiert?

Mathias schrieb:
> Schreiben geht, aber beim Lesen gibt es Fehler (falsche Werte).
Von Anfang an jedes Zeichen falsch?
Welche Zeichen erhältst du statt welcher Zeichen?
Was passiert, wenn du einmal oder dauernd 'a' an den µC schickst?
Bekommst du dann dauernd das selbe falsche Zeichen? Wenn ja welches?
Was, wenn du dauernd 'b' sendest?
Was bei 'c', was bei 'z'?
Wie sendest du die Zeichen an den µC? Als einzelne Zeichen mit einem 
Terminalprogramm über die Tastatur? Oder als String mit 20 Zeichen 
direkt hintereinander?


BTW: hast du ein Oszilloskop um mal die Bitdauer auszumessen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mathias schrieb:
>> Könnte es sein, daß die Arduino-Variante interruptgesteuert arbeitet?
>
> Sieht fast so aus.

Na, das zusammen mit

> Schreiben geht, aber beim Lesen gibt es Fehler (falsche Werte).

sollte doch Klarheit bringen.

Du kannst nur Zeichen empfangen, solange Du Deine Read_UART-Funktion 
aufrufst. Da Du aber noch anderes machst, bist Du in dieser Zwischenzeit 
"taub". Ein zwischenzeitlich ankommendes Zeichen wird noch von der 
UART-Hardware entgegengenommen, jedes weitere verschwindet aber im 
Orkus.


Du müsstest also Deine zwischen den Read_UART-Aufrufen unternommenen 
Aktivitäven massiv verkürzen, oder die Funktion ständig und immer wieder 
aufrufen (nur was machst Du dann mit den Zeichen, die Du in diesem 
Moment gar nicht gebrauchen kannst?).

Prinzipiell ist zwar Dein Programm schnell genug, aber die Datenrate, 
mit der es empfangen kann, schwankt während der Laufzeit sehr stark, und 
dadurch gehen Daten verloren.


Der interruptgesteuerte Empfang nimmt Dir dieses Problem ab. Der kann 
quasiautark solange Zeichen empfangen, bis der Empfangspuffer voll ist. 
Und Du kannst die aufgelaufenen Daten verarbeiten, ohne Dich um den 
gleichzeitig stattfindenden Empfang weiterer Daten kümmern zu müssen.

Probleme gibt es nur dann, wenn Dein Programm insgesamt zu langsam wird, 
d.h. wenn ein Auswertungsvorgang eines Datenblocks/Telegramms/Befehls 
länger dauert als der zeitliche Abstand zweier aufeinanderfolgender 
Datenblöcke/Telegramme/Befehle.

von avr (Gast)


Lesenswert?

M. K. schrieb:
> Noch ein Hinweis: Schau ins Datenblatt eines AVRs, z.B. dem vom
> Atemga328p ;)
Unabhängig davon was darin steht, ist 1MBd/s die richtige Einheit. 
Übertragen werden tatsächlich nur max. 800kb/s.
> Übrigens: Mein LAN-Port hier am Rechner wird auch mit 1 Gbps angegeben.
Weil hier die Datenrate abgegeben wird und eben nicht die Symbolrate. 
Die liegt nämlich bei Gigabit Ethernet (so wie übrigens auch bei fast 
Ethernet) bei 125MBd/s.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

avr schrieb:
> Unabhängig davon was darin steht, ist 1MBd/s die richtige Einheit.

Nö, Baud enthält schon "pro Sekunde".

1 MBd/s wäre die Beschleunigung einer Datenrate ...

von avr (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Baud enthält schon "pro Sekunde".

Stimmt, irgendwie hab ich da in Symbolen gedacht und Baud geschrieben.

von M. K. (sylaina)


Lesenswert?

avr schrieb:
> Unabhängig davon was darin steht, ist 1MBd/s die richtige Einheit.
> Übertragen werden tatsächlich nur max. 800kb/s.

Da beim Atmega die Symbolrate == Datenübertragungsrate ist, kann man 1 
MBd schreiben oder eben 1 Mbps. Da gibts eben nicht "die richtige 
Einheit".
Und wie kommst du denn auf die maximal 800 kb/s? Das wäre jetzt mal 
spannend.

avr schrieb:
> Weil hier die Datenrate abgegeben wird und eben nicht die Symbolrate.

Das ist mir bewusst. Preisfrage: Was hatte ich angegeben? ;)

> Die liegt nämlich bei Gigabit Ethernet (so wie übrigens auch bei fast
> Ethernet) bei 125MBd/s.

Wie kommst du denn jetzt darauf? Fast Ethernet hat eine 
Datenübertragungsrate von 100 Mbps, Gigabit Ethernet hat eine 
Datenübertragungsrate von 1000 Mbps. Hätten beide dieselbe Symbolrate, 
warum hätte man denn da 1000 Mbps erfinden sollen? Oder anders gefragt: 
Warum sollte beim Gigabit-Ethernet Symbole 10 mal mehr an Bits benötigen 
als beim Fast-Ethernet? Oder mixt du jetzt hier verschieden Symbole und 
vergleichst dann?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

M. K. schrieb:
> Und wie kommst du denn auf die maximal 800 kb/s? Das wäre jetzt mal
> spannend.

Was sind Start- und Stopbits, und welchen Rolle spielen sie bei einer 
asynchronen seriellen Datenübertragung?

von M. K. (sylaina)


Lesenswert?

Rufus Τ. F. schrieb:
> Was sind Start- und Stopbits, und welchen Rolle spielen sie bei einer
> asynchronen seriellen Datenübertragung?

Start- & und Stoppbits gehören zur Datenübertragung, auch wenn sie zur 
Information, die übertragen werden soll, keine Rolle spielen, zur 
Datenübertragungsrate gehören sie.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, dann hast Du Dir Deine Frage ja schon selbst beantwortet.

Eine mit 1 MBaud betriebene UART überträgt maximal 800 kByte/sec an 
Nutzdaten. Bei der asynchronen Datenübertragung mit UARTs werden 
Start-/Stop- und auch weitere Bits (Parity) bei Bit- und 
Baudratenbetrachtungen mitgezählt. Bei 8n1 werden für jedes Nutzbyte 
also 10 Bit übertragen.

von M. K. (sylaina)


Lesenswert?

Rufus Τ. F. schrieb:
> Eine mit 1 MBaud betriebene UART überträgt maximal 800 kByte/sec an
> Nutzdaten.

Wir reden hier die ganze Zeit von der Datenübertragungsrate des UART, 
von der Nutzdatenrate war bisher nie die Rede. In der Regel meint man 
beim UART auch nie die Nutzdatenrate wenn man von der Datenrate des UART 
spricht. Das sollte man dann vielleicht dazu sagen ;)

von AntiMaker (Gast)


Lesenswert?

M. K. schrieb:
> Fast Ethernet hat eine
> Datenübertragungsrate von 100 Mbps, Gigabit Ethernet hat eine
> Datenübertragungsrate von 1000 Mbps.

Ja.

> Hätten beide dieselbe Symbolrate,

Gigabit Ethernet: 125 MBaud, 2 Bit pro Symbol, 4 Adernpaare 
(bidirektional genutzt).
Fast Ethernet: 125 MBaud, 4 Bit pro 5 Symbole, 1 Adernpaar (pro 
Richtung).

von m.n. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Eine mit 1 MBaud betriebene UART überträgt maximal 800 kByte/sec an
> Nutzdaten.

Ich komme bei 8N1 auf maximal 100 kByte/s.
Wie auch immer: 1 MBd zu empfangen ist für einen AVR grenzwertig hoch. 
Da sind unter realen Bedingungen (weitere aktive ISRs) 
Übertragungsfehler vorprogrammiert - egal welche Schreibweise man 
vorzieht ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

M. K. schrieb:
> Wir reden hier die ganze Zeit von der Datenübertragungsrate des UART,
> von der Nutzdatenrate war bisher nie die Rede.

Natürlich war davon die Rede:

M. K. schrieb:
> avr schrieb:
>> Übertragen werden tatsächlich nur max. 800kb/s.
>
> Und wie kommst du denn auf die maximal 800 kb/s? Das wäre jetzt mal
> spannend.

von M. K. (sylaina)


Lesenswert?

Rufus Τ. F. schrieb:
> Natürlich war davon die Rede:

Die 800 kb/s hat heute mittag erst air ins Rennen gebracht, davor hat 
die keiner erwähnt. Da wurde ständig von der Datenübertragungsrate 
gesprochen und nie von der Nutzdatenrate. Die ist in diesem Fall ja auch 
maximal uninteressant.

von avr (Gast)


Lesenswert?

M. K. schrieb:
> Die 800 kb/s hat heute mittag erst air ins Rennen gebracht, davor hat
> die keiner erwähnt. Da wurde ständig von der Datenübertragungsrate
> gesprochen und nie von der Nutzdatenrate. Die ist in diesem Fall ja auch
> maximal uninteressant.

Ich wollte dich eigentlich darauf hinweisen, dass du Begriffe und 
Einheiten verwechselst, bzw. falsch verwendest.

Die Datenübertragungsrate bei einem 1MBd Uart beträgt max. 800kb/s.
Start- und Stopp-Bits sind, auch wenn sie leider so genannt werden, 
keine richtigen Bits. Sie enthalten keinerlei Information. Du kannst mit 
einem 1MBd Uart eben keine 1Mb/s übertragen.

Wenn du von den 8 Datenbits/UART-Frame eines als Parity-Bit nutzt, dann 
überträgst du immernoch 800kbit/s. Die Nutzdatenrate beträgt aber nur 
noch 700kbit/s.

Was dich interessiert, ist die Symbolrate - also wie viele Symbole pro 
Sekunde übertragen werden. Beim UART gibt es nur 2 Symbole, welche 
Datenbits, Start oder Stopp-Bits sein können. Genau die Symbolrate musst 
du durch die Register einstellen. Und die Einheit der Symbolrate ist 
nunmal Baud.

von M. K. (sylaina)


Lesenswert?

avr schrieb:
> Die Datenübertragungsrate bei einem 1MBd Uart beträgt max. 800kb/s.
> Start- und Stopp-Bits sind, auch wenn sie leider so genannt werden,
> keine richtigen Bits. Sie enthalten keinerlei Information. Du kannst mit
> einem 1MBd Uart eben keine 1Mb/s übertragen.

Ich versuch das mal aufzudröseln: 1 MBd sind 1 Million Zeichen pro 
Sekunde. Damit sind dann nur 800 kb/s möglich. OK. Jetzt spanne ich nur 
mal den Bogen zurück zum Beginn der Diskussion: Im Datenblatt steht aber 
nicht 800 kb/s und auch nicht 1 MBd. Nein, da stehen 1 Mbps. Nichts mit 
Baud oder ähnlichem. Rechnen wir das auf Baud um sind wir hier bei 1.2 
MBd.

Falsch ist das aber immer noch.
Die Baudrate, oder auch Symbolrate, gibt per Definition an, wie oft sich 
auf einem Kanal in einer Sekunde, der Zustand ändern kann.
Die Bitrate, oder auch Datenübertragungsrate, gibt an, wie viele Bits 
(ganz egal ob Overhead ist oder Nutzdaten) in einer Sekunde auf einem 
Kanal übertragen werden können.

Auch wenns nicht gefällt, auch ein Start- und Stoppbit müssen übertragen 
werden, diese auszusparen ist schlichtweg falsch. Daher ist beim Uart 
der Sonderfall, dass Baud- und Bitrate identisch ist. Und das kann man 
auch überall im Netz bzw. in entsprechender Literatur nachlesen wenn man 
ambitioniert ist. Zum Beispiel hier, was wohl zu den ersten Treffern bei 
Google gehören dürfte: 
https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
> Eine mit 1 MBaud betriebene UART überträgt maximal 800 kByte/sec an
> Nutzdaten.

Ich muss mich korrigieren. Es sind natürlich nicht 800 kByte/sec, 
sondern es sind 80 kByte/sec.

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
Noch kein Account? Hier anmelden.