Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Завершение асинхронной передачи по COM-порту


Автор: nayk 21.4.2008, 13:15
Добрый день.

Работаю с устройством по RS-232. Устройство сделано так, что для передачи ему пакета данных нужно устанавливать RTS=false, а для приема от него RTS=true.
Запись в порт происходит в асинхронном режиме. 

Каким образом можно узнать, что передан последний байт для взведения сигнала RTS?

Автор: Felan 22.4.2008, 08:13
Никаким. Ты пишешь в буфер порта. А из этого буфера передает уже драйвер порта. Можно попробовать поиграться с аппаратным контролем потока. Или настроить драйвер что бы он сам выставлял RTS/DTR. Но ты не сможешь указать ему что делать с этими сигналами. Можно только сказать, что они должны изменяться, а как именно он это будет делать (сбрасывать или взводить) написано в стандарте. Я точно не помню.
В делфи константы настройки управления этими сигналами объявлены неправильно. 
Вот я давно делал http://forum.sources.ru/index.php?showtopic=173025&view=findpost&p=1462984... его можно настроить что бы он дергал эти сигналы.
Вобщем для примера сойдет.

Автор: nayk 22.4.2008, 13:23
Спасибо, посмотрю. У меня тоже свой класс для работы с портом. RTS взводит правильно, но на момент записи в порт его нужно убирать.

Пока не нашел ничего лучше задержки после записи в порт. Время задержки ставлю в зависимости от скорости порта и кол-ва записываемых байт:

Код

ComPort.SetRTS(false);
ComPort.Write(Buf, BufLength); // Buf: array of byte - пакет, BufLength - длина пакета
Sleep((BufLength+1)*ByteSpeed);
ComPort.SetRTS(true);


ByteSpeed - скорость записи одного символа в порт с учетом настроек.
Работает нормально. Пока оставлю так.

Автор: Felan 23.4.2008, 08:26
Это ты сам его взводишь/убираешь. А должен это делать !САМ ДРАЙВЕР! т.к. у тебя нет возможности отследить все ли передалось в канал из внутреннего буфера драйвера или нет.

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

В моем исходнике смотри все связанное с константами dcb_RtsControlDisable, dcb_RtsControlEnable, dcb_RtsControlHandshake. Ну и в MSDN посмотри, что они означают.

Автор: nayk 23.4.2008, 11:26
Про RTSControl я знаю. По хорошему нужно установить RTS_CONTROL_TOGGLE. Тогда высокий уровень сигнала на RTS будет выставлен на время передачи. Но мне нужно наоборот - на время передачи низкий уровень, а такого режима в настройках нет.

Автор: Felan 23.4.2008, 12:17
smile
Да... Это только инвертор ставить. Т.к. драйвер ведет себя так, как положено ему себя вести, если бы исползовался модем... Для другого не предназначен.
Это, мне кажется будет самое правильное.
Еще, из железных вариантов, сделать переходник, который будет возвращать эхо. Тогда сможешь по принятию полного эха определить момент, когда его нужно сбросить.

Почему-то у нас электронщики всегда делают наоборот :(.

Из нормальных программных средств... даже и не знаю, что можно применить. Попробуй почитать про event'ы, и overlapped режим... Может быть там что-то будет, тут я уже точно не знаю.

Автор: nayk 23.4.2008, 13:28
Девайс такой собрали - преобразователь RS-232 <-> RS-485. Он вот так работает.
Через него подключено устройство, с которым нужно обмениваться данными.
Придется поднять вопрос по переделке адаптера начальству.  smile 

Ладно. Спасибо за помощь, Felan.

Автор: Felan 24.4.2008, 09:12
Цитата(nayk @  23.4.2008,  15:28 Найти цитируемый пост)
Девайс такой собрали - преобразователь RS-232 <-> RS-485. Он вот так работает.

Ага, я тоже когда-то занимался разработкой для таких девайсов... по MODBUSу работающих. У нас как раз переходник эхо возвращал.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)