Работа с двойной скоростью для USART на Arduino Mega 2560

Я случайно просматривал файл HardwareSerial.cpp, содержащий функции, используемые для последовательной связи для Arduino. Просматривая функцию HardwareSerial::begin(baud, config), я заметил, что в регистре ucsra установлен бит U2X0. Когда я просматривал техническое описание, там говорилось, что бит U2X0 установлен для запуска работы с удвоенной скоростью. Из того, что я читал, это означает, что скорость передачи данных удваивается.
Я уже некоторое время использую этот Arduino на этом компьютере, и никаких жалоб на неправильную скорость передачи данных не было. Что такое Double Speed Operation? Почему она, кажется, установлена в коде по умолчанию? Я прикрепил код и раздел в руководстве ниже.

void HardwareSerial::begin(unsigned long baud, byte config)
{
  // Сначала попробуйте режим u2x
  uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
  *_ucsra = 1 << U2X0;

  // жестко запрограммированное исключение для 57600 для совместимости с загрузчиком
  // поставляется с платами Duemilanove и предыдущими платами, а также с прошивкой
  // на 8U2 на Uno и Mega 2560. Кроме того, baud_setting не может
  // будет > 4095, поэтому переключитесь обратно в режим не-u2x, если скорость передачи данных слишком
  // низкий.
  if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
  {
    *_ucsra = 0;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;
  }

  // назначаем baud_setting, он же ubrr (регистр скорости передачи данных USART)
  *_ubrrh = baud_setting >> 8;
  *_ubrrl = baud_setting;

  _written = false;

  //установить биты данных, четность и стоповые биты
  #if defined(__AVR_ATmega8__)
    config |= 0x80; // выбор регистра UCSRC (совместно с UBRRH)
  #endif
  *_ucsrc = config;

  sbi(*_ucsrb, RXEN0);
  sbi(*_ucsrb, TXEN0);
  sbi(*_ucsrb, RXCIE0);
  cbi(*_ucsrb, UDRIE0);
}

, 👍3


2 ответа


4

В режиме двойной скорости, как отмечено в руководстве, используется меньше образцов. В асинхронной последовательной связи тактовый сигнал отсутствует, поэтому тактовый сигнал, который поддерживает синхронизацию двух устройств, экстраполируется из сигнала данных. Каждый конец связи имеет свой собственный источник тактового сигнала (кварцевый генератор, керамический резонатор, RC-генератор и т. д.), и вы редко найдете два, которые откалиброваны одинаково.

Приемник производит выборку сигнала с более высокой скоростью, чем фактическая скорость передачи данных, чтобы он мог лучше определить, где относительно его собственных часов повышаются или понижаются фронты сигнала данных, и постоянно корректирует свое смещение для компенсации дрейфа часов.

При работе в режиме двойной скорости приемнику приходится работать с меньшим количеством выборок, поэтому, если источник тактовой частоты вашего передатчика существенно отличается от источника тактовой частоты приемника или нестабилен, или у вас длинные или шумные провода, или колеблются температуры (и т. д.), то вы можете столкнуться с менее стабильной связью.

Если ваш конкретный вариант использования работает нормально, то придерживайтесь его. Но если вы начнете замечать ошибки в коммуникации, первым шагом по устранению неполадок будет отключение этого режима, поскольку восстановление часов в этом режиме менее надежно.

,

2

Как поясняется в ответе Хосе Кана У С, в режиме двойной скорости UART имеет меньше образцов для выполнения часов и восстановления данных. Но это не помогает отвечая на второй вопрос:

Почему это, кажется, установлено в коде по умолчанию?

Режим двойной скорости также имеет преимущество: он обеспечивает более высокое разрешение в Установка скорости передачи данных. В нормальном режиме длительность бита ограничена быть кратным 16 тактам ЦП, тогда как при двойной скорости режиме он ограничен только кратностью 8 циклов.

В качестве примера предположим, что вам нужна скорость 57600 бит/с на частоте 16 МГц. Arduino. Затем,

F_CPU ÷ желаемая_скорость_передачи = 277,78 = 8 × 34,72 = 16 × 17,36

В односкоростном режиме это округляется до 16 × 17, а округление ошибка сделает скорость передачи данных 2,1% слишком быстрой. В режиме двойной скорости это округляется до 8 × 35, а скорость передачи данных всего на 0,8% медленнее. Таким образом, вы получить лучшую точность скорости передачи данных в режиме двойной скорости. Обратите внимание, что для некоторых Скорость передачи данных, например 9600 бит/с, одинарная скорость и двойная скорость дают точно такая же ставка.

Вероятно, именно поэтому ядро Arduino использует режим двойной скорости, за исключением задокументированного исключения совместимости и для чрезвычайно низких скорости передачи данных (двойная скорость не может работать ниже 488 бит/с).

Следует отметить, что это не единственная возможная стратегия. avr-libc, например, предоставляет некоторые вспомогательные макросы для скорости передачи данных вычисления. Эти макросы отдают предпочтение односкоростным режим и вернуться к удвоенной скорости только в том случае, если ошибка округления превышает указанный допуск, который по умолчанию составляет 2%.

,