Последовательные данные получены с неправильными битами

У меня есть интерфейс RS422, настроенный между Arduino и изготовленным на заказ устройством. Устройство настроено на передачу 16-битного заголовка, за которым следуют 66 байт данных, со скоростью 460 800 бод и частотой 200 Гц. Это нельзя изменить.

Я читал в Интернете, что последовательный порт Arduino может без проблем обрабатывать 460 800 бит/с. На самом деле, я без проблем успешно обменивался данными между MatLab и Arduino на этой скорости. Я также подтвердил, что устройство работает, так как при прямом подключении к компьютеру оно читается нормально.

Когда я пытаюсь прочитать данные с помощью Arduino, я не получаю ожидаемого результата. Я должен получить заголовок 0x55AA. Однако большую часть времени я получаю 0xD56A, но иногда я получаю такие значения, как 0xB5CA. Кажется, что вторая половина каждого байта верна, но не первая, и у меня есть некоторые биты, которые становятся высокими, а некоторые - низкими, когда они не должны. Из-за этого я сомневаюсь в достоверности передаваемых данных.

Может кто-нибудь объяснить мне, почему это происходит, и какие решения я могу попытаться исправить, пожалуйста?

Спасибо

ОБНОВЛЕНИЕ: я просмотрел с помощью осциллографа, и я вижу форму волны, выходящую как 0x55AA, как и должно быть. Я увеличил последовательный буфер Arduino и сменил платы, но проблема не устранена.

Мне удалось заставить его работать на более низкой скорости (115 200 бод), но мне нужно установить ее на 460 800. При этой более низкой скорости я бы получил 0x55AA, но как только я увеличиваю ее до 460 800, я теряю эти данные, и они становятся такими, как указано выше.

Что заставляет вас думать, что есть только одна причина, по которой могут возникнуть описанные вами симптомы?
Если у вас есть доступ к прицелу, самое время им воспользоваться.
Вы когда-нибудь получали правильный заголовок?
@PlasmaHH Я не говорю, что есть только одна причина, я просто прошу объяснить, почему это происходит и как это решить.
@BrianDrummond Область показывает 0x55AA, как и должно быть.
@Tom: это кажется противоречивым. Вы сами говорите, что нет единой причины, почему это происходит, но хотите, чтобы мы рассказали вам, почему это происходит. Лучшее, что мы можем дать вам, — это предположение о сотнях возможных вещей, которые могли пойти не так, но у нас нет никакой информации о задействованном оборудовании или о том, как выглядят сигналы. Итак, на этом уровне причина, по которой это происходит, заключается в том, что данные неправильно передаются от А к Б.
@Andyaka Не на этой скорости. Однако я делаю это на более низкой скорости передачи данных. На этой скорости (460 800 бод) я получаю 0x952A, 0xD56A и т. д.

Ответы (2)

Во-первых, давайте посмотрим на данные, которые вы упомянули:

0x55AA  0101010110101010
0xD56A  1101010101101010
0xB5CA  1011010111001010

Как мы видим, данные близки, но немного отличаются. Причин того, что последовательные данные «слегка отклоняются», много, но очевидной в вашем конкретном случае является скорость последовательной передачи данных. Чтобы асинхронные последовательные данные принимались правильно, исходные часы должны быть воссозданы на принимающей стороне. Эмпирическое правило для последовательных соединений заключается в том, что если тактовая частота отличается более чем на 3%, вы получите ошибки, очень похожие на те, которые вы описываете.

Таким образом, при скорости 460 800 бит/с это чуть больше 2,27. мю с на бит. Вот несколько советов по устранению неполадок:

  1. проверьте часы битрейта на обоих концах и убедитесь, что частоты находятся в пределах 3% друг от друга.
  2. делайте проводку как можно короче.
  3. проверьте заделку линии на обоих концах, чтобы убедиться, что у нее такой же импеданс, как и у линии.
  4. проверьте полученный сигнал с помощью осциллографа. Ищите звонки или медленные переходы.

Вы также можете рассмотреть, есть ли в пакете CRC, который, по крайней мере, поможет вам обнаружить ошибку.

Как проверить часы

Во-первых, позвольте мне высказать свои предположения:

  1. каждая сторона может отправлять произвольные данные
  2. данные передаются в формате 8-N-1 (8 бит данных, без четности, 1 стоповый бит)
  3. вы можете настроить любой конец для непрерывной отправки

С учетом сказанного давайте посмотрим, как обычно отправляются последовательные данные. Давайте посмотрим на байты 0x55, 0x55, которые могут быть отправлены по несимметричному (RS-232) каналу передачи данных.

+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   
+---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   
  S   1   0   1   0   1   0   1   0   P   S   1   0   1   0   1   0   1   0   P 

На этой диаграмме Sначальный бит и Pстоповый бит, а 8 битов данных отправляются первым младшим значащим битом, как это обычно бывает. Глядя на это должно быть ясно, что если вы измерите частоту этого сигнала, она должна быть равна половине скорости передачи данных.

В конце сообщения есть контрольная сумма, но поскольку я не могу правильно подобрать заголовок, я не особо доверяю остальным данным, включая значение контрольной суммы. У меня есть ощущение, что это, скорее всего, тактовая частота. Раньше он работал со скоростью 115 200 бод, но мне пришлось это изменить. 2,27 мкс действительно довольно короткий. Как мне это проверить?

Какую тактовую частоту вы используете?

С тактовой частотой 8 МГц я не могу найти приемлемое значение прескалера для 460800 бод. 14,7456 МГц может подойти («Калькулятор скорости передачи AVR от WormFood»).