Ожидание между кадрами UART

Мне нужно воспроизвести сигнал (из 6 кадров UART), который имеет задержку 950 мкс между каждым из кадров. Затем задержка 37 мс в конце этих кадров.

Все в порядке, за исключением задержки между кадрами... Скорость передачи данных составляет 9600 бод.

Вот мой текущий код:

  Serial1.write(sw_binary_train_1);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_2);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_3);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_4);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_5);
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_6);
  delay(37);

, 👍0

Обсуждение

Является ли «Serial1» серийным программным обеспечением? Потенциально синхронизация может быть более точной при использовании аппаратного последовательного порта. Также вы можете проверить, работает ли увеличение или уменьшение задержки. Обычно принимающая сторона имеет своего рода «мертвую зону» (она должна быть между 900-950 мкс), и при значении 950 мкс вы можете просто выйти за пределы этого значения в некоторые моменты). Кроме того, вы должны попробовать поставить "Serial1.flush();" чтобы убедиться, что все байты отправлены (а не только помещены в очередь)., @Paul

Нет, я на Arduino Micro. Хорошо, я должен использовать задержку (1) вместо задержки микросекунд (950)? Между каждым кадром или в конце всех кадров?, @Martin.G

После еще нескольких тестов для задержки 950 мкс я должен установить delayMicroseconds (1900) ... Немного странно, но это работает ;)!, @Martin.G


2 ответа


1

set delayMicroseconds(1900) делает задержку 950 мкс между кадрами... Странно, но работает!

,

Приятно слышать, что вы нашли решение, возможно, вы все еще можете взглянуть на serial.flush(); (а потом задержать). Но если другой вариант работает для вас, это может быть нормально., @Paul

На самом деле delayMicroseconds() не находится между кадрами. Это больше или меньше времени для кадра плюс 950 мкс дополнительного пространства. Дополнительные 1000 мкс — это время, которое USART ISR помещает символ в выходной аппаратный буфер, плюс время для битов 1+8+1, которое составляет прибл. 1 мс при 9600 бит/с. Serial.write() не является синхронным для аппаратного USART., @Mikael Patel


1

В этом нет ничего странного. Serial не блокируется во время отправки. Когда вы вызываете запись, которая помещает байт в буфер отправки, и все. Затем код переходит к следующей инструкции, задержке (950), и в течение этого времени фактически отправляются последовательные данные. Для этого требуется около 1 миллисекунды.

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

Лучшим решением было бы:

  Serial1.write(sw_binary_train_1);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_2);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_3);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_4);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_5);
  Serial1.flush();
  delayMicroseconds(950);
  Serial1.write(sw_binary_train_6);
  Serial1.flush();
  delay(37);

Flush блокируется до тех пор, пока буфер отправки снова не станет пустым. Таким образом, вам не нужно учитывать это время, и все, для чего вам нужна задержка, — это время между передачами.

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

for (int i=0; i<6; i++){
  Serial1.write(sw_binary_train[i]);
  Serial1.flush();
  delayMicroseconds(950);
}
delay(37)

выглядит намного лучше.

,