Hier gibt es mehrere Faktoren:
- Wie hoch ist die Baudrate der ATmega328P-MCU?
- Wie hoch ist die Baudrate der USB-Serial-Schnittstelle?
- Was ist die Oszillatorfrequenz beim ATmega328P?
- Was ist die Oszillatorfrequenz an der USB-seriellen Schnittstelle (falls vorhanden)?
- Wie tolerant ist die USB-serielle Schnittstelle bei Baudratenfehlanpassungen?
Alle diese Faktoren sind für die Bestimmung der maximal erreichbaren Baudrate relevant. Der ATmega328P verwendet einen Hardware-Divisor aus seiner Taktrate, um den Basistakt für die serielle Schnittstelle zu generieren. Wenn zwischen dem Haupttakt und der Bit-Zeit der gewünschten Baudrate kein ganzzahliges Verhältnis besteht, kann die MCU die gewünschte Rate nicht exakt erzeugen. Dies kann zu potenziellen Problemen führen, da einige Geräte wesentlich empfindlicher auf Baudratenfehlanpassungen reagieren als andere.
FTDI-basierte Schnittstellen sind sehr tolerant gegenüber Baudratenfehlanpassungen, bis zu mehreren Prozent Fehler. Ich habe jedoch mit speziellen eingebetteten GPS-Modulen gearbeitet, die nicht einmal einen Fehler mit einer Baudrate von 0,5% bewältigen konnten.
Allgemeine serielle Schnittstellen tolerieren einen Baudratenfehler von ~ 5%. Da jedoch jedes Ende ausgeschaltet sein kann, beträgt eine häufigere Spezifikation + -2,5%. Auf diese Weise beträgt Ihr Gesamtfehler immer noch nur 5% , wenn ein Ende 2,5% schnell und das andere 2,5% langsam ist.
Sowieso. Das Uno verwendet einen ATmega328P als primäre MCU und einen ATmega16U2 als serielle USB-Schnittstelle. Wir haben auch das Glück, dass diese beiden MCUs ähnliche USARTs sowie 16-MHz-Uhren verwenden.
Da beide MCUs die gleiche Hardware und Taktrate haben, haben sie beide den gleichen Baudratenfehler in die gleiche Richtung, sodass wir das Problem des Baudfehlers funktional ignorieren können.
Die "richtige" Antwort auf diese Frage würde jedenfalls darin bestehen, die Quelle für den ATmega16U2 auszuloten und die möglichen Baudraten von dort aus zu ermitteln. Da ich jedoch faul bin, denke ich, dass einfache empirische Tests funktionieren werden.
Ein kurzer Blick auf das Datenblatt des ATmega328P ergibt die folgende Tabelle:
Angesichts der angegebenen maximalen Baudrate von 2 Mbit / s habe ich ein schnelles Testprogramm geschrieben:
void setup(){};
void loop()
{
delay(1000);
Serial.begin(57600);
Serial.println("\r\rBaud-rate = 57600");
delay(1000);
Serial.begin(76800);
Serial.println("\r\rBaud-rate = 76800");
delay(1000);
Serial.begin(115200);
Serial.println("\r\rBaud-rate = 115200");
delay(1000);
Serial.begin(230400);
Serial.println("\r\rBaud-rate = 230400");
delay(1000);
Serial.begin(250000);
Serial.println("\r\rBaud-rate = 250000");
delay(1000);
Serial.begin(500000);
Serial.println("\r\rBaud-rate = 500000");
delay(1000);
Serial.begin(1000000);
Serial.println("\r\rBaud-rate = 1000000");
delay(1000);
Serial.begin(2000000);
Serial.println("\r\rBaud-rate = 2000000");
};
Und dann mit einem seriellen Terminal auf die entsprechende serielle Schnittstelle schauen:
Die Hardware kann also problemlos mit 2.000.000 Baud betrieben werden.
Beachten Sie, dass diese Baudrate der MCU 64 nur 80 Taktzyklen pro Byte ermöglicht, so dass es sehr schwierig wäre, die serielle Schnittstelle beschäftigt zu halten. Während die einzelnen Bytes sehr schnell übertragen werden können, wird es wahrscheinlich viel Zeit geben, wenn die Schnittstelle einfach inaktiv ist.
Edit: Tatsächliches Testen!
Die 2 Mbit / s sind real:
Jede Bit-Zeit beträgt 500 ns, was genau dem entspricht, was erwartet wird.
Performance-Probleme! Gesamtpaketlänge:
500 kBaud:
1 MBaud:
2 MBaud: Hinweis: Das auffällige Überschwingen ist auf schlechte Erdungspraktiken der Oszilloskopsonde
zurückzuführen und wahrscheinlich nicht real. Ich verwende die Masseklemme, die Teil meiner Oszilloskop-Sonde ist, und die Leitungsinduktivität ist wahrscheinlich die Ursache für den Großteil des Überschwingens.
Wie Sie sehen, ist die Gesamtübertragungslänge für 0,5, 1 und 2 MBaud gleich. Dies liegt daran, dass der Code, der die Bytes in den seriellen Puffer legt, schlecht optimiert ist. Als solches werden Sie niemals etwas Besseres als effektive 500 Kbaud erreichen, es sei denn, Sie schreiben Ihre eigenen seriellen Bibliotheken. Die Arduino-Bibliotheken sind sehr schlecht optimiert, so dass es wahrscheinlich nicht allzu schwierig wäre, richtige 2 MBaud zu erhalten, zumindest für Burst-Übertragungen, wenn Sie ein wenig Zeit damit verbringen.