Главная arrow Начинающим arrow Пробуем программировать arrow Простая работа с периферийными портами в Windows  
13.01.2025 г.
Главная
Проекты
Статьи
Начинающим
Архив новостей
Ссылки
Контакты
Поиск
Файлы
Форум
Карта сайта
Авторизация
Админцентр
Поддержи наш сайт!
Через WebMoney

 R785211844650
 Z210696637574
 E368177590409

Простая работа с периферийными портами в Windows Печать E-mail
Рейтинг: / 14
ХудшаяЛучшая 
Автор ARV   
06.12.2007 г.

Статей на тему работы с СОМ-портом или LPT в Windows известно много, однако большинство из них посвящены низкоуровневому доступу, т.е. через доступ к аппаратным портам ввода-вывода. Подобный подход унаследован из времен MS DOS, где был практически единственным, и потому правильным. В Windows вплоть до NT-подобных версий подобный подход так же был возможен, хотя крайне не приветствовался. А в последних версиях Windows прямой доступ к аппаратным портам ввода-вывода практически невозможен без особых ухищрений, о которых, собственно, все и говорят.

Однако низкоуровневый доступ требует не только умения программировать. Обычно требуются специальные драйверы и (или) библиотеки, «обманывающие» ОС и позволяющие сделать то, что нельзя, т.е. обратиться напрямую в порт. Наконец, низкоуровневая работа требует так же приличных знаний аппаратного строения системы, т.к. LPT-порт физически представлен в виде 3 портов ввода-вывода (для стандартного режима), а COM-порт управляется уже минимум 4-мя...

 

Все эти тонкости не делают работу с параллельным и последовательным портом компьютера простой задачей для начинающих. Но ведь для большинства любительских задач никаких ухищрений не требуется, все необходимое для корректной работы с упомянутыми портами в ОС Windows уже встроено! И об этом пути я и хочу рассказать.

Надеюсь, читающие эти строки знают, что такое файловый ввод-вывод. Так вот, вывод в параллельный порт байтов элементарно реализуется с его помощью! Для этого всего-навсего нужно открыть файл (правильнее было бы сказать «устройство» или «поток», но не будем придираться к терминам) со стандартным именем «LPT1», а потом выводить в него требуемые байты! Только есть одно маленькое «но», которое, возможно, создавало впечатление невозможности такого простого подхода. Это «но» заключается в том, что функции вывода байтов, как правило, отрабатывают прекрасно, а выводимые данные на выводах разъема LPT не появляются... Это происходит потому, что драйвер параллельного порта перед выводом сигналов на линии обязательно желает быть уверенным, что к порту подключено готовое принимать данные устройство. И убеждается в этом он по уровню на контактах 11 и 12. Один из этих контактов соответствует сигналу «бумага кончилась» (Paper End), а другой - «устройство занято» (BUSY). Эти сигналы получили название, как вы догадались, от принтеров, которые совсем недавно только и подключались к параллельному порту. Если на этих контактах не будет низкого уровня, драйвер Windows будет считать, что устройство к приему данных не готово, а значит и выводить данные нельзя. Т.е. для того, чтобы описанный выше прием файлового вывода данных в LPT-порт заработал, необходимо и достаточно соединить контакты 11 и 12 разъема порта с любым «земляным» контактом (а земля, как известно, присутствует на контактах с 18-го по 25-й разъема).

Любителям Delphi и Borland C++ придется отказаться от предоставляемых этими системами объектов типа TStream, а воспользоваться для работы функциями API Windows. Их потребуется всего 3: CreateFile, WriteFile (или WriteFileEx) и CloseHandle. Описание параметров этих функций можно легко найти в справочном файле Windows SDK, который входит в состав Delphi или С++. Главное, вывод надо вести по одному байту, т.к. при попытке вывести какой-то массив данных, они будут выведены ОС с максимально возможной скоростью, что, скорее всего, вас не устроит. Кроме того надо учитывать, что кроме байтов, появляющихся на шине данных LPT-порта, драйвер ОС будет формировать и дополнительные сигналы на вспомогательных линиях, т.е. их желательно не использовать, не изучив детально протокол связи CENTRONICS.

