Làm thế nào cao tốc độ baud tôi có thể đi (không có lỗi)?


40

Tiêu chuẩn là 9600 baud. Đó chỉ là tiêu chuẩn . Sử dụng Arduino Uno SMD R2, tốc độ truyền thực tế cao nhất tôi có thể đạt được là bao nhiêu?

Điểm thưởng cho sự táo bạo: Làm thế nào bạn sẽ tạo ra một cơ chế kiểm tra lỗi và sau đó tăng tốc độ baud cao một cách vô lý để có được tốc độ truyền cao?


1
Điều đáng chú ý là các bo mạch Arduino sử dụng IC nối tiếp USB FTDI có thể thực sự nhanh chóng. FT 232 thông thường có thể đi được 3 Megabaud (tức là 3.000.000 baud) mà không gặp vấn đề gì. Việc sử dụng ATmega16U2 là yếu tố hạn chế.
Sói Connor

Bản sao Arduino Nano mà tôi nhận được từ eBay đạt tối đa 1.099.999. Nghiêm túc. Nó đã làm. Khi nó đạt 1.100.000, sản lượng bị cắt xén. laqq`na`fca`fga`fga`bcngaah````iin`ha`a`a`bga`fga`bcqpahhqfq```fh`oopa`bca`fca. Nó sử dụng chip CH340 cho comms USB.
PNDA

Câu trả lời:


59

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:
nhập mô tả hình ảnh ở đây

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:

nhập mô tả hình ảnh ở đây

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:
nhập mô tả hình ảnh ở đây
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: nhập mô tả hình ảnh ở đây

1 Mbaud: nhập mô tả hình ảnh ở đây

2 Mbaud: nhập mô tả hình ảnh ở đây
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 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ó.


4
Minh họa tốt đẹp của giới hạn thông lượng!
jippie

1
@AnnonomusPerson - Nếu bạn chuyển sang đồng hồ 20 Mhz, bạn có thể thực hiện 2,5 Mbps.
Sói Connor

1
@AnnonomusPerson - Bạn cần trao đổi cả hai hoặc sử dụng giao diện nối tiếp usb FTDI với bộ dao động ATmega328P 20 Mhz. ATmega328P không thể thực hiện 2,5 Mb / giây nếu không có bộ cộng hưởng / tinh thể 20 Mhz. Điều này cũng đúng với mọi giao diện ATmega16U2.
Sói Connor

1
Câu trả lời chính xác! Chỉ cần một hiệu chỉnh nhỏ: ở tốc độ 2 Mb / giây, mỗi lần truyền byte mất 80 chu kỳ CPU chứ không phải 64. Điều này là do, theo thời gian, mỗi byte có giá trị 10 bit (1 bắt đầu, 8 dữ liệu, 1 điểm dừng).
Edgar Bonet

1
@ linhartr22 - Dây điện chỉ thực sự phát huy tác dụng nếu chúng dài , như trong 12 "+. Tôi nghĩ có lẽ không có nhiều người sử dụng dây cáp dài 100 feet quá nhiều. Bên cạnh đó, câu hỏi là arduino / ATmega cao đến mức nào tốc độ baud có thể đi, chứ không phải mức độ lắp ráp cáp tùy ý có thể cao đến mức nào
Connor Wolf

7

Cửa sổ Arduino serial Monitor giới hạn bạn đến 115200, nhưng đó không phải là tốc độ truyền cao nhất có khả năng. Bạn có thể đọc các bảng dữ liệu Atmel và FT 232 (hoặc bất cứ thứ gì bạn đang sử dụng) để tìm ra mức tối đa nhưng tôi có thể sử dụng thành công 230400 (nhanh gấp đôi so với Arduino serial Monitor hỗ trợ) mà không gặp vấn đề gì.

Nếu bạn muốn xem kết quả trong máy tính của mình, bạn sẽ cần một màn hình nối tiếp khác hỗ trợ các tùy chọn tốc độ truyền khác. Tôi thích CoolTermMối .

Hãy lưu ý rằng điều này phụ thuộc rất nhiều vào tốc độ đồng hồ của bạn.

Đây là một máy tính để giúp bạn tính toán những gì có thể.


Khi bạn bắt đầu đi nhanh hơn và nhanh hơn, giới hạn sẽ trở thành thư viện Nối tiếp - việc triển khai không hiệu quả lắm.
Cyberg Ribbon

trang web của liên kết đã chết
Codebeat

3

Đây có lẽ là một trong số ít các khía cạnh mà bảng el-Cheapo khác với bảng gốc. Tốc độ truyền nối tiếp tối đa là khá nhiều chỉ bị giới hạn bởi chất lượng của bảng và bố cục của nó. Khi dữ liệu nối tiếp nhập vào chip giao diện AVR hoặc USB, dữ liệu sẽ được xử lý khác với giao thức UART nối tiếp.

Hãy nhớ rằng mặc dù vi điều khiển có một số phần cứng cơ bản để chuyển / xuất dữ liệu nối tiếp sang / từ các chân IO, nhưng tốc độ tối đa tuyệt đối được giới hạn ở xung nhịp 16 MHz (đối với AVR). Khi một byte được chuyển đến bộ đệm nối tiếp, phần cứng UART sẽ tự xử lý và tự đẩy ra / kéo các bit. Một AVR tốt nhất đạt 16M hướng dẫn mỗi giây và các ngắt được sử dụng để lấp đầy bộ đệm nối tiếp có một số chi phí (ít nhất 8 đồng hồ để xử lý ngắt + hướng dẫn để lưu trạng thái hiện tại + một số hướng dẫn để thực sự lấp đầy bộ đệm). Với tốc độ bit cho trước, giao thức sẽ chạy với tốc độ n bit mỗi giây, nhưng bộ điều khiển của bạn cần nhiều thời gian hơn để lấp đầy bộ đệm nối tiếp so với nhu cầu thực sự xuất dữ liệu, dẫn đến thông lượng trung bình thấp hơn bạn mong đợi và UART không hoạt động trong một thời gian tương đối dài

Một hiệu ứng khác cần nhớ là tất cả chi phí cần thiết để đẩy dữ liệu ra UART (hoặc kéo dữ liệu vào) không thể được sử dụng trong chương trình thực tế của bạn, một lần nữa ảnh hưởng đến thông lượng thực tế trung bình. Bạn chỉ có thể sử dụng mỗi chu kỳ hướng dẫn một lần, để điền vào bộ đệm hoặc để tính toán vòng lặp chính.

Do đó, thông lượng tối đa phụ thuộc vào ứng dụng bạn sử dụng (tốc độ được tạo / tính toán / sẵn sàng di chuyển đến / từ bộ đệm nối tiếp) và tốc độ bit 'vật lý' thực tế chỉ là một phần nhỏ trong quyết định thiết kế.


1
Tôi thực sự, thực sự nghi ngờ bất kỳ bảng nào ngoài đó có vấn đề bố trí đủ nghiêm trọng để ngăn tín hiệu 2 Mhz hoạt động tốt. 2 Mhz không chính xác tần số cao.
Sói Connor

@FakeName Ít nhất một bảng trên bàn của tôi ở đây đã tăng BER khi tôi đẩy tốc độ nối tiếp. Tôi thường sử dụng 9600, như vậy là quá đủ cho hầu hết các ứng dụng và mạnh mẽ.
jippie

Không đùa đâu! Huh. Tôi tự hỏi làm thế nào xấu bố trí phải có để điều đó xảy ra? Tuy nhiên, tôi nghi ngờ nó không bố trí nhiều như các bộ cộng hưởng / tinh thể dung sai kém.
Sói Connor

1
Tốc độ baud cao, đặc biệt nếu U2Xn = 1ở USART, có xu hướng trở nên khá khó chịu về sự không phù hợp.
Sói Connor

@FakeName Tôi là một con khủng long, tôi giống như "9600 8N1" vì tất cả các lý do di sản sai mà bạn có thể nghĩ ra; o)
jippie

2

Kiểm tra lỗi thực sự rất dễ dàng và có một lib lib thực hiện điều này trong một lớp lót.

Đọc lên util/crc16.hvà bạn sẽ tốt để đi trong thời gian không với các ví dụ bao gồm.

CRC khá mạnh mẽ và nhanh chóng cho các ứng dụng đơn giản.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.