Burada birkaç faktör var:
- ATmega328P MCU ne kadar yüksek bir baud hızı elde edebilir?
- USB-Seri arayüzü ne kadar yüksek bir baud hızı elde edebilir?
- ATmega328P'deki osilatör frekansı nedir?
- USB seri arayüzündeki osilatör frekansı nedir (eğer varsa)?
- Baud hızı uyumsuzluğunun USB seri arabirimi ne kadar toleranslıdır?
Bu faktörlerin tümü, ulaşılabilir maksimum baud oranının belirlenmesi ile ilgilidir. ATmega328P, seri arabirim için taban saati oluşturmak üzere saat hızından bir donanım böleni kullanır. Ana saatten istenen baud hızının bit zamanına tamsayı oranı yoksa, MCU istenen hızı tam olarak üretemez. Bazı cihazlar baud hızı uyumsuzluğundan ve diğerlerinden daha hassas olduğundan, bu durum olası sorunlara yol açabilir.
FTDI tabanlı arayüzler, baud hızı uyumsuzluğuna oldukça toleranslıdır, yüzde birkaç hataya kadar. Bununla birlikte,% 0.5 baud hızı hatasını bile kaldıramayan özel yerleşik GPS modülleri ile çalıştım.
Genel seri arayüzler ~% 5 baud hızı hatasına toleranslıdır. Ancak, her bir uç kapalı olabileceğinden, daha yaygın bir özellik% + -2.5'dir. Bu şekilde, eğer bir uç% 2.5 hızlı ve diğer% 2.5 yavaşsa, genel hatanız hala% 5'tir.
Neyse. Uno, birincil MCU olarak ATmega328P'yi ve USB seri arabirimi olarak ATmega16U2'yi kullanır. Bu MCU'ların 16 ABD doları ve 16 MHz saati gibi benzer donanım yazılımı USART kullandığı için de şanslıyız.
Her iki MCU da aynı donanım ve saat hızına sahip olduklarından, her ikisi de aynı yönde aynı baud hızı hatasına sahip olacak, böylece baud hatası sorununu işlevsel olarak görmezden gelebiliriz.
Her neyse, bu soruya verilen "doğru" cevap, ATmega16U2 kaynağını kazmayı ve olası baud oranlarını oradan çıkarmayı içerir, ancak tembel olduğum için basit, deneysel testlerin işe yarayacağını düşünüyorum.
ATmega328P veri sayfasında hızlı bir bakış aşağıdaki tabloyu üretir:
Yani maksimum 2 Mbps baud hızı verilen göz önüne alındığında, hızlı bir test programı yazdım:
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");
};
Ardından seri terminali bulunan ilgili seri porta bakın:
Böylece donanımın 2.000.000 baud'da sorunsuzca çalışabileceği anlaşılıyor.
Bu baud hızının yalnızca MCU 64 80 bayt başına saat döngüleri verdiğini unutmayın, bu nedenle seri arayüzü meşgul etmek çok zor olurdu. Bireysel baytlar çok hızlı bir şekilde aktarılabilse de, arayüz basitçe boştayken çok fazla zaman olabilir.
Düzenleme: Gerçek Test!
2 Mb / sn gerçektir:
her bir bit-zamanı 500 ns'dir ve bu beklenenlerle tamamen aynıdır.
Performans sorunları! Genel paket uzunluğu:
500 Kbaud:
1 Mbaud:
2 Mbaud: Not :
Dikkat çeken aşırı çekim, kapsam dışı prob topraklama uygulamalarından kaynaklanmaktadır ve muhtemelen gerçek değildir. Kapsam sondamın bir parçası olan toprak klipsi kullanıyorum ve kurşun endüktansı abartmanın çoğunluğunun sebebi.
Gördüğünüz gibi, toplam aktarım uzunluğu 0,5, 1 ve 2 Mbaud için aynıdır. Bunun nedeni, byte'ları seri arabellekte yerleştiren kodun zayıf şekilde optimize edilmiş olmasıdır. Dolayısıyla, kendi seri kütüphanelerinizi yazmadıkça, etkili bir 500 Kbaud'dan daha iyi bir şeyi asla başaramazsınız . Arduino kütüphaneleri çok kötü bir şekilde optimize edilmiştir, bu nedenle , eğer biraz zaman harcadıysanız, en azından patlama iletimleri için uygun bir 2 Mbaud elde etmek muhtemelen çok zor olmazdı .