Работа с СОМ-портом реализуется чуть более сложным образом. Во-первых, следует разделить ее на 2 части: обмен данными с другим аналогичным портом (например, микроконтроллером или модемом) и работа с отдельными линиями СОМ-порта, например, для реализации каких-то нестандартных устройств (такими устройствами являются, в частности, все простейшие адаптеры для ISP-программирования микроконтроллеров).

Первый способ работы мало отличается от рассмотренного ранее, разве что открыть необходимо файл со стандартным именем соответствующего СОМ-порта. Как правило, порт «СОМ1» всегда присутствует в системе (если присутствует вообще). Скорость и режимы обмена можно настроить через диспетчер устройств Windows. Настройка режимов возможна и в программе, но сейчас говорить об этом мне не хотелось бы.

А вот работа вторым способом заслуживает особого рассмотрения. Управлять по отдельности выходными линиями СОМ-порта возможно, как возможно и контролировать уровни на входных линиях (кроме линии RX), и для этого надо воспользоваться парой функций Windows API. Кстати, на выход у СОМ-порта работают всего 3 линии: выход передатчика TX, а так же линии DTR и RTS, а на вход (не считая линии приемника RX) - целых четыре: DCD, DSR, CTS и RI.
Функция EscapeCommFuntion позволит управлять уровнем на линиях DTR и RTS. Вызывается эта функция так: EscapeCommFunction(Port, Command), где Port - дескриптор открытого файла, возвращенного функцией CreateFile,
Command - одна из 4-х констант: SETRTS, CLRRTS, SETDTR и CLRDTR.

Уже по именам констант понятно, что для того, чтобы, например, установить высокий уровень на линии RTS, необходимо использовать константу SETRTS. Главное, не забыть о том, что уровни у СОМ-порта «перевернутые»: высокому уровню соответствует напряжение -9...-12В, а низкому +9...+12В.

 

Для управления уровнем в линии TX надо применить ту же самую функцию, но с другими константами: CLRBRAK для установки низкого уровня и SETBREAK для установки высокого.

Чуть сложнее осуществляется контроль уровней на входных линиях. Для этого используется функция GetCommModemStatus(Port, Status), где Port - тот же самый дескриптор, а Status - переменная типа длинное целое, биты которой будут содержать информацию о различных параметрах СОМ-порта. Нас будут интересовать только значения, определяемые константами MS_RLSD_ON (для проверки уровня сигнала DCD), MS_DSR_ON (для проверки DSR), MS_CTS_ON (для проверки CTC) и MS_RING_ON (для линии RI). Например, для проверки состояния линии DSR мы можем воспользоваться такой функцией (пример для Delphi):

function DSR : boolean;
// возвращает уровень на линии DSR: TRUE если высокий, FALSE - если низкий
var Status : cardinal;
begin

GetCommModemStatus(Port, Status); // Port - ранее открытый дескриптор СОМ-порта
Result := (Status and MS_DSR_ON) <> 0;

end;

Аналогично и другие линии контролируются. Все упомянутые функции Windows API и константы описаны в файлах windows.h (для С++) и модуле windows (для Delphi), которые обязательно надо подключить к своему проекту.
Как видите, все очень просто. Не надо никаких обходных маневров, никаких «обманов» ОС, никаких вспомогательных драйверов или библиотек... Для работы не нужно привилегий администратора, т.к. данные функции не используют недопустимых действий. Именно таким образом работает программа LptSW. Есть, конечно, и небольшая ложка дегтя: функции эти довольно медленные, во всяком случае гораздо медленнее прямого обращения к портам. Но ведь далеко не всегда требуется огромная скорость работы? Чаще на первый план выходит простота и доступность...


Добавить в любимые (1) | Просмотров: 32867

  Ваш коментарий будет первым

Только зарегистрированные пользователи могут оставлять коментарии.
Пожалуйста зарегистрируйтесь или войдите в ваш аккаунт.

 
« Пред.
Полезные материалы по сходным темам
Кто на сайте?
Сейчас на сайте находятся:
1 гость
Помощь on-line
BannerFans.com