Jest tu kilka czynników:
- Jaką prędkość transmisji może osiągnąć MCU ATmega328P?
- Jaką prędkość transmisji może osiągnąć interfejs szeregowy USB?
- Jaka jest częstotliwość oscylatora w ATmega328P?
- Jaka jest częstotliwość oscylatora na interfejsie szeregowym USB (jeśli taki posiada)?
- Jak tolerowany jest szeregowy interfejs USB niezgodności szybkości transmisji?
Wszystkie te czynniki są istotne dla określenia maksymalnej możliwej do osiągnięcia prędkości transmisji. ATmega328P wykorzystuje dzielnik sprzętowy na podstawie częstotliwości taktowania do generowania zegara bazowego dla interfejsu szeregowego. Jeśli nie ma stosunku liczb całkowitych z głównego zegara do czasu bitów żądanej prędkości transmisji, MCU nie będzie w stanie dokładnie wytworzyć żądanej prędkości. Może to prowadzić do potencjalnych problemów, ponieważ niektóre urządzenia są znacznie bardziej wrażliwe na niedopasowanie prędkości transmisji niż inne.
Interfejsy oparte na FTDI są dość tolerancyjne dla niedopasowania szybkości transmisji, nawet do kilku procent błędu. Jednak współpracowałem ze specjalistycznymi wbudowanymi modułami GPS, które nie były w stanie obsłużyć nawet 0,5% błędu prędkości transmisji.
Ogólne interfejsy szeregowe tolerują błąd ~ 5% prędkości transmisji. Ponieważ jednak każdy koniec może być wyłączony, bardziej powszechną specyfikacją jest +2,5%. W ten sposób, jeśli jeden koniec jest szybki o 2,5%, a drugi jest wolny o 2,5%, całkowity błąd nadal wynosi tylko 5%.
Tak czy inaczej. Uno używa ATmega328P jako podstawowego MCU, a ATmega16U2 jako interfejsu szeregowego USB. Mamy również szczęście, że oba te MCU używają podobnego USART Harware, a także zegarów 16 MHz.
Ponieważ oba MCU mają to samo oprogramowanie sprzętowe i częstotliwość taktowania, oba będą miały ten sam błąd szybkości transmisji w tym samym kierunku, więc możemy funkcjonalnie zignorować problem błędu transmisji.
W każdym razie „właściwa” odpowiedź na to pytanie wymagałaby wykopania źródła ATmega16U2 i opracowania stamtąd możliwych szybkości transmisji, ale ponieważ jestem leniwy, wydaje mi się, że proste, testy empiryczne będą działać.
Rzut oka na arkusz danych ATmega328P daje następującą tabelę:
Biorąc pod uwagę maksymalną podaną prędkość transmisji 2 Mb / s, napisałem szybki program testowy:
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");
};
A następnie patrząc na odpowiedni port szeregowy z terminalem szeregowym:
Wygląda więc na to, że sprzęt może działać bezproblemowo z prędkością 2 000 000 bodów.
Zauważ, że ta prędkość transmisji zapewnia MCU 64 80 cykli zegara na bajt, więc utrzymanie interfejsu szeregowego byłoby bardzo trudne. Podczas gdy poszczególne bajty mogą być przesyłane bardzo szybko, prawdopodobnie będzie dużo czasu, gdy interfejs będzie po prostu bezczynny.
Edycja: rzeczywiste testowanie!
2 Mb / s jest prawdziwe:
każdy czas bitów wynosi 500 ns, co odpowiada dokładnie oczekiwanemu.
Problemy z wydajnością! Całkowita długość pakietu:
500 Kbaud:
1 Mbaud:
2 Mbaud:
Uwaga: Zauważalne przekroczenie wynika z niewłaściwych praktyk uziemienia sondy pomiarowej i prawdopodobnie nie jest rzeczywiste. Używam ołowianego zacisku, który jest częścią mojej sondy lunety, a indukcyjność ołowiu jest prawdopodobnie przyczyną większości przeregulowania.
Jak widać, całkowita długość transmisji jest taka sama dla 0,5, 1 i 2 Mbodów. Wynika to z tego, że kod umieszczający bajty w buforze szeregowym jest słabo zoptymalizowany. Jako takie, nigdy nie osiągniesz niczego lepszego niż efektywne 500 Kbaud, chyba że napiszesz własne biblioteki szeregowe. Biblioteki Arduino są bardzo słabo zoptymalizowane, więc prawdopodobnie nie byłoby zbyt trudno zdobyć odpowiednie 2 Mbaud, przynajmniej dla transmisji seryjnych, jeśli spędziłeś na tym trochę czasu.