Có một số yếu tố ở đây:
- ATmega328P MCU có thể đạt được tốc độ baud cao đến mức nào?
- Giao diện USB-serial có thể đạt được tốc độ baud cao đến mức nào?
- Tần số dao động trên ATmega328P là gì?
- Tần số dao động trên giao diện nối tiếp USB (nếu có) là gì?
- Giao diện nối tiếp USB của baud-Rate không phù hợp như thế nào?
Tất cả các yếu tố này có liên quan để xác định tốc độ truyền đạt tối đa. ATmega328P sử dụng bộ chia phần cứng từ tốc độ xung nhịp của nó để tạo đồng hồ cơ sở cho giao diện nối tiếp. Nếu không có tỷ lệ nguyên từ đồng hồ chính đến thời gian bit của tốc độ truyền mong muốn, MCU sẽ không thể tạo ra chính xác tốc độ mong muốn. Điều này có thể dẫn đến các vấn đề tiềm ẩn, vì một số thiết bị nhạy cảm hơn nhiều với sự không phù hợp tốc độ baud sau đó các thiết bị khác.
Các giao diện dựa trên FTDI khá chấp nhận sự không phù hợp tốc độ baud, lỗi lên đến vài phần trăm. Tuy nhiên, tôi đã làm việc với các mô-đun GPS nhúng chuyên dụng không thể xử lý ngay cả lỗi tốc độ baud 0,5%.
Các giao diện nối tiếp chung có khả năng chịu được lỗi ~ 5% tốc độ baud. Tuy nhiên, vì mỗi đầu có thể tắt, một thông số phổ biến hơn là + -2,5%. Bằng cách này, nếu một đầu nhanh 2,5% và đầu kia chậm 2,5%, lỗi tổng thể của bạn vẫn chỉ là 5%.
Dù sao đi nữa. Uno sử dụng ATmega328P làm MCU chính và ATmega16U2 làm giao diện nối tiếp USB. Chúng tôi cũng may mắn ở đây là cả hai MCU này đều sử dụng USARTs tương tự, cũng như đồng hồ 16 Mhz.
Vì cả hai MCU đều có cùng một phần mềm và tốc độ xung nhịp, cả hai sẽ có cùng một lỗi tốc độ baud theo cùng một hướng, vì vậy chúng tôi có thể bỏ qua vấn đề về lỗi baud.
Dù sao, câu trả lời "phù hợp" cho câu hỏi này sẽ liên quan đến việc khai thác nguồn cho ATmega16U2, và tìm ra tốc độ baud có thể từ đó, nhưng vì tôi lười biếng, tôi cho rằng thử nghiệm đơn giản, theo kinh nghiệm sẽ hiệu quả.
Nhìn lướt qua bảng dữ liệu ATmega328P tạo ra bảng sau:
Vì vậy, với tốc độ baud tối đa là 2 Mb / giây, tôi đã viết một chương trình thử nghiệm nhanh:
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");
};
Và sau đó nhìn vào cổng nối tiếp có liên quan với một thiết bị đầu cuối nối tiếp:
Vì vậy, có vẻ như phần cứng có thể chạy ở mức 2.000.000 baud mà không gặp vấn đề gì.
Lưu ý rằng tốc độ truyền này chỉ cung cấp cho MCU 64 80 chu kỳ xung nhịp trên mỗi byte, do đó sẽ rất khó khăn để giữ cho giao diện nối tiếp bận rộn. Mặc dù các byte riêng lẻ có thể được truyền rất nhanh, nhưng có khả năng sẽ có rất nhiều thời gian khi giao diện đơn giản là không hoạt động.
Chỉnh sửa: Thử nghiệm thực tế!
2 Mbps là có thật:
mỗi bit-time là 500 ns, khớp chính xác với những gì được mong đợi.
Vấn đề hiệu năng! Tổng chiều dài gói:
500 Kbaud:
1 Mbaud:
2 Mbaud:
Lưu ý: Việc vượt mức đáng chú ý là do thực hành nối đất thăm dò phạm vi kém, và có lẽ không có thật. Tôi đang sử dụng đầu nối đất là một phần của đầu dò phạm vi của mình và độ tự cảm của chì có thể là nguyên nhân của phần lớn các trường hợp vượt mức.
Như bạn có thể thấy, chiều dài truyền tổng thể là như nhau cho 0,5, 1 và 2 Mbaud. Điều này là do mã đặt các byte trong bộ đệm nối tiếp được tối ưu hóa kém. Như vậy, bạn sẽ không bao giờ đạt được bất cứ điều gì tốt hơn sau đó là 500 Kbaud hiệu quả , trừ khi bạn viết thư viện nối tiếp của riêng mình. Các thư viện Arduino được tối ưu hóa rất kém, vì vậy có lẽ sẽ không quá khó để có được 2 Mbaud thích hợp, ít nhất là cho truyền phát, nếu bạn dành một chút thời gian cho nó.