Работа с последовательными портами
Юрий Горский, Издательский Дом "КОМИЗДАТ"
В настоящее время существует множество устройств, которые обмениваются с компьютером информацией через последовательный порт (COM1, COM2) по протоколу RS-232. Причем такие устройства разрабатывают до сих пор и, я уверен, будут разрабатывать и в дальнейшем. Ведь несмотря на недостатки такой связи: медленная скорость обмена информацией, ограничение на длину соединительных линий — существует и немало достоинств: программная поддержка протокола RS-232 и ему подобных многими периферийными устройствами, специализированными микросхемами, низкая стоимость, минимальное количество соединительных проводов, простота.
Но, как это ни странно, информации по работе с последовательными портами в программах под Win32 очень мало. Материал этой статьи основан на статье Олега Титова “Работа с коммуникационными портами (COM и LPT) в программах для Win32”. Автором очень подробно описаны функции для работы с коммуникационными портами, основное внимание уделено синхронному обмену информацией. Мы же рассмотрим вариант обмена между компьютером и периферийным устройством в асинхронном режиме (как правило, используемом наиболее часто) — причем для простейшего соединения по трем проводам, без использования управляющих сигналов. Таким же образом можно организовать связь между двумя компьютерами (хотя бы для проверки работы своей программы).
Начнем с главного: с последовательными портами в Win32 работают как с файлами. Причем используют только функции API Win32. Начинается работа с открытия порта как файла, причем для асинхронного режима ввода-вывода возможен только один вариант:
HANDLE handle = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
Других вариантов быть не может, поэтому не будем рассматривать параметры этой функции подробно, единственное, что можно сделать — это заменить “COM1” на “COM2”. Больше последовательных портов на компьютере, как правило, нет. При успешном открытии порта функция возвращает дескриптор handle, с которым и будем работать в дальнейшем. При неудачном открытии порта функция вернет значение INVALID_HANDLE_VALUE.