Столкнулся с тем, что расстояние между последовательными передачами по интерфейсу составляет 13мс. Т.е. скорость передачи соответствует, а вот если передаю по два байта - Код (Text): while(true) { WriteInCom(...); } , то выходят они в линию через время 13 мс и никак не раньше. Использую функцию WinAPI WriteFile(). Это так и есть в СОМ-порте или у меня руки не оттуда растут?
Приёмного, что ль? Не, оно намного быстрее работает. Я тут разобрался маленько. В процедуре ещё ботва всякая была типа очистки буфера. Если оставить только запись, то получается минимальное время 50мкс. А вот максимальное. Максимальное время задержки между передачами оговорено где-нибудь?
FatMoon Да, я читал об этом. Вот что смущает. Допустим, скорость у меня сейчас 500.000 бит/c. Т. о., передача одного байта займёт приблизительно 10бит * 2мкс = 20 мкс. Таймоуты измеряются в миллисекундах. Т.о., я могу устанавливать 1, 2, 3 и т.д. всякие задержки. Однако 1 мс - слишком много для меня. Да и установлены они сейчас в минимум - по нулям. Означает ли это, что сейчас задержек нет никаких при передаче? Иначе говоря, что, о задержках меньше 1мс сказать ничего нельзя и мне принимать за промежуток времени между передачей двух разных байт 1мс? Буду весьма признателен за толковый ответ.
Phuntik Из твоего описания кроме того что ошибка в твоем коде непонятно ничего. Соответствует чему? Из кода ничего не понятно, где тут два байта передаются? Судя по всему тут и ошибка. Меня честно слово смущает точка в числе 500.000 т.е получается 500 и это будет не микросикунды, а милисикунды. А еще частоты 500 не бывает есть 600 и 300 10/600=0.016667=16.66 мс. Дальше разговор бессмыслен так как вы уже тут явно путаетесь. Потому что стандартный COM больше 128000 бод/ в с не выдает.
Есть специализированые устройства со своими драйверами (платы расширения RS232(COM)/RS485/RS422), которые поддерживают большие скорости, в т.ч. 500кбод. Но тут явно разговор "не про то"-"не про сё"
Pavia Ошибка действительно была. Кроме записи, в цикле выполнялась ещё очистка буфера и некоторые проверочные операции. Видимо, это всё и занимало 13 мс. Вот такой код теперь: Код (Text): while(true) { port->WriteByte(100); } bool ComPort::WriteByte(const BYTE& B) { DWORD realWrite = 0; if(WriteFile(handle, (void*)&B, 1, &realWrite, NULL)) { return realWrite == 1; } return false; } Теперь время между посылками составляет от 50мкс до не знаю какого значения. Вот это значение я и хотел узнать. Соответствует скорости передачи, т.е. при скорости 500 тыс. длительность одного бита 2мкс. Использую не стандартный порт, а устройство на микросхеме СР2101 с USB-интерфейсом. Там есть скорость 500000 бит/с. Вот про неё и говорю. RET Да, это я сглупил. В общем, очевидно, что вопросы задавать не умею. Попробую ещё раз. Имеется пассивное устройство, работающее по интерфейсу RS-232 через USB-адаптер на микросхеме СР2101 (эмулятор СОМ-порта). От устройства нужно принимать побайтно информацию через равные промежутки времени. Если бы оно само могло быть инициатором передачи, никаких проблем - я бы считывал информацию из буфера по мере её поступления. Но для того, чтобы получить байт, я должен передать байт. Отсюда вопрос - с какой максимальной частотой я могу делать передачу одного байта? Чем ограничено это значение и есть ли какое-то стандаризированное значение, допуски?
Phuntik Так не хорошо отправлять. Надо сразу во WriteFile писать столько байт сколько надо. Сам WriteFile займет сколько-то времени причем скорее всего порядка 10 мкс. В компьютере все шины рассчитанный на блочную передачу. Скорее всего ты упираешься в USB. Для PCI ISA COM это не так заметно. А вот в USB. Она работает так вопрос к устройству ответ от устройства. Плюс есть приоритеты. В частности для реализации механизма прерываний и сервисного обслуживания устройств. Вот прерывания там имеет фиксированные временные задержки. На до бы глянуть как конкретно СР210 работает с USB. Принципе минимум должен укладываться в доли мкс, а максимум не скажу я в USB плохо разбираюсь но вроде до 1 миллисекунды
Pavia Т.е. можно сказать, что время, через которое информация окажется в линии передачи, состоит из следующего: 1. Быстродействие компьютера - ~10мкс. 2. "Время реакции" USB. Для наихудшего случая - 1мс. Казалось бы, 1, ну две, миллисекунды. Но нет. Т.к. Windows многозадачная система, вполне может сложиться ситуация, что он в течение 10мс вообще не даст процессорного времени моей программе. Я так понимаю, полностью гарантировать заданную частоту передачи я смогу, если буду передавать запросы раз в 20 мс?
Phuntik А что вы собственно говоря делаете? Если пытаетесь сделать систему реального времени, то персональный компьютер нужно сразу выбросить. А если у вас просто датчик, который выдаёт данные только по запросу, то можно добавить в линию простейший контроллер, который будет через заданные интервалы посылать этот самый запрос.
Вставлю свои 5 копеек: Я контороллеры только в теории знаю, но, имхо, действительно лучше поставить домолнительный контроллер, как сказал Black_mirror который будет ком-хостом. Т.е. он будет опрашивать устройство сам, и сам же дёргать комп. Во многох МК есть UART. Поправьте, если так нельзя сделать =)
Phuntik Компьютер работает параллельно. Это надо принять это надо понять это лучше чем жесткое реальное время так как разные процессы не могут конкурировать за процессорное время. Вообще отпадает проблема как таковая. Правда из минусов не все распараллелино. Удорожание разработки компонентов. Но эти минусы малозаметны. Как тут уже скзали надо ставить микроконтроллер. А теперь о плюсах. Вместо сокрости в несколько 10-1000 байт вы получаете скорость в 1000-100000000 байт/с Для этого надо использовать блочную и асинхронную передачу.
Black_mirror и остальные. Свою ситуацию я описал в посте №9(нижинй абзац). Пока имеется устройство, которое может только отвечать на запрос. И ПК с операционной системой Windows. Сам в схемотехнических делах плохо шарю. Накидайте ссылочек, пожалуйста, про дополнительный контроллер, который может быть связующим звеном между компьютером и устройством. Pavia Ваш пост не очень хорошо понял. Эх, будь я сам разработчиком... Но тут же как. Прибор сделан, сроки просрочены, отчитываться нужно... Вот и пытаются выжать всё что можно, хотя понятно, что фэйл...(
Phuntik У вам приём и передача идёт ведь по отдельным проводам?! я имею ввиду от СР2101 к устройству. Тогда возможно следующее решение: Открываем и настраиваем порт. Создаём поток для отправки запросов. И выполняем в нём следующий код: while(WriteFile(hcom,"\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55" "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55",64,&res,0)&&res==64); Количество отправляемых символов должно быть достаточно большим, чтобы отправка выполнялась постоянно, без всяких пауз! Проверяем при помощи осцилографа. Далее смотрим сколько времени устройству требуется чтобы ответить на запрос, и в буфере после каждого байта запроса ставим байты, которые устройство будет молча игнорировать(если устройство пытается сообщать о непрвильных командах, то оторвать разработчикам руки), в количестве достаточном для получения ответа. Подгоняем размер буфера чтобы он был кранет размеру посылки, и был не меньше чем нужно для непрерывной передачи. Создаём поток для получения ответов. Ну и отдельный поток для общения с пользователем и тому подобного. Если такой метод работать не будет, то тогда попробую подробно рассказать вариант с контроллером. Хотя там придётся паять, там как минимум нужен: 1) Контроллер, который будет успевать управлять хотябы одной своей ногой, чтобы сформировать байт запроса на нужной скорости передачи (Еще может потребоваться принять байт, тогда микроконтроллер должен будет за время передачи стартового бита успеть войти в прерывание, которое формируется на отрицательному перепаду на принимающей(передающей) ноге, а дальше должен успевать принимать и сохранять принятые биты, чтобы мы могли потом проверить что за байт, нужно ли ему начать генерировать запросы, или прекратить это безобразие). 2) Микросхема типа MAX232 для преобразования уровней выдаваемых контроллером к напряжениям последовательного порта. 3) Источник питания 4) и еще возможно кварц. Вообще некоторые контроллеры имеют встроенные RC генераторы, но будет ли у них достаточная стабильность я не знаю. Еще как вариант - жестко пинать разработчиков, чтобы они перепрошили устройство и оно научилось самостоятельное непрерывно передавать данные(после получения некоторой команды разумеется). С технической точки зрения это самый простой вариант.
Black_mirror Да. Спасибо за подробный ответ. Подобное решение предлагалось разработчику. Он сказал, что так нельзя. Вообще изначально просчёт был допущен, когда контроллер не заложили в состав прибора. В итоге имеем цифровой осциллограф, собранный на логических элементах. В принципе, свои функции выполняет, но хотят ещё в режиме реального времени информацию получать 200 раз в секунду. С горе-разработчиками столкнулся, похоже. Говорят, что так не можно сделать (Альтеру используют). Если понадобится, за схемой обращусь, хорошо?
Как выяснилось, в винде многозадачность при работе последовательного порта сильно отсутствует, непрерыно читать и записывать его в различных потоках не получается, когда начинается чтение, запись притормаживает, видимо на время чтения и записи захватывается какой-то семафор. Но вот если вместо перемычки использовать два последовательных порта, то непрерывной передавать на одном, а принимать на другом вполне получается. То есть для программного решения задачи переходников USB-COM потребуется как минимум два. В процессе эксперимента использовались переходники: MOXA UPort 1150(этот поддерживает стандартные скорости до 115200, а так же 230К, 460К и 921К) TRENDnet TU-S9(этот несмотря на заявленную скорость 500К, скоростей выше 115К поставить не позволяет) Вывод отсюда такой, что переходники позволяют поставить далеко не всякую скорость.