Главная   Назад  


RS-232.
Рекомендованный стандарт 232.
Интерфейс между терминалом данных и передающим оборудованием линии связи, применяющий последовательный обмен двоичными данными.

Автор:Яшкардин Владимир    
www.softelectro.ru    
2009              
electron18@softelectro.ru

Содержание:
§1.Вступление
§2.Описание стандарта RS-232
2.1 Разработчики и редакции стандарта RS-232
2.2 Краткая историческая справка
2.3 Международные и национальные стандарты, основанные на RS-232
2.4 Расширение стандарта RS-232
2.5 Содержание стандарта RS-232
2.5.1 Область применения RS-232
2.5.2 Характеристики сигналов RS-232C
2.5.3 Механические характеристики интерфейса. Разъем для интерфейса стандарта RS-232
§3.Описание COM портов персонального компьютера IBM XT
3.1 Основные свойства COM портов
3.2 Технические характеристики COM портов
3.3 Назначение сигналов СОМ порта по стандарту RS-232C
3.4 Уровни сигналов UART
3.5 Передача данных через UART
3.6 Соединительные кабели
3.7 Организация обмена данных при аппаратном режиме синхронизации
3.8 Организация обмена данных при программном режиме синхронизации
3.9 Описание контрольных битов (Parity Control Bit)
3.10 ASCII кодовая таблица
3.11 Аппаратная реализация СОМ портов
3.12 Программная реализация UART
3.13 Диагностический режим работы UART
§4 Программирование COM-порта
4.1. Программирование в MS-DOS
4.1.1. Программирование СОМ-порта прямым кодом микропроцессора
4.1.2. Программирование СОМ-порта с помощью функций BIOS
4.1.3. Программирование СОМ-порта с помощью средств MS-DOS
4.2. Программирование в Windows
4.2.1. Программирование СОМ-порта с помощью API функций Windows
4.2.2. Программирование СОМ-порта с помощью внешних компонент ActiveX
§5 Программное обеспечение для работы с COM портами ПК
§6.Заключение
Приложение 1. Примеры программирования

§1.Вступление

    RS-232 (Recommended Standard 232) - стандарт описывающий интерфейс для последовательной двунаправленной передачи данных между терминалом (DTE, Data Terminal Equipment) и конечным устройством (DCE,Data Circuit-Terminating Equipment ).
Это легендарный стандарт, который появился в 60-х годах 20 века, и стал основой для всех последующих интерфейсов последовательного обмена данными.
Интерфейс RS-232C был применен в первых персональных компьютерах фирмы IBM и до сегодняшнего дня входит в структуру любого персонального компьютера в аппаратном или программном виде.
Решения, которые заложены в этот стандарт, используются практически повсеместно.
Невозможно считать себя промышленным программистом не зная этого стандарта.
Интерфейс RS-232 полностью аппаратно реализован на персональных компьютерах в виде микросхем и разъемов .
В PC его называют COM-портом(Communication port).
Аппаратная реализация означает то, что он работает всегда, не зависимо, какая операционная система установлена на PC (он работает и без ОС).
Программы могут взаимодействовать с СОМ-портами всеми доступными средствами: прямым кодом микропроцессора, аппаратными прерываниями, функциями BIOS, средствами ОС, компонентами языков высокого уровня.
СОМ порт реализованный по стандарту RS-232- универсален.
Он обеспечивал работу PC с периферийными устройствами (чем сейчас занят USB), взаимодействие с локальной сетью через модем (Ethernet), обмен данными между PC и промышленным оборудованием ( ModBus и др.), чтобы разбираться как работают эти протоколы необходимо понимать какую функцию СОМ порта они взяли на себя.

§2.Описание стандарта RS-232

2.1 Разработчики и редакции стандарта RS-232

Обозначение стандарта:
RS-232(Recommended Standard 232).Рекомендованный стандарт 232.

Название:
Interface Between Data Terminal Equipment and Data Circuit-Terminating Equipment Employing Serial Binary Data Interchange.
Интерфейс между терминалом данных и передающим оборудованием линии связи, применяющий последовательный обмен двоичными данными.

Разработчики:
Electronics Industries Association (EIA). до 1997 года. Ассоциация промышленной электроники.
Electronics Industries Alliance (EIA)..  после 1997 года. Альянс отраслей промышленной электроники.
Telecommunications Industry Association (TIA).  совместно EIA c 1988 года. Ассоциация телекоммуникационной промышленности.

Выпуски стандарта:
RS-232A (Recommended Standard 232 Edition: A) год выпуска 1962.
RS-232B (Recommended Standard 232 Edition: B) год выпуска ????.
RS-232C (Recommended Standard 232 Edition: C) год выпуска 1969.
EIA 232-D (RS-232D - не официально) год выпуска 1986.
TIA/EIA 232-E (RS-232E - не официально) год выпуска 1991.
TIA/EIA 232-F (RS-232F - не официально) год выпуска 1997.



2.2 Краткая историческая справка.

    В 60-х годах прошлого века началось бурное развитие телекоммуникационных технологий.
Многочисленные фирмы США и других стран, выпускавшие оборудования связи, использовали собственные стандарты передачи данных.
Использование этого оборудования вызывало проблемы их совместимости.
Разъёмы, электрические характеристики сигналов, сервисные сигналы, способы синхронизации были различны у разных фирм.
Одни протоколы кодировали символы 4 битами, другие 5 битами и т.д. до 8 бит.
Отсутствие международного стандарта по последовательной передачи данных тормозило развитие телекоммуникационной отрасли.

    В 1962 году Electronics Industries Association (EIA) разработало рекомендации для производителей оборудования, назвав их "Рекомендованный стандарт 232".
Интерфейс RS-232 был разработан максимально универсальным , что позволяло многим производителям легко переделать своё оборудование под этот стандарт.
Кодировать символы допускалось от 5 до 8 бит, напряжение сигнала могло быть от ±3 до ±25 В и т.д.
Было предусмотрено 16 сервисных сигналов, использование которых было не обязательно.
Допускалась работа, как в синхронном, так и асинхронном режиме передачи данных.
Такая лояльность стандарта устраивала производителей телекоммуникационного оборудования.

    В 1969 году EIA выпустила редакцию стандарта RS-232C, в котором был учтен семилетний опыт применения стандарта RS-232A/В.
Окончательно был узаконен 25 штырьковый разъем DB25 и электрические характеристики сигнала.
Эта редакция стала основным интерфейсом передачи данных по последовательным каналам связи на многие годы вперед.
Международные и национальные стандарты стали включать части стандарта RS-232C в свои структуры.
В 1983 году фирма IBM выпустила персональные компьютеры IBM XT и 1984 году IBM AT с встроенными универсальными приемопередатчиками UART.
UART разрабатывались по стандарту RS-232C, он поддерживал передачу данных только в асинхронном режиме.
IBM XT поддерживал до 4-х независимых UART, которые назывались COM-портами (Communication port).
Первоначально разъемы СОМ-портов соответствовали стандарту RS-232C, т.е. использовали 25 штырьковый разъем DB25p.
Большая часть сервисных сигналов RS-232C в UART не использовалась.
Поэтому фирма IBM стала использовать в своих компьютерах 9-ти штырьковые разъемы DE9p, в которых использовались шесть сервисных сигналов стандарта RS-232C.
Чтобы узаконить использование этого разъема TIA выпустила новый стандарт TIA-574.
Стандарт TIA-574 разрешал использовать 9 штырьковый разъем в телекоммуникационном оборудовании, работающем по стандарту RS-232C.

    С развитием международных и национальных стандартов в области телекоммуникаций, роль EIA стала уменьшаться.
В 1986 году EIA для подержания своего имиджа заменило название стандартов с RS на EIA.
Роль ассоциации продолжала падать и её обязанности перешли к родственной ассоциации TIA.
Ассоциация TIA выпустила ещё две редакции стандарта RS-232C с наименованием TIA/EIA 232-E (1991) и TIA/EIA 232-F(1997).
Ничего нового в последовательной передаче данных эти стандарты не привнесли, они практически полностью повторяют стандарт RS-232C.
В 1997 году ассоциация EIA перестала существовать, её наследником стал альянс производителей промышленной электроники.
Сегодня EIA и TIA торговые организации.



2.3 Международные и национальные стандарты, основанные на RS-232.

Стандарт RS-232 стал основоположником целого ряда международных и национальных стандартов.
Ниже показаны некоторые из этих стандартов:

ITU-T v.24.  (2000г. действующий)
Издатель:
TELECOMMUNICATION STANDARDIZATION SECTOR OF ITU
Название: LIST OF DEFINITIONS FOR INTERCHANGE CIRCUITS BETWEEN DATA TERMINAL EQUIPMENT (DTE) AND DATA CIRCUIT-TERMINATING EQUIPMENT (DCE)
Старые редакции:
ITU-T v.24.  (1996г. не действующий)
ITU-T v.24.  (1993г. не действующий)
CCIT v.24.  (1988г. не действующий)

ITU-T v.28 .  (1993г. действующий)
Издатель:
TELECOMMUNICATION STANDARDIZATION SECTOR OF ITU
Название:ELECTRICAL CHARACTERISTICS FOR UNBALANCED DOUBLE-CURRENT INTERCHANGE CIRCUITS.
Старые редакции:
CCIT v.28   (1988г. не действующий)

ГОСТ 23675-79  (1979г.)
Издатель:
СССР. Государственный комитет по стандартам.
Название:Цепи стыка С2 системы передачи данных.

ГОСТ 18145-81  (1981г.)
Издатель:
СССР. Государственный комитет по стандартам.
Название:Цепи на стыке С2 аппаратуры передачи данных с оконечным оборудованием при последовательном вводе-выводе данных.

ГОСТ Р 50668-94 (1994г.)
Издатель:
НАЦИОНАЛЬНЫЙ СТАНДАРТ РФ
Название:Цепи стыка С2 системы передачи данных.

ANSI/TIA/EIA-232-F  (1997)
Издатель:
США. Американский национальный институт стандартов.
Название:Интерфейс между терминалом данных и передающим оборудованием линии связи, применяющий последовательный обмен двоичными данными.



2.4 Расширение стандарта RS-232.   [1]



2.5 Содержание стандарта RS-232 .   [1]

Оригинальная часть стандарта RS-232 содержит шесть секций.

1. Область применения.
2. Характеристики сигнала.
3. Механические характеристики интерфейса.
4. Функциональное описание сигналов обмена.
5. Стандартные интерфейсы для выбранных конфигураций системы связи.
6. Рекомендации и приложения.


2.5.1 Область применения RS-232.   [1]

Cтандарт RS-232 определяет взаимосвязи терминального оборудования ввода данных (DTE) и оконечного оборудования линии связи (DCE), использующих последовательный обмен двоичных данных.

Стандарт RS-232 включает тринадцать определенных конфигураций интерфейса, обозначенных латинскими буквами A-M.
И одной пользовательской конфигурацией, обозначаемой Z.
Конфигурация интерфейса должна указываться производителем коммуникационного оборудования.
Конфигурация интерфейса определяет состав сигналов, синхронность, порядок выставления сигналов, скорость и др.

Стандарт RS-232 предназначен для использования на скоростях не превышающих 20 000 бит/сек.

Стандарт RS-232 применяется в системах с общими электрическими проводами и не может применяться в системах где требуется гальваническая развязка цепей.

Стандарт RS-232 может применяться в синхронных и асинхронных системах последовательной передачи двоичных данных.

2.5.2 Характеристики сигналов RS-232.   [1]   [3]

На рис.1 показана эквивалентная электрическая схема при обмене последовательными данными по стандарту RS-232C. Эта эквивалентная схема независима от того, где расположен генератор в DTE или DCE.
Характеристики сигнала обмена данными по стандарту RS-232C включены в международный стандарт ITU-T v.28.

Рис.1 Эквивалентная электрическая схема RS-232C   [3]
Interchange equivalent circuit for RS-232

Стыком интерфейса RS-232C считается линия соединения DTE плюс кабель с DCE. То есть, соединительный кабель интерфейса входит в состав DTE.

Рис.2 Практическая схема стыка интерфейса RS-232C   [3]
Practical representation of the inferface RS-232

2.5.3 Механические характеристики интерфейса. Разъем для интерфейса стандарта RS-232 .

В качестве разъема для интерфейса RS-232C выбран миниатюрный разъем D-типа (D-subminiature).
        Для терминалов (DTE) - DB25p
        Для оконечных устройств (DCE) -DB25s
При использовании стандарта TIA/EIA 574 можно применять 9-ти штырьковые разъемы:
        Для терминалов (DTE) - DE9p
        Для оконечных устройств (DCE) -DE9s

Сейчас эти разъемы выпускаются многими фирмами по всему миру и указанную маркировку не соблюдают.
Часто вместо DB25p (plug-"штырь") указывают DB25m (male -"папа"), DB25s(socket-"гнездо")- DB25f(femini-"мама").
Также, вместо DE9p (COM-порт) могут указать: DB9p, DB9m.(хотя обоймы "В" и "Е" различны по размеру)

Рис.3 Цоколевка разъема DB25 по стандарту RS-232C

pin DB25 for RS-232

Можно напрямую соединить разъемы приборов DTE и DCE, так как их сигналы подобраны нужным образом.
То есть, выходные сигналы DTE попадают на входные сигналы DCE, и наоборот выходные сигналы DCE попадают на входные сигналы DTE.
Поэтому для соединения устройства DTE с устройствами DCE используют прямой (модемный) кабель.
Для соединения устройств DTE между собой или устройств DCE между собой, используют перекрестный (кроссовер) кабель.



Назначение контактов соединителя интерфейса RS-232C .

В интерфейсе RS-232 используются:
        16 сервисных сигналов
        4 информационных сигнала
        2 общих сигнала
Использование сигналов не обязательно и зависит от приложения, где их используют.
Например, минимальный набор сигналов TD и GND, позволяет передавать данные от DTE к DCE по стандарту RS-232c по двум проводам.

        Международный стандарт ITU-T v.24 включает в себя описание 37 сигналов, которые используются для передачи двоичных данных между терминалом (DTE) и оконечным устройством связи (DCE).
Все сигналы RS-232C включены в состав сигналов стандарта ITU-T v.24 под другими названиями.
Соответствие сигналов стандарта RS-232C сигналам стандарта ITU-T v.24, а также их популярное название показаны в следующей таблице.

2.5.4. Функциональное описание сигналов обмена.

Таблица 1. Назначение контактов соединителя интерфейса RS-232 для DTE   [1]   [2]   [4]
Nr.Обозн.
v.24
Обозн.
RS232
Обозн.
дефакто
Для DTE Описание
1PGОбщий(Protective Ground) Защитное заземление
2103BATDВыход(Transmitted Data) Передача данных.
По этой цепи в DCE передаются сигналы, вырабатываемые DTE:
    а)для передачи данных одной или нескольким удаленным станциям;
    б)поступающие в DCE с целью проверки со стороны DTE;
    в)для программирования или управления DCE в процессе последовательного автоматического вызова.
3104BBRDВход(Received Data) Прием данных.
По этой цепи в DTE передаются сигналы, формируемые DCE в соответствии:
    а)с принимаемыми данными, полученными от удаленной станции;
    б)с проверочными сигналами DTE, а также ответы на сигналы (или «эхо» сигналов) программирования или управления, поступающие от DTE в процессе последовательного автоматического вызова.
4105
133
CA/CJRTS Выход(Request To Send) Запрос на передачу.
Сигналы, передаваемые по этой цепи, управляют в DCE функцией передачи по каналу данных.
При состоянии RTS=True DCE переводится в режим передачи по каналу данных.
При состоянии RTS=False DCE переводится в режим отсутствия передачи по каналу данных после того, как закончится передача всех данных, ранее переданных по цепи TD(2)
5106CBCTS Вход(Clear To Send) Очищен для передачи.
Сигналы, передаваемые по этой цепи, указывают на готовность DCE передавать данные по каналу данных.
Состояние CTS=True указывает, что DCE готов к передаче данных по каналу данных.
Состояние CTS=False указывает, что DCE не готова передавать данные по каналу данных.
6107CCDSRВход(Data Set Ready) Установка данных готова.
Сигналы, передаваемые по этой цепи, указывают на готовность DCE к работе.
Состояние DSR=True (если цепь 25 находится в состоянии TM=False или не используется) указывает на то, что устройство преобразования сигналов или аналогичное устройство подсоединено к линии связи и что DCE готов к взаимодействию по цепям управления на стыке с DTE для обмена данными.
Состояние DSR=True при наличии состояния TM=True в цепи 25 указывает на то, что DCE готов к взаимодействию по цепям управления на стыке DTE для проведения проверки.
Состояние DSR=False при наличии в цепи CTS(5)=True указывает на то, что DCE готов осуществить обмен сигналами данных, связанных с программированием или управлением последовательным автоматическим вызовом.
Состояние DSR=False при наличии в цепи CTS(5)= False указывает, что:
    а)DCE не готов для передачи данных;
    б)обнаружено состояние неисправности, которое может быть в сети или в DCE;
    в)обнаружено разъединение от удаленной станции или от сети.
Состояние DSR=False при наличии в цепи TM(25)=False указывает, что DCE участвует в проверке со стороны сети или удаленной станции.
7102ABGNDОбщий(Ground) Общий.
Цепь представляет собой общий обратный провод для несимметричных цепей RS-232C и устанавливает эталонный потенциал по постоянному току для симметричных цепей. Внутри DCE эта цепь должна заканчиваться в одной точке, причем должна быть предусмотрена возможность соединения ее с защитным заземлением с помощью перемычки. Перемычка должна устанавливаться или сниматься в соответствии с требованиями действующих правил или для уменьшения помех, наводимых в электронных схемах оборудования.
8109CFDCDВход(Data Carrier Detected) Обнаружен носитель информации.
Сигналы, передаваемые по этой цепи, указывают, находится ли уровень принимаемого линейного сигнала канала данных в пределах, установленных соответствующими рекомендациями на DCE.
Состояние DCD=True указывает, что уровень принимаемого сигнала соответствует установленным пределам.
Состояние DCD=True может быть также во время обмена данными между DCE и DTE при программировании или управлении последовательным автоматическим вызовом.
Состояние DCD=False указывает, что уровень принимаемого сигнала не соответствует установленным пределам.
9зарезервирован
10зарезервирован
11126неопределён
12122
112
SCF/CISDCDВход(Secondary Carrier Detect) Обнаружен носитель информации обратного канала.
Эта цепь эквивалентна цепи DCD(8) с той лишь разницей, что она указывает, находится ли уровень принимаемого сигнала по обратному каналу в пределах, установленных соответствующими рекомендациями на DCE.
13121SCBSCTSВход(Secondary Clear To Send) Очищен для передачи.Обратный канал.
Эта цепь эквивалентна цепи CTS(5) (Очищен для передачи) с той лишь разницей, что она указывает на готовность DCE передавать данные по обратному каналу.
Состояние SCTS=True указывает на готовность DCE передавать данные по обратному каналу.
Состояние SCTS=False указывает на то, что DCE не готов передать данные по обратному каналу.
14118SBASTDВыход(Secondary Transmitted Data) Обратная передача данных.
Эта цепь эквивалентна цепи TD(2) (Передаваемые данные) с той лишь разницей, что она используется для передачи данных по обратному каналу.
15114DBTSTВход(Transmitter Signal Timing DCE source) Передатчик сигналов синхронизации.
Сигналы, передаваемые по этой цепи, обеспечивают в DTE синхронизацию единичных элементов сигнала.
Состояния TST=True должны длиться в течение равных промежутков времени.
DTE должно обеспечивать по цепи TD(2)(Передаваемые данные) сигнал данных, в котором переходы между единичными элементами сигнала происходят в то же время, что и переходы из состояния TST=True в состояние TST=False в цепи 15.
16119SBBSRDВход(Secondary Received Data) Обратный прием данных.
Эта цепь эквивалентна цепи RD(3) (Принимаемые данные) с той лишь разницей, что она используется для приема данных по обратному каналу.
17115DDRSTВход(Receiver Signal Timing)Приемник синхросигнала.
Сигналы, передаваемые по этой цепи, обеспечивает в DTE синхронизацию единичных элементов сигнала.
Состояния RST=True и RST=False должны поддерживаться в течение равных промежутков времени. Переход из состояния RST=True в состояние RST=False должен соответствовать середине каждого единичного элемента сигнала в цепи RD(3)(Принимаемые данные).
18141LLLLВыход(Local Loopback) Локальная обратная петля.
Сигналы, передаваемые по этой цепи, управляют состоянием проверки шлейфом в местном DCE.
Состояние LL=True вызывает установление шлейфа в местном DCE.
Состояние LL=False вызывает снятие шлейфа в местном DCE.
19120SCASRTSВыход(Secondary Request to Send) Запрос передачи по обратному каналу.
Этот сигнал эквивалентен сигналу RTS (Запрос передачи) с той лишь разницей, что он используется в DCE для управления функцией передачи по обратному каналу.
При состоянии SRTS=True DCE должен перейти в режим передачи по обратному каналу.
При состоянии SRTS=False DCE должен перейти в режим отсутствия передачи по обратному каналу, когда закончится передача всех данных, ранее переданных по обратному каналу.
20108/2
108/1
CDDTRВыход(Data Terminal Ready) Готовность терминала данных.
Сигналы, передаваемые по этой цепи, управляют подключением к линии связи или отключением от линии связи устройства преобразования сигналов или аналогичного ему устройства.
Состояние DTR=True указывает, что DTE готово к работе, подготавливает DCE к подключению к линии связи устройства преобразования сигналов или аналогичного ему устройства, а также должно указывать на необходимость сохранения соединения, которое было установлено внешними средствами.
При состоянии DTR=False DCE должен отключить от линии связи устройство преобразования сигналов или аналогичное ему устройство после того, как закончится передача всех данных, ранее переданных по цепи TD(3) или по цепи STD(14).
Состояние DTR=False также может быть использовано для прерывания или прекращения процедуры адресного способа установления соединения в устройстве автоматического вызова DCE.
21140
110
RL/CGRLВыход(Remote Loopback) Эксплуатационная проверка.
Сигналы, передаваемые по этой цепи, управляют состоянием эксплуатационной проверки.
Состояние RL=True вызывает установление состояния проверки.
Состояние RL=False вызывает прекращение состояния проверки.
22125
135
CE/CKRIВход(Ring Indicator). Индикатор звонка.
Сигналы, передаваемые по этой цепи, указывают, получен ли DCE сигнал вызова.
Состояние RI=True указывает, что сигнал вызова принимается.
Состояние RI=False указывает, что сигнал вызова не принимается.
Это состояние может также появляться во время прерываний импульсно-модулированного сигнала вызова.
23111
112
CH/CIDSRSВыход(Data Signal Rate Selector) Переключатель скорости сигнала данных.
Сигналы, передаваемые по этой цепи, служат для переключения скорости передачи данных в случае синхронного DCE, имеющей две скорости или для переключения диапазона скоростей передачи данных в случае асинхронным DCE, имеющей два диапазона скоростей.
При состоянии DSRS=True DCE должен перейти на верхнюю скорость или верхний диапазон скоростей.
При состоянии DSRS=False DCE должен перейти на нижнюю скорость или на нижний диапазон скоростей.
24113DATSTВыход(Transmitter Signal Timing DTE source) Передатчик сигналов синхронизации.
Сигналы, передаваемые по этой цепи, обеспечивают в DCE синхронизацию единичных элементов сигнала.
Состояния TST=True и TST=False должны поддерживаться в течение равных промежутков времени.
Переход из состояния TST=True в состояние TST=False должен соответствовать середине каждого единичного элемента сигнала в цепи TD(2)(Передаваемые данные).
25142TMTMВход(Test Mode) Тестовый режим.
Сигналы в этой цепи указывают, установлено ли состояние проверки в DCE.
Состояние TM=True указывает, что DCE находится в состоянии проверки.
Состояние TM=False указывает, что DCE не находится в состоянии проверки.

2.5.5.Стандартные интерфейсы для выбранных конфигураций системы связи.
2.5.6. Рекомендации и приложения.

Так как интерфейс RS-232C универсален, то подразумевается использование его в различных приложениях и режимах.
Для каждого приложения могут использоваться различные сочетания сигналов интерфейса, которые называются конфигурациями.
Стандарт RS-232C предусматривает 13 стандартных конфигураций A-M и одну пользовательскую конфигурацию Z.

Стандартные конфигурации:
A - первый канал только передача
базовые сигналы: AB(GND), BA(TxD), CB(CTS), CC(DSR)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST)
опционально для тестирования: TM(TM)
B - первый канал только передача со стробом(RTS)
базовые сигналы: AB(GND), BA(TxD), CA(RTS), CB(CTS), CC(DSR)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST)
опционально для тестирования: TM(TM)
C - первый канал только приём
базовые сигналы: AB(GND), BB(RxD), CC(DSR), CF(DCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DD(RST)
опционально для тестирования: TM(TM)
D - первый канал дуплекс со стробом(RTS)
базовые сигналы: AB(GND), BA(TxD), BB(RxD), CA(RTS), CB(CTS), CC(DSR), CF(DCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST), DD(RST)
опционально для тестирования: TM(TM)
E - первый канал дуплекс
базовые сигналы: AB(GND), BA(TxD), BB(RxD), CB(CTS), CC(DSR), CF(DCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST), DD(RST)
опционально для тестирования: TM(TM)
F - первый канал только передача со стробом(RTS), второй канал только приём
базовые сигналы: AB(GND), BA(TxD), CA(RTS), CB(CTS), CC(DSR), SBB(SRD), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST)
опционально для тестирования: TM(TM)
G - первый канал только приём, второй канал только передача со стробом(SRTS)
базовые сигналы: AB(GND), BB(RxD), CA(RTS) CC(DSR), CF(DCD), SBA(STD), SCA(SRTS), SCB(SCTS)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DD(RST)
опционально для тестирования: TM(TM)
H - первый канал только передача, второй канал только приём
базовые сигналы: AB(GND), BA(TxD), CB(CTS), CC(DSR),SBB(SRD), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST)
опционально для тестирования: TM(TM)
I - первый канал только приём, второй канал только передача
базовые сигналы: AB(GND), BB(RxD), CC(DSR), CF(DCD), SBA(STD), SCB(SCTS)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DD(RST)
опционально для тестирования: TM(TM)
J - первый канал только передача со стробом(RTS), второй канал полудуплекс
базовые сигналы: AB(GND), BA(TxD), CA(RTS), CB(CTS), CC(DSR), SBA(STD), SBB(SRD), SCA(SRTS), SCB(SCTS), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST)
опционально для тестирования: TM(TM)
K - первый канал только приём, второй канал полудуплекс
базовые сигналы: AB(GND), BB(RxD), CC(DSR), CF(DCD), SBA(STD), SBB(SRD), SCA(SRTS), SCB(SCTS), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST), DD(RST)
опционально для тестирования: TM(TM)
L - первый канал дуплекс со стробом(RTS), второй канал дуплекс со стробом(SRTS)
базовые сигналы: AB(GND), BA(TxD), BB(RxD), CA(RTS), CB(CTS), CC(DSR), CF(DCD), SBA(STD), SBB(SRD), SCA(SRTS), SCB(SCTS), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST), DD(RST)
опционально для тестирования: TM(TM)
M - первый канал дуплекс, второй канал дуплекс
базовые сигналы: AB(GND), BA(TxD), BB(RxD), CA(RTS), CB(CTS), CC(DSR), CF(DCD), SBA(STD), SBB(SRD), SCB(SCTS), SCF(SDCD)
опционально для коммутируемых служб: CD(DTR), CE(RI)
опционально для синхронных каналов: DA(TST), DB(TST), DD(RST)
опционально для тестирования: TM(TM)
Z - конфигурация производителя, допускает любые сочетания сигналов.
Например, COM порт ПК использует конфигурацию D с опцией коммутируемых служб.







§3.Описание COM портов персонального компьютера IBM XT.

3.1 Основные свойства COM портов.

Работа коммуникационных портов реализована на универсальных асинхронных приемопередатчиках UART.
UART- это микросхемы, которые работают по стандарту RS-232C в конфигурации D с опцией коммутируемых служб(см.п.2.5.5)
Для СОМ порта компьютера используется 25-ти штырьковый разъем DB25p согласно стандарта RS-232C или 9-ти штырьковый разъем DE9p согласно стандарта TIA-574.
В этом разъеме используется шесть сервисных сигналов и один дуплексный канал связи.

Основные свойства СОМ портов:
1.Полнодуплексный обмен данными.
Означает, что можно одновременно передавать и принимать поток данных.
Существуют два аппаратно и программно независимых канала передачи данных.
Один канал для передачи данных, другой канал для приема данных.
Причем COM-портам безразлично, чем занят процессор в это время, у них присутствуют собственные буферы приема и передачи данных.
В этих буферах данные выстраиваться в очередь на передачу и очередь на прочтение данных процессором.
Любая программа может обратиться к СОМ-порту и получить данные из его буфера, тем самым очистив его.
Естественно буферы не безграничны, их размер задается при конфигурировании портов.
Интерфейсы RS-485, Modbus, USB и др. (за исключением сетевых протоколов) являются полудуплексными и физически не способны вести обмен данными в обоих направлениях одновременно.
2.Набор сервисных сигналов
Сервисные сигналы, предусмотренные стандартом RS-232c, позволяют организовать обмен данными между двумя устройствами одновременно в обоих направлениях.
Сервисные сигналы представлены отдельными цифровыми входами и выходами с памятью.
Например, кода по телефону на модем поступал звонок со станции, модем по 9-му контакту (RI) сообщал РС, что ему позвонили, и начиналась процедура обмена данных.
Причем с помощью сервисных сигналов РС и модем могли приостановить обмен данных или заставить повторить их.
Вариантов использования сервисных сигналов большое множество.
Разработчик может использовать их по своему усмотрению.
Например, с помощью этих сигналов удобно опрашивать контакты концевых выключателей или фотодатчиков, а также можно включать/выключать различные устройства или запитывать слаботочное устройство.
3.Программная независимость
UART полностью реализован аппаратно и не зависит от программного обеспечения и ОС.
4. Асинхронная передача данных по каналу связи
Означает то, что РС может послать данные на конечное устройство, не заботясь о синхронности их поступления.
Конечное устройство само подстраивается под полученные данные.
В синхронных протоколах для этого служит специальный сигнал, передающийся по отдельному проводу.
В коммуникационных портах синхросигнал встроен в каждый передаваемый символ, в виде стартового и стопового бита.
Метод, которым синхронизируются данные по стандарту RS-232С, стал общеупотребительным для всех асинхронных протоколов обмена данными.

3.2 Технические характеристики COM портов

Рис.4 Вид разъёмов СОМ1 и СОМ2 на материнской плате.

COM-port RS-232

3.3 Назначение сигналов СОМ порта по стандарту RS-232C.

Рис.5 Нумерация контактов для разъёмов COM-порта
pin COM-port

3.4 Уровни сигналов UART

UART использует уровни сигналов -12в....+12в .
Зона нечувствительности, то есть отсутствие сигналов считается напряжение -3в...+3в.
При этом обратите внимания, что принимаемые/передаваемые данные инвертированы.

Рис.6 Уровни сигналов UART по стандарту RS-232c

Уровни сигналов RS-232C

3.5 Передача данных через UART

При передаче данных символы передаются из буфера передатчика последовательно (первым пришел- первым вышел).
Специально назвал символами , а не байтами, так как символы могут иметь размер от 5 до 8 бит.
Каждый переданный символ снабжается стартовым и стоповым битами, предназначенным для синхронизации на приемной стороне.
После стартового бита следуют биты данных, начиная с младшего бита и заканчивая старшим.
За последним битом данных символа может следовать бит паритета, служащий для обнаружения ошибки передачи битов данных.
Последним передается стоповый бит, который необходим для временного разделения переданных символов.

Рис.7 Показана передача символов "0" "0" без паритета, с одним стоповым битом

Передача символов в RS-232C

На рисунке 7 хорошо видно, что стоповый бит разделяет два переданных символа. При необходимости можно увеличить этот интервал до 2 стоповых битов, если конечное устройство не успевает разделять символы.

Рис.8 Показана передача символов "0" "0" с проверкой на четность (EVEN), с одним стоповым битом

Передача символов с проверкой на четность в RS-232C

3.6 Соединительные кабели

Нуль-модемное соединение двух COM портов.

При таком соединении компьютеры(терминалы) соединяются между собой непосредственно через СОМ-порты, без использования модемов.
Так как компьютеры обладают большой скоростью обработки данных, то синхронизировать их работу не нужно.
Поэтому предполагается, что режим синхронизации обмена (Handshaking): 0-None, то есть сервисные сигналы не влияют на процедуры обмена данными.
Для этого используется нуль-модемный кабель.

Рис.9 Нуль-модемный кабель для Handshaking = 0 (None)

Нуль-модемный кабель

Так как режим синхронизации обмена на СОМ портах может быть включен, то часто сервисные сигналы СОМ портов замыкают самих на себя, тем самым исключая их влияния на процедуру обмена.

Рис.10 Нуль-модемный кабель для любых режимов Handshaking

Нуль-модемный кабель RS-232

Если необходимо можно использовать полный кабель, но при этом СОМ-порты должны быть настроены на аппаратную синхронизацию обмена.

Рис. 11 Нуль-модемный кабель для аппаратного режима синхронизации Handshaking=2

Нуль-модемный кабель RS-232 аппаратным контролем

Модемное соединение.

Модемное соединение подразумевает соединение двух компьютеров(DTE) через модемы(DCE).
Модемы (модуляторы-демодуляторы) - специальные устройства, позволяющие вести обмен данными практически на неограниченное расстояния, используя для этого модуляцию и демодуляцию информационных сигналов.
Поэтому модемное соединение подразумевает подключение СОМ-порта компьютера(DTE) к конечному устройству (DCE).
Обычно в таком соединении используют аппаратный режим синхронизации Handshaking =2.
Этот режим позволяет модемам управлять процессом передачи данных.

Рис. 12 Типичный модемный кабель.

Модемный кабель RS-232



3.7 Организация обмена данных при аппаратном режиме синхронизации.

Аппаратный режим синхронизации обмена данными RTS/CTS (hardware flow control) Handshaking =2, использует сервисные сигналы RS-232C для управления потоком данных.

Рис.13 Организация обмена при аппаратной синхронизации.

Организация обмена при аппаратной синхронизации RS-232

Как видно из рис.13 модем использует сигнал CTS, который позволяет остановить передачу данных, если приемник не готов к их приему.
Передатчик «выпускает» очередной байт только при включенной линии CTS.
Байт, который уже начал передаваться, задержать сигналом CTS невозможно (это гарантирует целостность посылки).
Аппаратный протокол обеспечивает самую быструю реакцию передатчика на состояние приемника.



3.8 Организация обмена данных при программном режиме синхронизации.

Программный протокол управления потоком XON/XOFF( Handshaking =1). Работает протокол следующим образом: если устройство, принимающее данные, обнаруживает причины, по которым оно не может их дальше принимать, оно по обратному последовательному каналу посылает байт-символ XOFF (13hex).
Противоположное устройство, приняв этот символ, приостанавливает передачу.
Когда принимающее устройство снова становится готовым к приему данных, оно посылает символ XON (11hex), приняв который противоположное устройство возобновляет передачу.
Время реакции передатчика на изменение состояния приемника по сравнению с аппаратным протоколом увеличивается, по крайней мере, на время передачи символа (XON или XOFF) плюс время реакции программы передатчика на прием символа.
Преимущество программного протокола заключается в отсутствии необходимости передачи управляющих сигналов интерфейса — минимальный кабель для двустороннего обмена может иметь только 3 провода.
Недостатком данного метода является большее время реагирования и исключения из передаваемого потока двух символов (13hex, 11hex).

Существует смешанный метод синхронизации обмена данными RTS/XOn/Xoff (Handshaking =3), который представляет собой объединение двух предыдущих методов.



3.9 Описание контрольных битов (Parity Control Bit):



3.10 ASCII кодовая таблица.

Для кодирования символов передаваемых по RS-232С используется таблица, кодирующая использованные символы и управляющие знаки.

Рис.14 Стандартная кодовая таблица ASCII

ASCII 437

Первые 32 символа этой кодовой страницы представляют собой управляющие символы, которые предназначены для управления модемом.
Например, использование символов 17(11hex) и 19(13hex) были изложены выше, в программном способе управления обменом.
Эти символы были разработаны в основном для управления печатающими устройствами и модемами

Таблица 2. Управляющие символы ASCII.
00(00hex) - NUL пустой символ 08(08hex)- BS возврат на одну позицию 16(10hex)- DLE переключение кода 24(18hex)- CAN отмена
01(01hex)- SOH начало заголовка09(09hex)- HT горизонтальная табуляция 17(11hex)- DC1 управление первым устройством (XON) 25(19hex)- EM конец носителя
02(02hex)- STX начало текста 10(0Ahex)- LF перевод строки 18(12hex)- DC2 управление вторым устройством 26(1Ahex)- SUB замена
03(03hex)- ETX конец текста 11(0Bhex)- VT вертикальная табуляция 19(13hex)- DC3 управление третьим устройством (XOFF) 27(1Bhex)- ESC переход
04(04hex)- EOT конец передачи 12(0Chex)- FF подача бланка (новый лист) 20(14hex)- DC4 управление четвертым устройством 28(1Chex)- FS разделитель файла
05(05hex)- ENQ запрос 13(0Dhex)- CR возврат каретки 21(15hex)- NAK переспрос 29(1Dhex)- GS разделитель группы
06(06hex)- ACK подтверждение 14(0Ehex)- SO переход на верхний регистр 22(16hex)- SYN режим синхронного ожидания 30(1Ehex)- RS разделитель записи
07(07hex)- BEL звонок 15(0Fhex)- SI переход на нижний регистр 23(17hex)- ETB конец передачи блока 31(1Fhex)- US разделитель блока

3.11 Аппаратная реализация СОМ портов.

Для аппаратной реализации СОМ портов по стандарту RS-232 используется специализированная микросхема UART.
UART (Universal Asynchronous Receiver-Transmitter )- универсальный асинхронный приёмо-передатчик.
Микросхема i8250 установленная в IBM XT послужила началом целой серии микросхем UART, которые устанавливались на материнские платы PC.

Микросхемы выпускались разными фирмами производителями: Intel, National Semiconductor, Maxim и др.

Микросхема представляет собой управляемую логическую схему с буферными регистрами для приёма и передачи последовательных данных.
Буферные регистры позволяют вести передачу и приём данных без участия CPU.
Соответственно чем больше ёмкость буферных регистров, тем реже микросхема прерывает работу CPU.
Буферные регистры устроены по принципу "очереди" (FIFO) - первым пришел, первым вышел.
Получив порцию данных в передающий буферный регистр, UART начинает передавать её в сеть RS-232, одновременно он может принимать данные из сети RS-232 в приёмный буферный регистр.
Программное обеспечение в любой момент может обратиться к приёмному буферу UART, тем самым освободив его для приёма следующих данных.
При заполнении приёмного буфера UART может прервать работу CPU, сообщив ему о заполнении буфера.
Заполнение приёмного буфера вызовет остановку приёма данных из сети RS-232, до тех пор пока он не будет прочитан.
Рассмотрим работу UART на примере микросхемы PC16550D

Рис.15 Стандартная схема включения UART PC16550D с микропроцессором Intel 8088   [5]

PC16550D

Обращение к микросхеме осуществляется через адресное пространство портов ввода-вывода CPU.
Микросхема подключается к системной шине при активизации сигнала CS0, который вырабатывается при обращении CPU к заданному диапазону адресов порта.
Адреса портов ввода-вывода заданы в BIOS. Обычно они имеют значения: COM1=3F8h, COM2=2F8h, COM3=3E8h, COM4=2E8h .
На входы UART A0,A1,A2 подаются три младших разряда адресной шины CPU.
Адрес заданный в BIOS является начальным адресом диапазона адресов (A2A1A0=000).
Следовательно полный диапазон адресов для каждого порта равен 8 адресам (от A2A1A0=000 до A2A1A0=111).
Например, для СОМ4 2E8h,2E9h,2EAh,2EBh,2ECh,2EDh,2EEh,2EFh.
Расстояние между начальными адресами портов равно 16, что допускает в дальнейшем использования микросхем с четырьмя начальными адресными линиями.
Обращение к микросхеме по определённому адресу открывает доступ к группе регистров управления или буферных регистров приёма и передачи.
CPU может записать данные в регистры UART выставив сигнал WR=0, или прочитать данные, выставив сигнал RD=0.

3.12 Программная реализация UART.   [5]

UART состоит из 12 регистров, к которым можно обратиться по восьми адресам портов ввода-вывода.
Так как индивидуального адреса для каждого регистра не хватает, то используют расщепление адресного пространства с помощью следующих методов:
    1.Разделение одного адресного пространства на два регистра по записи/чтению.
        По сигналу чтения RD=0 читается один регистр, по сигналу записи WR=0 записывается второй регистр.
        То есть данные по одинаковому адресу записываются или читаются с разных регистров.
        Таких регистров четыре:
                THR, RBR - по адресу UART 00h(A2A1A0=000)
                IIR, FOR - по адресу UART 02h(A2A1A0=010)
        Эти регистры односторонние, то есть в одни можно только записывать, в другие только читать данные.
    2.Использование дополнительного адресного бита
        Используют 7-ой бит регистра LCR-находящегося по адресу UART 03h(A2A1A0=011).
        Этот бит называют DLAB, если DLAB=0, то для чтения/записи используется один регистр,
        если DLAB=1, то для чтения/записи используется второй регистр.
        Таких регистров пять:
                (THR & RBR),DLL - по адресу UART 00h(A2A1A0=000)
                DIM, IER - по адресу UART 01h(A2A1A0=001)

Таблица 3. Регистры UART.
адрес DLABчтение/записьНазвание регистра
00h0WRTHR(Transmit Holding Register)-регистр данных ожидающих передачи
00h0RDRBR(Receiver Buffer Register)- буферный регистр приемника
00h1RD/WRDLL(Divisor Latch LSB)-младший байт делителя частоты
01h1RD/WRDIM(Divisor Latch MSB)-старший байт делителя частоты
01h0RD/WRIER(Interrupt Enable Register)-регистр разрешения прерывания
02hхRDIIR(Interrupt Identification Register)-регистр идентифицирующий прерывания
02hхWRFCR(FIFO Control Register)-регистр управления режимом FIFO
03hxRD/WRLCR(Line Control Register)-регистр управления линией связи
04hxRD/WRMCR(Modem Control Register)-регистр управления модемом
05hxRD/WRLSR(Line Status Register)-регистр состояния линии связи
06hxRD/WRMSR(Modem Status Register)-регистр состояния модема
07hxRD/WRSCR(Scratch Pad Register)-регистр временного хранения

Рис.16 Функциональная схема UART PC16550.   [5]

UART PC16550

THR-регистр данных ожидающих передачи(только для записи)
(Transmit Holding Register)

Рис.17 Регистр THR (Адрес=00h, DLAB=0, WR)
THR UART

        В этот регистр записывают байт данных, определённый как символ (от 5 до 8 бит) который будет передан в линию связи.
Символ, принятый в THR передаётся далее в сдвигающий регистр младшем битом вперед (см. рис.7).
В начало символа добавляется стартовый бит, в конец символа добавляется стоповый бит.
Перед стоповым битом может находиться бит паритета.
Если символ короче 8 бит, то старшие биты регистра THR игнорируются (не используются, хотя записываются в этот регистр).
Регистр THR может принять всего один байт данных и передать его в регистр последовательного сдвига.
В большинстве UART имеется режим FIFO, в котором данные загружаются не в THR, а в регистр FIFO.
Например, UART PC16550 имеет регистр FIFO, который может принять 16 байт данных.
Кроме этого у некоторых UART существует режим DMA, в этом режиме сдвигающий регистр заполняется байтами данных непосредственно из оперативной памяти без участия микропроцессора.

Для указания того, что регистр THR пуст и в него можно загрузить очередной байт данных используют бит 5 регистра LSR.
Этот бит называется THRE(Transmitter Holding Register Empty) -"регистр данных ожидающих передачи пуст".
Если THRE=1, то в регистр THR можно посылать очередной байт данных, в режиме FIFO этот бит говорит о том, что регистр FIFO пуст и можно посылать следующий пакет байтов данных.
Бит THRE может быть источником прерывания CPU.

RBR- буферный регистр приемника(только для чтения)
(Receiver Buffer Register)

Рис.18 Регистр RBR (Адрес=00h, DLAB=0, RD)
THR UART

        В этот регистр байты(символы) принимаются из приемного сдвигающегося регистра.
Регистр RBR может принять только один байт из сдвигающего приемного регистра.
Аналогично передающей части UART здесь есть регистр FIFO, который может принимать больше одного байта данных минуя регистр RBR.
К моменту заполнения сдвигающего приёмного регистра регистр RBR должен быть освобожден для приема очередного байта, иначе произойдет ошибка переполнения.
Освобождение регистра RBR происходит, когда данные из него читаются микропроцессором.
О том, что символ потерян в результате переполнения сообщает бит 1 регистра LSR.
Этот бит называется ОЕ (Overrun Error)-"ошибка переполнения", OE=1 означает что один из переданных символов потерян.
О том, что байт готов к прочтению микропроцессором (т.е. полностью выгрузился из приемного сдвигающегося регистра или FIFO) сообщает бит 0 регистра LSR.
Этот бит называется DR (Receiver Data Ready) -"Данные приёмника готовы".
DR=1 говорит о том, что регистр RBR(или FIFO) содержит принятый байт и его необходимо прочитать, DR сбрасывается в ноль после прочтения регистра RBR микропроцессором.
Это бит также может инициировать прерывание микропроцессора.

DLL-младший байт делителя частоты :16 (чтение/запись)
(Divisor Latch LSB)

Рис.19 Регистр RBR (Адрес=00h, DLAB=1, RD/WR)
DLL register UART

        В это регистре находится младший байт делителя частоты деленного на 16.

DIM-старший байт делителя частоты :16 (чтение/запись)
(Divisor Latch MSB)

Рис.19 Регистр RBR (Адрес=01h, DLAB=1, RD/WR)
DIM register UART

        В этом регистре находится старший байт делителя частоты деленного на 16.
В микросхеме UART частота задающего кварца делится на делитель частоты(Decimal Divisor),который получается из двухбайтового числа (DIM,DLL) умноженного на 16.
Таким образом делитель частоты задает скорость обмена данных через UART.
Записью в регистры DIM и DLL старшего и младшего байта этого двухбайтового числа вы зададите скорость обмена СОМ-порта в бит/сек.
Для кварца UART частотой f=1,8432 МГц, делитель частоты:16 считается по формуле:

D=115200/V, где V-скорость в бит/сек, D=делитель частоты:16

Для кварца UART частотой f=24 МГц, делитель частоты:16 считается по формуле:

D=1 500 000/V, где V-скорость в бит/сек, D=делитель частоты:16

Таблица 4. Делитель частоты для UART PC16550.
1,8432 МГц24 МГц
Скорость, бит/секделитель:16DIMDLLделитель:16DIMDLL
50230409h00h3000075h30h
75153606h00h200004Eh20h
110104741h07h1363635h44h
15076803h00h1000027h10h
30038401h80h500013h88h
60019200hC0h250009hC4h
1 2009600h60h125004hE2h
1 8006400h40h83303h41h
2 0005800h3Ah75002hEEh
2 4004800h30h62502h71h
3 6003200h20h4170hA1h
4 8002400h18h31201h38h
7 2001600h10h20800hD0h
9 6001200h0Ch15600h9Ch
14 400800h08h10400h68h
19 200600h06h7800h4Eh
28 800400h04h5200h34h
38 400300h03h3900h27h
57 600200h02h2600h1Ah
115 200100h01h1300h0Dh
250 000xxx600h06h
300 000xxx500h05h
375 000xxx400h04h
500 000xxx300h03h
750 000xxx200h02h
1 500 000xxx100h01h

Как видно из таблицы 4, СОМ порт ПК (с UART 16550 и выше) может работать на скорости до 1,5Mb/s.

IER-регистр разрешения прерывания(чтение/запись)
(Interrupt Enable Register)

Рис.20 Регистр IER (Адрес=01h, DLAB=0, RD/WR)
IER register UART

        Регистр разрешения прерываний дает разрешения определённым событиям вызывать прерывание микропроцессора.
Бит 0. RxD_IЕ — если RxD_IЕ=1,то разрешено прерывание для приема данных,это прерывание возникает когда необходимо принять символ из регистра RBR (в режиме FIFO — прерывание по тайм-ауту).

Бит 1. TxD_IE — если TxD_IEЕ=1,то разрешено прерывание для передачи данных, это прерывание возникает когда передающий буфер пуст и необходимо загрузить байт в регистр THR.

Бит 2. RxL_IЕ — если RxL_IЕ=1,то разрешено прерывание при обрыве линии связи или ошибке в приёме данных, это прерывание возникает когда в регистре состояния линии связи LSR будут выставлены биты этих ошибок.

Бит 3. Mod_IЕ — если Mod_IЕ =1,то разрешено прерывание при изменении состояния любого из входных сигналов RST,CTS,DCD,RI, это прерывание возникает когда состояние входных сигналов COM-порта изменились.

Бит 4..7. Не используются и всегда равны 0.

IIR-регистр идентифицирующий прерывания (чтение)
(Interrupt Identification Register)

Рис.21 Регистр IIR (Адрес=02h, RD)
IIR register UART

        Чтобы минимизировать программное обеспечение, UART располагает по приоритетам прерывания в четыре уровня и делает запись этих прерываний в IIR.
Четыре уровня прерывания располагаются в порядке приоритета условий прерывания заданных регистрами - RLS; RDR; THR; и MSR.
Когда CPU обращается к IIR, UART замораживает все прерывания и указывает самое высокое приоритетное отложенное прерывание для CPU.
Во время обработки прерывания, UART делает запись новых прерываний, но не изменяет их текущий признак, до полной обработки.

Бит 0. IP(Interrupt Pending)— если IP=1, то все прерывания обработаны. Если IP=0,то есть необработанные прерывания.

Бит 1. I_ID0(Interrupt ID Bit0)- нулевой бит идентификатора прерываний
Бит 2. I_ID1(Interrupt ID Bit1)- первый бит идентификатора прерываний
Бит 3. I_ID2(Interrupt ID Bit2)- второй бит идентификатора прерываний
Таблица 5. Идентификация прерывания (обычный режим)
I_ID2I_ID1I_ID0Приоритетидентификация
x00ЧетвертыйИзменилось состояние модема, сбрасывается прочтением регистра MSR.
x01ТретийРегистр THR пуск, ожидается байт от CPU. Сбрасывается записью байта в THR.
x10ВторойПринят байт данных в регистр RBR, сбрасывается чтением регистра RBR.
x11НаивысшийОбрыв линии или ошибка на линии, сбрасывается прочтением регистра LSR.

Таблица 6. Идентификация прерывания (режим FIFO)
I_ID2I_ID1I_ID0Прирритетидентификация
000ЧетвертыйИзменилось состояние модема, сбрасывается прочтением регистра MSR
001ТретийБуферный регистр передачи FIFO пуск, ожидается данные от CPU. Сбрасывается записью в передающий буфер FIFO
010ВторойПриемный буфер FIFO заполнился, сбрасывается чтением приемного буфера FIFO.
011НаивысшийОбрыв линии или ошибка на линии, сбрасывается прочтением регистра LSR
100
101
110Второйиндикатор тайм-аута (за 4-кратный интервал времени символа не передано и не принято ни одного символа, хотя в буфере FIFO имеется, по крайней мере, один символ). Сброс выполняется чтением приемного буфера FIFO.
111

Бит 4..5.Зарезервированны

Бит 6. FE_ID0(FIFOs Enabled ID Bit0)- нулевой бит идентификатора режима FIFO
Бит 7. FE_ID1(FIFOs Enabled ID Bit1)- первый бит идентификатора режима FIFO
Таблица 7. Идентификация режима FIFO
FE_ID1FE_ID0Режим
00обычный режим работы, данные передаются побайтно через регистры THR и RBR.
01
10режим FIFO для UART 16550.
11режим FIFO для UART 16550A.


FCR-регистр управления режимом FIFO (запись)
(FIFO Control Register)

Рис.22 Регистр FCR (Адрес=02h, WR)
FCR register UART

        Это регистр используется только для записи, его данные расположены как в регистре IIR.
Этот регистр используется, чтобы разрешить режимы FIFO, очистить буферы FIFO, задать уровень заполнения буферов FIFO, и выбрать тип DMA(прямого обращения к памяти).

Бит 0. TRFIFOE(Transmit And Receive FIFO Enable)— Запись 1 в этот бит допускает оба режима FIFO передатчика(XMIT) и приемника(RCVR).
Сброс бита в 0 очистит все байты в обоих буферов FIFO.
При изменении режима FIFO к 16450 и наоборот, буферы FIFO автоматически очищаются.
Этот бит должен быть в 1, когда производится запись других битов регистра FCR, иначе они не будут запрограммированы.

Бит 1. RESETRF(Reset Receiver FIFO)-Запись 1 в этот бит очищает все байты в приемном буфере FIFO и сбрасывает его счетчик в 0.
Сдвиговый регистр при этом не очищается.
После этого 1 в этом бите сбрасывается в 0.

Бит 2. RESETTF(Reset Transmitter FIFO)- Запись 1 в этот бит очищает все байты в передающем буфере FIFO и сбрасывает его счетчик в 0.
Сдвиговый регистр при этом не очищается.
После этого 1 в этом бите сбрасывается в 0.

Бит 3. DMAE(DMA Enabled)- Запись 1 в этот бит приводит к изменению сигналов UART RxRDY и TxRDY с 0 к 1,при условии что FCR(bit0)=1.
Эти аппаратные сигналы используются для организации правильной работы режима DMA в микропроцессорной системе.

Бит 4..5.Зарезервированные.

Бит 6. ITL_ID0 (Interrupt Trigger Level ID bit0) - нулевой бит идентификатора триггера уровня прерывания.
Бит 7. ITL_ID1(Interrupt Trigger Level ID bit1)- первый бит идентификатора триггера уровня прерывания.
В этих двух битах задается идентификатор, который задает уровень при котором будет вырабатываться прерывание при приеме данных в режиме FIFO. Уровень задается количеством байт в приемном(RCVR) буфере FIFO.
Таблица 8. Идентификация тригера уровня прерывания
ITL_ID1ITL_ID0уровень прерывания, байт
0001
0104
1008
1114


LCR-регистр управления линией связи(запись/чтение)
(Line Control Register)

Рис.23 Регистр LCR (Адрес=03h, RD/WR)
LCR register UART

        Данный регистр служит для определения(задания) формата асинхронного обмена передачи данных.
Также в этом режиме устанавливается бит DLAB, который позволяет программисту записывать и читать данные из нужных регистров.
Программист может не только записывать, но и читать содержимое регистра LCR.
Способность чтения упрощает системное программирование и устраняет потребность в отдельной области в системной памяти для хранения характеристик линии.

Бит 0. SDB_ID0(Serial Data Bits ID0)- нулевой бит идентификатора количества бит в передаваемом символе.
Бит 1. SDB_ID1(Serial Data Bits ID1)- первый бит идентификатора количества бит в передаваемом символе.
С помощью этих битов задают количество бит в передаваемом или принимаемом символе.

Таблица 9. Количество бит в символе данных
SDB_ID1SDB_ID0количество бит в символе
005
016
107
118

Бит 2. STOP_B(Stop Bits)- Этот бит определяет число стоповых битов, переданных или полученных в каждом последовательном символе.
Если бит STOP_B=0, то передается один стоповый бит. Если бит STOP_B=1, то стоповый бит равен двум для 6,7,8 битовых символов и полтора стоповых бита для 5-ти битовых символов.
Приемник проверяет только первый стоповый бит, независимо от выставленных стоповых битов.

Бит 3. PAREN(Parity Enable) -Если PAREN=1, то разрешено использование бита паритета и данный бит вставляется между последним битом данных и стоповым битом. Если PAREN=0, то бит паритета не выставляется и не входит в состав передаваемого символа.

Бит 4. EVENPAR(Even Parity Select) - Бит выбора типа контроля паритета. Если EVENPAR=1, то происходит проверка на четность. Если EVENPAR=0, то происходит проверка на нечетность.

Бит 5. STICPAR (Sticky Parity)- Если STICPAR=0, то бит паритета бит генерируется в соответствии с паритетом выводимого символа.
Если STICPAR=1, то постоянное значение контрольного бита: при EVENPAR=1 — нулевое, при EVENPAR=0 — единичное.

Бит 6. BRCON(Break Control)- Управляющий бит обрыва связи. Если BRCON=1, то вслучае возникновения перерыва в приеме данных, передатчик UART начнёт передавать в линию нули.

Бит 7. DLAB(Divisor Latch Access Bit)- Этот бит доступа к делителю частоты. Если DLAB=1, то можно обратиться к регистрам DIM, DLL в которых хранятся младший и старший байт делителя частоты :16.Если DLAB=0, то можно обратиться к регистрам THR,RBR,IER.

MCR-регистр управления модемом (запись/чтение)
(Modem Control Register)

Рис.24 Регистр MCR (Адрес=04h, RD/WR)
MCR register UART

        Этот регистр управляет интерфейсом модема или периферийным устройством.

Бит 0. DTR(Serial Data Bits ID0)(Data Terminal Ready)- Этот бит управляет выходным сигналом DTR (Готовность терминала данных).
Когда бит DTR=1, вывод DTR UART устанавливается в логический 0, в IBM XT этот сигнал инвертируется буферным инвертором DS1488(см.рис.15) в логическую 1 т.е. U= +12в (сигнал DTR COM-порта считается включенным)
Соответственно когда бит DTR=0, сигнал DTR COM-порта U= -12в логический 0 (сигнал DTR считается выключенным)

Бит 1. RTS(Request To Send )- Этот бит управляет выходным сигналом RTS (Запрос на передачу).
Когда бит RTS=1, вывод RTS UART устанавливается в логический 0, в IBM XT этот сигнал инвертируется буферным инвертором DS1488(см.рис.15) в логическую 1 т.е. U= +12в (сигнал RTS COM-порта считается включенным)
Соответственно когда бит RTS=0, сигнал RTS COM-порта U= -12в логический 0 (сигнал RTS считается выключенным)

Бит 2. OUT1(OUT1 Bit Control) - Управление вспомогательным выходом OUT1.

Бит 3. OUT2(OUT2 Bit Control) - Управление вспомогательным выходом OUT2.

Бит 4. LOOP(Loopback Mode Enable)-Бит режима диагностики. Если LOOP=0, то UART работает в обычном режиме. Если LOOP=1, то URAT работет в режиме диагностики с обратной связью, в этом режиме используются вспомогательные сигналы OUT1 и OUT2.

Бит 5..7. Зарезервированы.

LSR -регистр состояния линии связи (запись/чтение)
(Line Status Register)

Рис.25 Регистр LSR (Адрес=05h, RD/WR)
LSR register UART

        Данный регистр показывает состояние приемопередатчика.

Бит 0. DR(Receiver Data Ready) — Готовность данных приемника.DR=1 информирует о том, что данные приняты и загружены в регистр RBR или приемный буфер FIFO.
Бит сбрасывается в ноль, когда все данные будут прочитаны CPU из регистра RBR или буфера FIFO.

Бит 1. OE(Overrun Error) — Бит ошибки переполнения. Бит указывает, что данные в регистре RBR не были прочитаны CPU прежде, чем следующий символ был передан в RBR, что привело к потере предыдущего символа.
Бит устанавливается в OE=1 после обнаружения ошибки переполнения и сбрасывать всякий раз, когда SPU читает содержание регистра LSR.

Бит 2. PE(Parity Error) —Бит ошибки контрольного бита паритета.PE=1 если символ принят с ошибкой паритета.

Бит 3. FE(Framing Error) — ошибка кадра (неверный стопбит).

Бит 4. BD(Break Detected) — индикатор обрыва линии (вход приемника находится в состоянии 0 не менее чем время посылки символа).

Бит 5. THRE(Transmitter Holding Register Empty) — регистр передатчика готов принять байт для передачи. В режиме FIFO указывает на отсутствие символов в FIFO-буфере передачи. Может являться источником прерывания.

Бит 6. TEMPT(Transmitter Empty Status) — регистр передатчика пуст (нет данных для передачи ни в сдвиговом регистре, ни в буферных регистрах THR или FIFO).

Бит 7. FIFOE(FIFO Error Status) —ошибка принятых данных в режиме FIFO (буфер содержит хотя бы один символ, принятый с ошибкой формата, паритета или обрывом). В не FIFO-режиме всегда 0.

MSR-регистр состояния модема
(Modem Status Register)

Рис.26 Регистр MSR (Адрес=06h, RD/WR)
MSR register UART

        Этот регистр позволяет CPU контролировать текущее состояние линий управления модема или периферийного устройства.
В дополнение к этому , четыре бита (0..3) регистра MSR контролируют изменения сигналов на входах CTS,RTS,RI,DCD микросхемы и вырабатывают прерывание микропроцессора.

Бит 0. DCTS(Delta Clear To Send) — Изменение состояния сигнала CTS(очищен для передачи).Бит устанавливается в DCTS=1 при изменении сигнала CTS на входе микросхемы и сбрасывается при прочтении регистра MSR микропроцессором.
При установке бита в 1 генерируется прерывание микропроцессора.

Бит 1. DDSR(Delta Data Set Ready) — Изменение состояния сигнала DSR(установка данных готова).
Бит устанавливается в DDSR=1 при изменении сигнала DSR на входе микросхемы и сбрасывается при прочтении регистра MSR микропроцессором.
При установке бита в 1 генерируется прерывание микропроцессора.

Бит 2. ТЕRI(Trailing Edge Of Ring Indicator) — Детектор заднего фронта сигнала RI(индикатор звонка).
Бит устанавливается в TERI=1, когда сигнал на выводе микросхемы RI изменяет свой уровень с низкого на высокий.
Бит сбрасывается в TERI=0 при прочтении регистра MSR микропроцессором.
При установке бита в 1 генерируется прерывание микропроцессора.

Бит 3. DDCD(Delta Data Carrier Detect) — Изменение состояния сигнала DCD(обнаружен носитель информации).
Бит устанавливается в DDCD=1 при изменении сигнала DCD на входе микросхемы и сбрасывается при прочтении регистра MSR микропроцессором.
При установке бита в 1 генерируется прерывание микропроцессора.

Бит 4. CTS(Clear To Send) — Состояние линии CTS. Если CTS=1, то на вход CTS СОМ-порта подано напряжение +12в(сигнал CTS активен).
Если CTS=0, то вход СОМ-порта подано напряжение -12В(сигнал CTS пассивен).
В режиме диагностики этот бит эквивалентен биту RTS регистра MCR.

Бит 5. DSR(Data Set Ready) — Состояние линии DSR. Если DSR=1, то на вход DSR СОМ-порта подано напряжение +12в(сигнал DSR активен).
Если DSR=0, то вход СОМ-порта подано напряжение -12В(сигнал DSR пассивен).
В режиме диагностики этот бит эквивалентен биту DTR регистра MCR.

Бит 6. RI(Ring Indicator) — Состояние линии RI. Если RI=1, то на вход DSR СОМ-порта подано напряжение +12в(сигнал RI активен).
Если RI=0, то вход СОМ-порта подано напряжение -12В(сигнал RI пассивен).
В режиме диагностики этот бит эквивалентен биту OUT1 регистра MCR.

Бит 7. DCD(Data Carrier Detect) — Состояние линии DCD. Если DCD=1, то на вход DCD СОМ-порта подано напряжение +12в(сигнал DCD активен).
Если DCD=0, то вход СОМ-порта подано напряжение -12В(сигнал DCD пассивен).
В режиме диагностики этот бит эквивалентен биту OUT2 регистра MCR.

SCR-регистр временного хранения (чтение/запись)
(Scratch Pad Register)

Рис.27 Регистр SCR (Адрес=07h, RD/WR)
SCR UART

        Регистр временного хранения, на работу UART не влияет, предназначен для временного хранения данных (в UART i8250 отсутствует).



3.13 Диагностический режим работы UART.

Режим диагностики UART позволяет проверить работоспособность СОМ-портов без подключения к ним периферийных устройств. Режим диагностики включается битом LOOP=1 регистра MCR.
При этом внутри UART организуется аппаратная "заглушка":

Аппаратная "заглушка" позволяет передавать и сразу принимать данные СОМ-порта, без каких либо подключений к нему. В результате этого возможно проверить работу сдвигающего регистра, отработку системы прерываний и т.д.

       

§4 Программирование COM-порта.

4.1. Программирование в MS-DOS.

    В MS-DOS программировать СОМ порты можно всем спектром программных средств: прямым кодом микропроцессора(assembler), функциями BIOS, средствами операционной системы, языками программирования высокого уровня.

4.1.1. Программирование СОМ-порта прямым кодом микропроцессора.

    Под программированием прямым кодом микропроцессора понимается программирование микросхемы UART через порты ввода-вывода с помощью команд микропроцессора.
В системе команд микропроцессора есть команды OUT и IN, которые позволяют читать/записать байт по указанному адресу порта ввода/вывода.
В п.3.12 описаны 12 регистров микросхемы UART, которые полностью определяют работу указанной микросхемы.
Необходимо просто записать нужные данные в эти регистры, чтобы заставить СОМ порт выполнить нужные действия.
При программировании регистров UART нужно учитывать, что в памяти BIOS находятся адреса портов ввода/вывода для СОМ1...СОМ4.
По умолчанию они равны COM1=3F8h, COM2=2F8h, COM3=3E8h, COM4=2E8h , но бывают "чудики" которые могут их поменять в настройках BIOS.
Поэтому перед началом программирования портов в MS-DOS желательно проверить адреса СОМ портов.
В BIOS адрес СОМ порта занимает 2 байта, и находятся в ячейках памяти по адресам СОМ1: 40...41h, СОМ2: 42...43h, СОМ3: 44...45h, СОМ4: 46...47h.

Пример:
'записываем  в LCR режим работы сом порта:
'8 бит всимволе,1 стоп бит, проверка паритета на четность,выдавать 0 в случае обрыва, DLAB=1 
        mov dx,3fbh 'адрес регистра
	mov al,DBh 'записываем в AL значения для регистра LCR=DBh
	out dx,al'записываем данные в регистр UART LCR
'задаем скорость обмена  115 000 бит/сек  DIM=00h, DLL=01h
        mov dx,3f8h 'адрес регистра
	mov al,01h
	out dx,al 'запись регистра DLL=01h
        mov dx,3f9h 'адрес регистра
	mov al,00h
	out dx,al 'запись регистра DIM=00h
'снимаем бит DLAB=1
        mov dx,3fbh 'адрес регистра
	mov al,5Bh 'DLAB=0
	out dx,al
'послать байт 03h в линию связи
        mov dx,3f8h 'адрес регистра
	mov al,03h
	out dx,al 'посылает байт 03h на скорости 115 000 бит/сек

    Перед записью байта данных в регистр передатчика необходимо убедиться в том, что регистр хранения передатчика свободен, то есть убедиться в том, что передача предыдущего символа завершена.
Признаком того, что регистр передатчика свободен, является установленный бит 5(THRE=1) регистра состояния линии LSR.
    Аналогично тому как это делается при передаче данных, перед вводом символа из порта приемника необходимо убедиться в том, что бит 0 регистра LSR установлен (т.е. DR=1).
Это означает, что символ принят из линии и находится в буферном регистре приемника.

4.1.2. Программирование СОМ-порта с помощью функций BIOS.

    В BIOS имеются функции которые могут выполняться по команде программного прерывания микропроцессора INT 00h...INT 1Fh.
Так как код этих функций находится в BIOS, то их выполнение возможно даже при отсутствии ОС на ПК.
Кроме этого, функции BIOS работают по номерам СОМ портов, а не по адресу ввода/вывода, что существенно удобней.

Рассмотрим функции BIOS которые применяются для работы с СОМ портом:

Функции по прерыванию INT 14h

    Программа обработчик этого прерывания, как мы уже говорили, находится в BIOS по вектору 14h.
BIOS представляет собой энергонезависимую память ПК, поэтому загружать программу обрабатывающую прерывание не надо, она всегда находится в памяти.
Вызов функции осуществляется по номеру функции, который записывается в старший байт аккумулятора (AH).
Пример:
	mov ah,00h 'номер функции
	int 14h    'вызов функции
Рассмотрим функции вызываемые INT 14h:

INT 14h AH=00h-инициализация СОМ порта.
Под инициализацией порта (также применяют термин "открытие") понимают установку всех его параметров: номер порта, длину символа, число стоп-бит, установку четности и скорость обмена.

входные параметры INT14h AH=00h
регистрстарший младший
AX00hбайт параметров связи
BX
CX
DX(n-1), где n-номер COM порта

DX: 0000h-COM1, 0001h-COM2, 0002h-COM3, 0003h-COM4

байт параметров связи
  7     6     5     4     3     2     1     0   описаниедопустимые значения
xxxскорость, бод000- 110
001- 150
010- 300
011- 600
100- 1200
101- 2400
110- 4800
111- 9600
xxпроверка паритета00- нет
01- нечетность
10- нет
11- четность
xдлина стопового бита0- 1
1- 2
xxкол. бит в символе10- 7
11- 8


Пример вызова функции:
	mov ah,00h 'номер функции
	mov al,EBh '9600 бод,нечетность,1 стоп, 8 бит
	int 14h    'вызов функции
После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=00h
регистрстарший младший
AXбайт состояние линии LSRбайт состояние модема MSR
BX
CX
DX

В качестве выходных параметром в регистр аккумулятора копируются регистры UART LSR(см.рис.25) и MSR(см.рис.26).
Из выше сказанного видно, что работа с СОМ портом через функцию BIOS INT14h ограничена по скорости и по количеству бит в символе.

INT 14h AH=01h-запись символа в СОМ порт.
При вызове этой функции происходит передача символа из регистра AL в порт с номером заданным в регистре DX.
входные параметры INT14h AH=01h
регистрстарший младший
AX01hсимвол
BX
CX
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=01h
регистрстарший младший
AXбайт состояние линии LSRсимвол
BX
CX
DX


INT 14h AH=02h-чтение символа из СОМ порта.
При вызове этой функции происходит чтение символа из приемного регистра СОМ порта, с номером заданным в регистре DX, в регистра AL .
входные параметры INT14h AH=02h
регистрстарший младший
AX 02h
BX
CX
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=02h
регистрстарший младший
AXбайт состояние линии LSRсимвол
BX
CX
DX


INT 14h AH=03h- запрос состояния СОМ порта.
При вызове этой функции происходит чтение регистров LSR и MSR из заданного UART.
выходные параметры INT14h AH=03h
регистрстарший младший
AX03h
BX
CX
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=03h
регистрстарший младший
AXбайт состояние линии LSRбайт состояние модема MSR
BX
CX
DX


INT 14h AH=04h-расширенная инициализация СОМ порта.
Применяется для моделей PS/2.
входные параметры INT14h AH=04h
регистрстарший младший
AX 04h установка прерывания
BXустановка паритетаустановка стопового бита
CXбит в символескорость, бит/сек
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=04h
регистрстарший младший
AXбайт состояние линии LSRбайт состояние модема MSR
BX
CX
DX


INT 14h AH=05h- чтение/запись управляющего регистра модема MCR.
Применяется для моделей PS/2.
Чтение регистра MCR
выходные параметры INT14h AH=05h
регистрстарший младший
AX05h 00h
BX
CX
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=05h
регистрстарший младший
AX
BXрегистр MCR
CX
DX


Запись регистра MCR
выходные параметры INT14h AH=05h
регистрстарший младший
AX05h 01h
BXрегистр MCR
CX
DX(n-1), где n-номер COM порта

После выполнения функция возвращает выходные параметры :

выходные параметры INT14h AH=05h
регистрстарший младший
AXбайт состояние линии LSRбайт состояние модема MSR
BX
CX
DX




4.1.3. Программирование СОМ-порта с помощью средств MS-DOS.

Хотя СОМ порт и является основным коммуникационным средством ПК, в MS-DOS практически очень мало программных средств для эффективной работы с портом. Рассмотрим основные программные средства операционной системы MS-DOS:

Функции по прерыванию INT 21h

Существуют четыре функции программного прерывания INT 21h для работы с СОМ портом: 03h,04h,3Fh,40h.
Перед началом описания работы этих функций ознакомимся с понятием "описатель". Описатель- это идентификатор последовательного устройства(объекта) или файла в системе MS-DOS.
С точки зрения программы описатель это целое число, которое указывает на определённую программную структуру (объект), которая(который) обеспечивает работу этого устройства(объекта) с ОС.
Кто "дружит" с Windows, знает насколько важную роль имеет описатель(дескриптор) в этой системе, но начало этого было в MS-DOS.
В MS-DOS первые номера описателей отданы стандартным последовательным устройствам:
описательимяустройство
0CONстандартное устройство ввода (клавиатура)
1CONстандартное устройство вывода (дисплей)
2CONстандартное устройство вывода ошибок (всегда CON)
3AUXвспомогательное устройство (по умолчанию COM1)
4PRNстандартный вывод на печать (по умолчанию LPT1)

Описатель номер 3 называется AUX и адрес ввода-вывода этого устройства находится в ячейках BIOS с адресами 40h,41h.
Эти же ячейки определяют адрес ввода вывода СОМ1, если в эти ячейки записать число 2f8h, то устройством ввода-вывода по описателю 3 будет СОМ2.
Таким образом, на описатель 3 (AUX) может быть назначено любое последовательное устройство.

INT 21h AH=03h-ввод символа из AUX.
Эта функция ожидает ввода символа со стандартного вспомогательного устройства AUX
входные параметры INT21h AH=03h
регистрстарший младший
AX03h
BX
CX
DX

После выполнения функция возвращает выходные параметры :

выходные параметры INT21h AH=03h
регистрстарший младший
AXсимвол
BX
CX
DX
Ввод символов по этой функции не буферизируется и должен опрашиваться на готовность данных в UART.
Для чтения очередного символа необходимо убеждаться что 5-й бит регистра LSR равен 1 (DR=1).

INT 21h AH=04h-запись символа в AUX.
Эта функция записывает символ в стандартное вспомогательное устройство AUX
входные параметры INT21h AH=04h
регистрстарший младший
AX04h
BX
CX
DXсимвол

Выходных параметров у этой функции нет.

INT 21h AH=3Fh-чтение данных через описатель.
    При вызове этой функции читается количество символов записанных в регистре CX из устройства по описателю номер которого записан в регистре BX.
Считанные данные сохраняются в буфере, первый элемент которого указан в DS:DX.
После выполнения функции в регистре AX отражается количество полученных символов.
Если CX=AX и флаг CF=0, то функция выполнена без ошибок.

INT 21h AH=40h-запись данных через описатель.
    При вызове этой функции количество символов указанных в CX записываются в устройство по номеру описателя указанному в BX.
Данные содержатся в буфере по адресу указанному в DS:DX.
После вызова в регистр AX возвращается количество переданных символов.

Использование аппаратных прерываний

    Так как процесс последовательной передачи данных протекает медленно, можно выполнять его в фоновом режиме, используя прерывания по окончанию передачи или приема символа.
Напомним, что порту COM1 соответствует аппаратное прерывание IRQ4 с вектором INT 0Ch, а COM2 - IRQ3 с вектором INT 0Bh.
Для разрешения прерываний необходимо установить биты регистра управления прерыванием IER (UART), соответствующие тем прерываниям, которые нужно обрабатывать.
Когда происходит прерывание, программа-обработчик, расположенная по указанному вектору прерывания, должна проанализировать причину прерывания, прочитав регистр, идентифицирующий прерывания IIR.
Не забудьте, что в конце обработчика аппаратного прерывания должна находится последовательность команд:

	mov al, 20h
	out 20h, al
	iret
Чтобы была возможность обработки нескольких прерываний.

Использование команд MS-DOS

В MS-DOS имеется ряд встроенных команд для работы и настройки СОМ порта. Команды можно вставлять в пакетные файлы с расширением .bat для исполнения их по заданному сценарию.

Команда MODE
Команда Mode предназначена для изменения режима работы периферийных устройств. Формат:

	Mode COMx,бод,паритет,кадр,стоп,P
где: x-номер СОМ порта; бод- скорость: 110,150,300,600,1200,2400,4800,9600,19200 бод; паритет-n-нет, o-четность, e-нечетность; кадр- бит на символ: 7,8; стоп- число стоп битов: 1,2 P- задает режим повторения попыток передачи при неудаче.
В результате исполнения пакетного файла Test.bat строка записанная в файле data.txt будет передаваться в СОМ1 со скоростью 9600 бод, с проверкой на четность, 8 битами в символе, с одним стоп битом.
В этом пакетном файле мы использовали три MS-DOS команды:
В Windows также возможно исполнение пакетных файлом, но параметры команд необходимо записывать несколько иначе:
	mode com1 baud=9600 parity=n data=8 stop=1
	type c:\data.txt>com1
Кроме того, в Windows строку заканчивать символом Enter не обязательно.




4.2. Программирование в Windows.

    Программирование в операционных системах Windows 2000 и выше отличается от программирования в MS-DOS.
Во-первых, COM1-COM4 в этих системах не имеет стандартных адресов ввода вывода и стандартных номеров прерываний, Windows автоматически распределяет ресурсы для COM-портов.
Поэтому если вы захотите программировать СОМ-порт через порты ввода-вывода, вам понадобиться, сначала определить ресурсы которые занимает СОМ-порт на данном ПК.
Во-вторых, Windows не дает прямой возможности работать с портами ввода-вывода, это возможно только при программировании на уровне ядра ОС (что тоже не просто).
В принципе такой вариант программирования возможен, то есть пишите драйвер ядра для работы с портами ввода-вывода и программу для работы с СОМ-портом работающем через этот драйвер.

    Но, не всё так плохо. Естественно разработчики Windows предусмотрели возможность работы с коммуникационными портами через пользовательский интерфейс Windows.
Этот способ, наверное, даже проще чем программирование Сом-порта через порты ввода-вывода.
В Windows к Сом-порту можно обратиться как к файлу(потоку).
Достоинство этого способа очевидны: вам не надо думать о типе микросхемы UART, о номерах портов ввода-вывода и о номерах прерываний.
ОС незаметно для программиста работает с аппаратной частью коммуникационного порта.

4.2.1. Программирование СОМ-порта с помощью API функций Windows.

Попробуйте, создать в проводнике папку или файл с именем "СОМ1", сделать это не получится.
ОС Windows зарезервировала имена от СОМ1 до СОМ9 для работы с СОМ-портами.

Рассмотрим подробнее программирование СОМ-порта с помощью API-функций:

1. Для работы с СОМ-портом первое что надо сделать, это открыть порт.
Сделать это можно с помощью API функции CreateFile из библиотеки "kernel32" :
Эта функция создает новый объект и присваивает ему описатель, по которому с этим объектом можно будет работать.
Пример описания функции CreateFile на языке Си:

 HANDLE CreateFile(
     		LPCTSTR               lpFileName,
     		DWORD                 dwDesiredAccess,
     		DWORD                 dwShareMode,
     		LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    		DWORD                 dwCreationDistribution,
     		DWORD                 dwFlagsAndAttributes,
     		HANDLE                hTemplateFile
  			);

Пример декларирования функции CreateFile на языке VB6:

Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long

Чтобы открыть СОМ-порт вы должны выполнить эту функцию в коде своей программы, с заданными входными параметрами.
Результатом работы этой функции будет 32-битное число handle(описатель), по которому вы сможете обращаться к созданному функцией программному объекту связанному с выбранным СОМ-портом.

Пример открытия СОМ1 в VB6:

Com_Handle = CreateFile("COM1:", &HC0000000, 0, 0, 3, 0, 0)

Пример открытия СОМ1 в Си:

Com_Handle = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL, NULL);

2. После открытия СОМ порта можно передавать и принимать данные через этот СОМ-порт.
Для передачи данных используется API функция WriteFile из библиотеки kernel32.
Для приёма данных используется API функция ReadFile из библиотеки kernel32.

Пример описания функции ReadFile и WriteFile на языке Си:
BOOL ReadFile(
  HANDLE       hFile, // описатель сОМ порта
  LPVOID       lpBuffer, // Указатель на буфер, который принимает прочитанные данные из порта
  DWORD        nNumberOfBytesToRead,// Число байтов, которые читаются из порта
  LPDWORD      lpNumberOfBytesRead, // Указатель на переменную, которая получает число прочитанных байтов
  LPOVERLAPPED lpOverlapped    // Указатель на структуру OVERLAPPED.
			);

BOOL WriteFile(
  HANDLE       hFile,// описатель сом порта
  LPCVOID      lpBuffer,// Указатель на буфер, содержащий данные, которые будут записаны в файл. 
  DWORD        nNumberOfBytesToWrite,// Число байтов, которые будут записаны в файл.
  LPDWORD      lpNumberOfBytesWritten,//  Указатель на переменную, которая получает число записанных байтов
  LPOVERLAPPED lpOverlapped // Указатель на структуру OVERLAPPED
	);
Пример декларирования функции ReadFile и WriteFile на языке VB6:

Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Long) As Boolean

Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Long) As Boolean

С помощью этих функций из программного кода можно читать или записывать данные в указанный буфер.
Пример чтения 255 байт из порта в массив на языке VB6:

Dim File_Buffer(255) As Byte 'приемный буфер
Dim Com_Byte_Read As Long 'количество принятых байт
Dim Retval As Boolean
Retval = ReadFile(Com_Handle, File_Buffer(0), 255, Com_Byte_Read, 0)

3. После окончания работы с портом его нужно закрыть.
Закрытие порта осуществляется API функцией CloseHandle из библиотеки kernel32.

Пример описания функции CloseHandle на языке Си:
BOOL CloseHandle(
         HANDLE hObject   // описатель порта
          );
Пример декларирования функции CloseHandleна языке VB6:

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Boolean

Пример закрытия порта на языке VB6:

Dim Com_Exit as Boolean
Com_Exit = CloseHandle(Com_Handle)


4. Настройка режима работы сом порта осуществляется с помощью структур данных, которые представляют из себя набор переменных разного типа. Структуруы загружаются и читаются с помощью API функций.
Рассмотрим основные структуры для настройки режимов работы сом порта:

DCB структура

Структура DCB определяет основные настройки СОМ порта.
В ней содержиться реальная информация из регистров UART.
  typedef struct _DCB {
      DWORD DCBlength;            // длина структуры (DCB)
      DWORD BaudRate;             // скорость в бит/сек
      DWORD fBinary:1;            // бинарный режим
      DWORD fParity:1;            // разрешение контроля четности
      DWORD fOutxCtsFlow:1;       // слежение за CTS
      DWORD fOutxDsrFlow:1;       // слежение за DSR
      DWORD fDtrControl:2;        // режим работы сигнала DTR
      DWORD fDsrSensitivity:1;    // чувствительность к DSR
      DWORD fTXContinueOnXoff:1;  // продолжение передачи при XOFF
      DWORD fOutX:1;              // программное управление потоком при передачи (XON/XOFF)
      DWORD fInX:1;               // программное управление потоком при приеме (XON/XOFF)
      DWORD fErrorChar:1;         // замена ошибочных символов
      DWORD fNull:1;              // действия при приёме нулевого символа
      DWORD fRtsControl:2;        // Задает режим управления потоком для сигнала RTS
      DWORD fAbortOnError:1;      // игнорирование запись/чтение при ошибке
      DWORD fDummy2:17;           // зарезервировано
      WORD  wReserved;            // не используется, равно 0
      WORD  XonLim;               // мин. количество символов для посылки XON
      WORD  XoffLim;              // макс. кол-во символов для посылки XOFF
      BYTE  ByteSize;             // количество бит в символе
      BYTE  Parity;               // режим паритета 0-4=no,odd,even,mark,space
      BYTE  StopBits;             // длина стопового бита 0,1,2 = 1, 1.5, 2
      char  XonChar;              // символ для XON
      char  XoffChar;             // символ для XOFF
      char  ErrorChar;            // символ для замены ошибок
      char  EofChar;              // символ конца данных
      char  EvtChar;              // символ события
      WORD  wReserved1;           // резервный
  } DCB;
Для работы с DCB структурой используют API функции из библиотеки kernel32.:

BuildCommDCB- заполняет указанную структуру DCB значениями, заданными в строке управления устройством. Строка управления устройством использует синтаксис команды mode MS-DOS.
SetCommState- конфигурирует коммуникационное устройство согласно данным указанным в структуре DCB. Функция повторно инициализирует все аппаратные и управляющие настройки, но не опорожняет очереди вывода или ввода данных.
GetCommState- читает DCB структуру.

COMMTIMEOUTS структура

Данная структура задает временные параметры(задержки и таймауты) работы СОМ порта и определяет поведение функций ReadFile и WriteFile.
typedef struct _COMMTIMEOUTS {
  DWORD ReadIntervalTimeout; //интервал между символами
  DWORD ReadTotalTimeoutMultiplier; //множитель для периода простоя чтения
  DWORD ReadTotalTimeoutConstant; //постоянная для периода простоя чтения
  DWORD WriteTotalTimeoutMultiplier; //множитель для периода простоя записи
  DWORD WriteTotalTimeoutConstant; //постоянная для периода простоя записи
} COMMTIMEOUTS, 
*LPCOMMTIMEOUTS;
Для работы с COMMTIMEOUTS структурой используют API функции из библиотеки kernel32.:

SetCommTimeouts- устанавливает параметры простоя для всех операций чтения и записи для заданного коммуникационного устройства.
GetCommTimeouts- извлекает данные о параметрах простоя для всех операций чтения и записи на заданном коммуникационном устройстве.

COMMSTAT структура

Структура которая сообщает статус СОМ порта после обнаружения ошибки связи.
  typedef struct _COMSTAT {
  DWORD fCtsHold    :1;//ожидание символа CTS(готовности к приёму)
  DWORD fDsrHold    :1;//ожидание сигнала DSR(готовности модема)
  DWORD fRlsdHold   :1;//ожидание RSLD(детектор сигнала с линии)
  DWORD fXoffHold   :1;//ожидание передачи (был принят XOFF)
  DWORD fXoffSent   :1;//передача символа XOFF
  DWORD fEof        :1;//принят символ конец данных EOF
  DWORD fTxim       :1;//имеется очередь символов для передачи
  DWORD fReserved   :25;//резерв
  DWORD cbInQue;//число байтов полученых от ReadFile
  DWORD cbOutQue;//число байтов для WriteFile
} COMSTAT, 
*LPCOMSTAT;

Для работы с COMMSTAT структурой используют API функции из библиотеки kernel32.:

ClearCommError- Функция ClearCommError извлекает информацию об коммуникационной ошибке и сообщает о текущем состоянии коммуникационного устройства. Функция вызывается тогда, когда происходит ошибка обмена информацией и сбрасывает флажок ошибки устройства, чтобы включить в работу дополнительные операции ввода и вывода данных (I/O).

COMMPROP структура

Структура которая сообщает информацию о свойствах коммуникационного устройства.
  typedef struct _COMMPROP {
  WORD wPacketLength;//размер пакета данных
  WORD wPacketVersion;//версия структуры
  DWORD dwServiceMask;//битовая маска услуг поставщика
  DWORD dwReserved1;//резерв
  DWORD dwMaxTxQueue;//макс. размер передающего буфера
  DWORD dwMaxRxQueue;//макс. размер приёмного буфера
  DWORD dwMaxBaud;//макс. скорость в бит/сек
  DWORD dwProvSubType;//тип коммуникационного устройства
  DWORD dwProvCapabilities;//возможности предлагаемые поставщиком
  DWORD dwSettableParams;//параметр который может изменяться
  DWORD dwSettableBaud;//скорость разрешенная к использованию
  WORD wSettableData;//число битов в символе которые разрешено задавать
  WORD wSettableStopParity;//стоповые биты и паритет которые могут быть выбраны
  DWORD dwCurrentTxQueue;//текущий размер передающего буфера
  DWORD dwCurrentRxQueue;//текущий размер приёмного буфера
  DWORD dwProvSpec1;//данные определяемые поставщиком
  DWORD dwProvSpec2;//данные определяемые поставщиком
  WCHAR wcProvChar;//знаки определяемые поставщиком
} COMMPROP;


Для работы с COMMPROP структурой используют API функции из библиотеки kernel32:

GetCommProperties - Функция GetCommProperties извлекает информацию о коммуникационных характеристиках указанного коммуникационного устройства.

4.2.2. Программирование СОМ-порта с помощью внешних компонент ActiveX.

    Программирование работы СОМ порта с помощью внешних компонент один из наиболее распространённых и простых способов работы с СОМ портом.
Внешний компонент это программный модуль, который выполняет заданные функций и обладает всеми параметрами программного объекта.
Внешний компонент разрабатывается по технологии ActiveX, что позволяет ему встраиваться в любые проекты программ, написанных на языках программирования поддерживающих эту технологию.
Практически все современные средства разработки программ поддерживают технологию ActiveX.
Вы можете создавать проект своего приложения на C++, Delphi, VB, 1C,MS-Office и для работы с СОМ портом подключить готовую внешнюю компоненту.
При этом вам не нужно разбираться, как работает СОМ порт, это делает программный объект внешней компоненты, разработчик только использует свойства, методы и события этого объекта.
Технология ActiveX является логическим продолжением dll, DDE, OLE, COM технологий.

    Внешняя компонента(элемент ActiveX) является законченным программным продуктом и обладает всеми авторскими правами.
Поэтому разработчику необходимо помнить, что подключая элемент ActiveX, вы подключаете код чужой программы к своему проекту, и соответственно часть вашей программы будет написана разработчиком компоненты, что требует оплаты.
Внешних компонент для работы с СОМ портами написано большое количество.
Необходимо определиться какую компоненту, и на каких условиях вы будете применять в своём проекте.

Внешние компоненты оформлены в виде файлов и имеют расширение .ocx либо более раннее .dll.
Для того чтобы внешнюю компоненту можно было использовать в проекте, она должна быть зарегистрирована в ОС.
Регистрация компоненты осуществляется записью ключей в реестр ОС, с помощью специальной программы или команды "Зарегистрировать" из контекстного меню файла.

Для рассмотрения возьмём известную компоненту MSCOMM32.ocx написанную Microsoft и включенную в пакет разработчика Visual Studio Enterprise.
Подключите MSCOMM32.ocx к вашему проекту. После подключения компоненты к проекту вы сможете работать с объектом MSComm1.

Пример работы с СОМ портом на VB:
Private Sub Command1_Click()
    Dim Data_S As String

    MSComm1.CommPort = 1 'номер сом порта
    MSComm1.PortOpen = True 'открыть порт
    MSComm1.Settings = "9600,n,8,1" 'скорость 9600 бит/сек, без паритета, 8 бит в симв/, 1 стоп.
    Data_S = MSComm1.Input 'принять данные из порта
    MSComm1.Output = "Hello" ' передать данные в порт
    MSComm1.DTREnable = True ' включить сигнал DTR
    MSComm1.PortOpen = False 'закрыть порт
End Sub
	
В данной программе при нажатии кнопки 1 открывается порт СОМ1 на скорости 9600 бит/сек, без проверки паритета, 8 бит в символе, с одним стоповым битом.
В переменную DATA_S считывается строка символов из приёмного буфера СОМ1 и в передающий буфер СОМ1 выводится слово "Hello".
После этого включается сигнал DTR и порт закрывается.

Как видно из приведенного примера работа с Сом портом, при использовании элемента ActiveX, достаточно проста.
Кроме указанных свойств компонент MSCOMM32.ocx имеет большое количество других свойств, событий и методов, которые полнофункционально реализуют работу СОМ порта в ОС Windows.

       

§5 Программное обеспечение для работы с COM портами ПК.

Интерфейс RS-232, стал основой для промышленных сетей передачи данных.
Такие протоколы как ModBus, HART, ProfiBus DP, DCON, DH-485 , работают по сетям RS-485,RS-422, Bell-202 и др.
Аппаратной основой обработки данных в этих сетях является микросхема UART (СОМ порт), которая реализована на ПК в аппаратном или программном виде.
Даже когда используют USB модем, например для RS-485, он все равно работает через эмулированный СОМ порт ПК.

Протоколы передачи данных являются наиболее скрытной и засекреченной частью информационных каналов.
Это объясняется уязвимостью информации в процессе её передачи в физической среде.
Информацию по тому или иному протоколу связи приходится собирать по крупицам.
Специалисту, работающему с промышленными сетями необходима программа для чтения всей информации передаваемой в информационных сетях.
Основные секреты промышленных протоколов можно обнаружить только при всестороннем анализе переданных и полученных данных.
Рассмотрим программы для анализа сетей.

5.1 Программа   ComRead v.2.0 - сканер канала RS-232.

Эта программа предназначена для сохранения и отображения данных и сервисных сигналов передаваемых в информационных сетях, которые работают по стандартам RS-232, RS-485, ModBus, HART и др.
Программа не только сохраняет всю информацию, но и создает временную развертку данных и сервисных сигналов.
Программа ComRead v.2.0 сканирует информационный канал, не влияя на его работу, то есть работает в режиме прослушивания физической среды передачи информации.
Кроме того, программа может работать в режиме транслятора данных и сервисных сигналов.
При этом она становится непосредственной частью информационного канала связи.
Более подробно можно ознакомиться здесь .

5.2 Программа   ComPort v.1.0

Это простая программа служит для отображения состояния сразу 4-х СОМ портов ПК.
В текстовом и графическом виде можно посмотреть состояние всех сигнальных линий СОМ порта в текущем времени.
Порты можно настроить на любой режим работы.
Программа ComPort v.1.0 может генерировать и принимать циклические посылки данных.
Программа очень удобна при различных задачах.
Более подробно можно ознакомиться здесь .





§6.Заключение




Приложение 1

Примеры программирования COM-порта в Win32 с помощью API функций.

Реализация простых функций com-порта:
   -открытие порта
   -настройка порта
   -запись текста в порт
   -чтение текста из порта
   -закрытие порта

Напишем программу реализующие эти функции на различных языках программирования: VB6, MASM32, C

Исходник на VB6 COMAPIvb v.1.01   Скачать   
Исходник на MASM32 COMAPIas v.1.00   Скачать   
Исходник на C, скомпилирован на MS VC6++ COMAPIc v.1.00   Скачать   

Рис.28 Окно проекта COMAPI

Practical representation of the inferface RS-232

Программа работает следующим образом:
    -при нажатии кнопки Open port открывается сом-порт СОМ1
    -настройка СОМ1: 1200 бод, 8 бит на символ, с 1 стоповым битом, без проверки паритета
    -при нажатии кнопки Write port , стока записанная в Text2(Hello World!) посылается в СОМ1
    -при нажатии кнопки Read port, в Text1 помещается строка из приемного буфера СОМ1
    -при нажатии кнопки Close port, порт СОМ1 закрывается

Пример 1 Программа COMAPI на VB6 из пакета Visual Studio Enterprise с SP6 в ОС XP SP3

Вводим код модуля:


'COMAPIvb v.1.01
'Electron18
'www.softelectro.ru
'06.04.2012

Option Explicit

'The declaration of used functions API
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Long) As Boolean
Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Boolean
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function SetCommState Lib "kernel32" (ByVal hFile As Long, lpDCB As DCB) As Boolean
Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Boolean
Declare Function GetLastError Lib "kernel32" () As Long


Public Com_Handle As Long 'Descriptor of port
Public Buf(255) As Byte 'The buffer of port
Public Com_Byte_Read As Long 'количество принятых байт
'Structure for parameter setup of port
Type DCB
    DCBlength As Long       'Length of structure in byte.
    BaudRate As Long        'Speed of data exchangeб, bps
    fBitFields As Long      'Bit field for setting of port
    wReserved As Integer    'Reserved
    XonLim As Integer       'minimum number of bytes in the buffer to send Xon
    XoffLim As Integer      'maximum number of bytes in the buffer for sending Xof
    ByteSize As Byte        'the number of bits in a symbol
    Parity As Byte          'parity check mode
    StopBits As Byte        'Stop bit length
    XonChar As Byte         'character code Xon
    XoffChar As Byte        'character code Xof
    ErrorChar As Byte       'code symbol error
    EofChar As Byte         'character code data end
    EvtChar As Byte         'character code Events
    wReserved1 As Integer   'Reserved
End Type
Public DCB1 As DCB
'Structure for parameter setup of port
Type COMMTIMEOUTS
    ReadIntervalTimeout As Long       'интервал между символами
    ReadTotalTimeoutMultiplier As Long        'множитель для периода простоя чтения
    ReadTotalTimeoutConstant As Long      'постоянная для периода простоя чтения
    WriteTotalTimeoutMultiplier As Long    'множитель для периода простоя записи
    WriteTotalTimeoutConstant As Long       'постоянная для периода простоя записи
End Type
Public COMMTIMEOUTS1 As COMMTIMEOUTS


'Function of opening of port
Function Com_Open()
    Dim Retval As Long
    Dim Retval_B As Boolean
    Dim Retval_S As Boolean
    
    Retval = CreateFile("COM1:", &HC0000000, 0, 0, 3, 0, 0)
    If Retval = -1 Then
        MsgBox ("The open error of port:" & GetLastError)
    Else
        Com_Handle = Retval
        'set dcb
        DCB1.BaudRate = 1200
        DCB1.ByteSize = 8
        DCB1.DCBlength = 28
        DCB1.EofChar = 0
        DCB1.ErrorChar = 0
        DCB1.EvtChar = 0
        DCB1.fBitFields = 1
        DCB1.Parity = 0
        DCB1.StopBits = 0
        DCB1.wReserved = 0
        DCB1.wReserved1 = 0
        DCB1.XoffChar = 0
        DCB1.XoffLim = 0
        DCB1.XonChar = 0
        DCB1.XonLim = 0
        Retval_S = SetCommState(Com_Handle, DCB1)
        'set timeout
        COMMTIMEOUTS1.ReadIntervalTimeout = -1
        COMMTIMEOUTS1.ReadTotalTimeoutConstant = 0
        COMMTIMEOUTS1.ReadTotalTimeoutMultiplier = 0
        COMMTIMEOUTS1.WriteTotalTimeoutConstant = 5000
        COMMTIMEOUTS1.WriteTotalTimeoutMultiplier = 0
        Retval_B = SetCommTimeouts(Com_Handle, COMMTIMEOUTS1)
        
        If Retval_B = False Or Retval_S = False Then
            MsgBox ("Error DCB&Timout:" & GetLastError)
        End If
        MsgBox ("Open port HANDLE:" & Com_Handle)
       
    End If
    
End Function
'Function of closing the port
Function Com_Close()
    Dim Retval As Long
    
    Retval = CloseHandle(Com_Handle)
    If Retval = 0 Then
        MsgBox ("Close port ERROR:" & GetLastError)
    Else
        MsgBox ("Close port")
    End If
End Function

'Recording function to the port
Function Com_Write(n As Long)
    Dim Len_Buf As Long
    Dim Retval As Boolean
   
    Retval = WriteFile(Com_Handle, Buf(0), n, Len_Buf, 0)
    If Retval = False Then
        MsgBox ("Write port ERROR:" & GetLastError)
    Else
        MsgBox ("Data write: Ok")
    End If
    PurgeBuf
   
End Function

'function of reading from the port
Function Com_Read()
    Dim Retval As Boolean
    PurgeBuf
    Retval = ReadFile(Com_Handle, Buf(0), 255, Com_Byte_Read, 0)
    If Retval = False Then
        MsgBox ("Read port ERROR:" & GetLastError & Err.Description)
    Else
        MsgBox ("Data read: Ok")
    End If
  
End Function
'clear buffer
Sub PurgeBuf()
    Dim a As Integer
    
    For a = 0 To 255
        Buf(a) = &H20
    Next a
End Sub


Вводим код формы:

'COMAPIvb v.1.01
'Electron18
'www.softelectro.ru
'06.04.2012
Option Explicit

'Open port
Private Sub Command1_Click()
    Dim Retval As Boolean
    Retval = Com_Open
End Sub
'Close port
Private Sub Command2_Click()
    Dim Retval As Boolean
    Retval = Com_Close
End Sub
'Read port
Private Sub Command3_Click()
    Dim s As String
    Dim a As Long
    Com_Read
    For a = 1 To Com_Byte_Read
            s = s & Chr(Buf(a - 1))
    Next a
    Text1.Text = s
End Sub
'Write port
Sub Command4_Click()
    Dim s As String
    Dim n As Long
    Dim a As Integer
    Dim Retval As Long
    s = Text2.Text
    s = Mid(s, 1, 255)
    n = Len(s)
    For a = 1 To n
        Buf(a - 1) = Asc(Mid(s, a, 1))
    Next a
    Com_Write (n)
End Sub
'Exit programm
Private Sub Form_Unload(Cancel As Integer)
    Dim Retval As Long
    Retval = CloseHandle(Com_Handle)
End Sub


Пример 2 Программа COMAPIas на MASM32 v.10 в ОС XP SP3

	

;COMAPIas v.1.00
;htpp:\\www.softelectro.ru
;Electron18 
.386
.model flat,stdcall
option casemap:none

STYLBTN equ WS_CHILD + BS_DEFPUSHBUTTON + WS_VISIBLE
STYLEDT equ WS_CHILD+WS_VISIBLE+WS_BORDER+WS_TABSTOP 

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
PurgeBuf PROTO 

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.DATA
    ClassName db "SimpleWinClass",0
    AppName  db "COMAPIas v.1.00",0
        ;data button
   
    CLSBUTN         DB 'BUTTON',0
    CPBUT1          DB 'Open port',0
    HWNDBTN1        DD 0
    CPBUT2          DB 'Close port',0
    HWNDBTN2        DD 0
    CPBUT3          DB 'Read port',0
    HWNDBTN3        DD 0
    CPBUT4          DB 'Write port',0
    HWNDBTN4        DD 0
        ;data edit
    CLSEDIT         DB 'EDIT',0
    CPEDT1          DB ' ',0
    HWNDEDT1        DD 0
    CPEDT2          DB 'Hello World!',0
    HWNDEDT2        DD 0
    TEXT            DB 'Строка редактирования',0

        ;Message App
        ;App message
    uType           EQU 0
    lpCapApp        DB "App message",0
    lpApp1          DB "Open port HANDLE:", 6 dup(" "),0
    lpApp2          DB "Close port",0
    lpApp3          DB "Data read: Ok",0
    lpApp4          DB "Data write: Ok",0
    
        ;error message
    lpCapERR        DB "Error Message",0       
    lpERR1          DB "Open port Error:",10 dup(" "),0
    lpERR2          DB "DCB Structure ERROR:",10 dup(" "),0
    lpERR3          DB "SetComm Function ERROR:",10 dup(" "),0
    lpERR4          DB "Read port ERROR:",10 dup(" "),0
    lpERR5          DB "Write port ERROR:",10 dup(" "),0
    lpERR6          DB "Close port ERROR:",10 dup(" "),0
   
        ;data com port
    Mem1            DD 0
    Par1            DB "%lu",0
    Buf             DB 255 dup(" "),0
    HWNDCOM         DD 0
    LenBuf          DD 0
    NumCOM          DB "COM1:",0
    COMSETTING      DB "Com1: baud=1200 parity=N data=8 stop=1",0
    DCB1            DCB <>  

.DATA?
    hInstance       HINSTANCE ?
    CommandLine     LPSTR ?
   

.CODE
START:
	INVOKE GetModuleHandle, NULL
	   mov    hInstance,eax                                                ;handle app
	INVOKE GetCommandLine                                                  ;handle command line
	INVOKE WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT             ;input to app
	INVOKE ExitProcess,eax                                                 ;exit app
                                                                             ;main window
WinMain PROC hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hwnd:HWND
	   mov   wc.cbSize,SIZEOF WNDCLASSEX
	   mov   wc.style, CS_HREDRAW or CS_VREDRAW
	   mov   wc.lpfnWndProc, OFFSET WndProc
	   mov   wc.cbClsExtra,NULL
	   mov   wc.cbWndExtra,NULL
	   push  hInst
	   pop   wc.hInstance
	   mov   wc.hbrBackground,4;COLOR_MENU;COLOR_WINDOW
	   mov   wc.lpszMenuName,NULL
	   mov   wc.lpszClassName,OFFSET ClassName
	INVOKE LoadIcon,NULL,IDI_APPLICATION 
	   mov   wc.hIcon,eax                                                  ;handle icon
	   mov   wc.hIconSm,0
	INVOKE LoadCursor,NULL,IDC_ARROW
	   mov   wc.hCursor,eax                                                ;handle cursor
	INVOKE RegisterClassEx, addr wc                                        ;register class window
                                                                             ;create main window
	INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,20,20,800,200,NULL,NULL,hInst,NULL
	   mov   hwnd,eax                                     
	INVOKE ShowWindow, hwnd,SW_SHOWNORMAL                                  ;show window
	INVOKE UpdateWindow, hwnd                                              ;update window

                                                                             ;loop message
	.WHILE TRUE
                INVOKE GetMessage, ADDR msg,NULL,0,0                         ;get message
                .BREAK .IF (!eax)                           
                INVOKE TranslateMessage, ADDR msg                            ;get key char
                INVOKE DispatchMessage, ADDR msg                             ;call Win Proc
                
	.ENDW
	           mov     eax,msg.wParam                                     
	           ret
WinMain endp


                                                                             ;procedure window
WndProc PROC hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

      .IF uMsg==WM_DESTROY
	INVOKE PostQuitMessage,NULL  
      .ELSEIF uMsg==WM_COMMAND
                mov EAX, HWNDBTN1 
                cmp lParam, EAX
                je  BUTTON1_CLICK

                mov EAX, HWNDBTN2 
                cmp lParam, EAX
                je  BUTTON2_CLICK

                mov EAX, HWNDBTN3 
                cmp lParam, EAX
                je  BUTTON3_CLICK

                mov EAX, HWNDBTN4 
                cmp lParam, EAX
                je  BUTTON4_CLICK     

      .ELSEIF uMsg==WM_CREATE    
                                                                                ;create button1..4
            INVOKE CreateWindowEx, 0,OFFSET CLSBUTN,OFFSET CPBUT1,STYLBTN,10,10,100,20,hWnd,0,hInstance,0
                mov HWNDBTN1, EAX                                               ; handle button1
            INVOKE CreateWindowEx, 0,OFFSET CLSBUTN,OFFSET CPBUT2,STYLBTN,10,40,100,20,hWnd,0,hInstance,0
                mov HWNDBTN2, EAX                                               ; handle button2
            INVOKE CreateWindowEx, 0,OFFSET CLSBUTN,OFFSET CPBUT3,STYLBTN,10,70,100,20,hWnd,0,hInstance,0
                mov HWNDBTN3, EAX                                               ; handle button3
            INVOKE CreateWindowEx, 0,OFFSET CLSBUTN,OFFSET CPBUT4,STYLBTN,10,100,100,20,hWnd,0,hInstance,0
                mov HWNDBTN4, EAX                                               ; handle button4
                                                                                ;create edit1 and edit2
            INVOKE CreateWindowEx, 0,OFFSET CLSEDIT,OFFSET CPEDT1,STYLEDT,120,70,600,20,hWnd,0,hInstance,0
                mov HWNDEDT1, EAX                                               ; handle edit1
            INVOKE CreateWindowEx, 0,OFFSET CLSEDIT,OFFSET CPEDT2,STYLEDT,120,100,600,20,hWnd,0,hInstance,0
                mov HWNDEDT2, EAX                                               ; handle edit2
      
	.ELSE
		INVOKE DefWindowProc,hWnd,uMsg,wParam,lParam                        ;default message
		    ret
	.ENDIF
      jmp ENDMESS
      
BUTTON1_CLICK:                                                                  ;open port
            INVOKE CreateFile,OFFSET NumCOM, GENERIC_READ or GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL,NULL
                mov HWNDCOM, eax
                .IF EAX==-1
                    INVOKE GetLastError
                        mov Mem1,eax
                    INVOKE wsprintf,OFFSET lpERR1(17),OFFSET Par1,Mem1;
                    INVOKE MessageBoxA,NULL,OFFSET lpERR1,OFFSET lpCapERR,uType
                .ELSE
                    INVOKE wsprintf,OFFSET lpApp1(18),OFFSET Par1,HWNDCOM
                    INVOKE MessageBoxA,NULL,OFFSET lpApp1,OFFSET lpCapApp,uType
                    INVOKE BuildCommDCB,OFFSET COMSETTING, OFFSET DCB1
                    .IF EAX==0
                        INVOKE GetLastError
                            mov Mem1,eax
                        INVOKE wsprintf,OFFSET lpERR2(21),OFFSET Par1,Mem1;
                        INVOKE MessageBoxA,NULL,OFFSET lpERR2,OFFSET lpCapERR,uType
                    .ENDIF
                    INVOKE SetCommState,HWNDCOM,OFFSET DCB1
                    .IF EAX==0
                        INVOKE GetLastError
                            mov Mem1,eax
                        INVOKE wsprintf,OFFSET lpERR3(24),OFFSET Par1,Mem1;
                        INVOKE MessageBoxA,NULL,OFFSET lpERR3,OFFSET lpCapERR,uType
                    .ENDIF
                .ENDIF
            jmp ENDMESS
            
BUTTON2_CLICK:                                                                  ;close port
            INVOKE CloseHandle,HWNDCOM
             .IF EAX==0
                INVOKE GetLastError
                    mov Mem1,eax
                INVOKE wsprintf,OFFSET lpERR6(18),OFFSET Par1,Mem1;
                INVOKE MessageBoxA,NULL,OFFSET lpERR6,OFFSET lpCapERR,uType
            .ELSE
                INVOKE MessageBoxA,NULL,OFFSET lpApp2,OFFSET lpCapApp,uType
            .ENDIF


            
            jmp ENDMESS
            
BUTTON3_CLICK:
            CALL  PurgeBuf                                                                   ;read port                          
            INVOKE ReadFile,HWNDCOM,OFFSET Buf, SIZEOF Buf,OFFSET LenBuf, NULL
            .IF EAX==0
                INVOKE GetLastError
                    mov Mem1,eax
                INVOKE wsprintf,OFFSET lpERR4(17),OFFSET Par1,Mem1;
                INVOKE MessageBoxA,NULL,OFFSET lpERR4,OFFSET lpCapERR,uType
            .ELSE
                INVOKE SendMessage,HWNDEDT1,WM_SETTEXT,SIZEOF Buf,OFFSET Buf
                INVOKE MessageBoxA,NULL,OFFSET lpApp3,OFFSET lpCapApp,uType
            .ENDIF
            jmp ENDMESS
            
BUTTON4_CLICK:                                                                  ;write port
                CALL  PurgeBuf
                INVOKE SendMessage,HWNDEDT2,WM_GETTEXT,SIZEOF Buf,OFFSET Buf
                INVOKE WriteFile,HWNDCOM,OFFSET Buf, SIZEOF Buf,OFFSET LenBuf, NULL
            .IF EAX==0
                INVOKE GetLastError
                    mov Mem1,eax
                INVOKE wsprintf,OFFSET lpERR5(18),OFFSET Par1,Mem1;
                INVOKE MessageBoxA,NULL,OFFSET lpERR5,OFFSET lpCapERR,uType
            .ELSE
                INVOKE MessageBoxA,NULL,OFFSET lpApp4,OFFSET lpCapApp,uType
            .ENDIF
 
            jmp ENDMESS



ENDMESS:
	xor    eax,eax
	ret
WndProc ENDP
                                                                ; clear buffer
PurgeBuf PROC
    push ebx
    push ecx
   
    mov cx,255
    mov ebx,offset Buf
    mov al,20h
 L:
    mov [ebx],al
    inc ebx
    LOOP L

    pop ecx
    pop ebx
    xor    eax,eax
    ret
PurgeBuf ENDP

END START


Пример 3 Программа COMAPIc v.1.00 на C, компилирована в MS VC6++ Enterpise SP6 в ОС XP SP3

	
// COMAPIc.cpp 
// www.softelectro
//Electron18

#include "stdafx.h"
#define STYLBTN WS_CHILD|BS_DEFPUSHBUTTON|WS_VISIBLE
#define STYLEDT WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP 

 		//data main window
	HINSTANCE hInst;											
	LPCTSTR szTitle="COMAPIc v.1.00";						
	LPCTSTR szWindowClass="SimpleWinClass";
		//data control
	LPCTSTR CLSBUTN="BUTTON";
	LPCTSTR CPBUT1="Open port";
	LPCTSTR CPBUT2="Close port";
	LPCTSTR CPBUT3="Read port";
	LPCTSTR CPBUT4="Write port";
	LPCTSTR CLSEDIT="EDIT";
	LPCTSTR CPEDT1;
	LPCTSTR CPEDT2="Hello World!";
	HWND HWNDBTN1;
	HWND HWNDBTN2;
	HWND HWNDBTN3;
	HWND HWNDBTN4;
	HWND HWNDEDT1;
	HWND HWNDEDT2;  
	HMENU ID_BTN1=(HMENU) 101;
	HMENU ID_BTN2=(HMENU) 102;
	HMENU ID_BTN3=(HMENU) 103;
	HMENU ID_BTN4=(HMENU) 104;
	
        //App message
	LPCTSTR  lpCapApp = "App message";
	char  lpApp1[40]   = "Open port HANDLE:";
	LPCTSTR  lpApp2    ="Close port";
	LPCTSTR  lpApp3    ="Data read: Ok";
	LPCTSTR  lpApp4    ="Data write: Ok";
    
        //error message
	LPCTSTR  lpCapERR  ="Error Message";       
	char lpERR1[40]={"Open port Error:"};
	char lpERR2[40]={"DCB Structure ERROR:"};
	char lpERR3[40]={"SetComm Function ERROR:"};
	char lpERR4[40]={"Read port ERROR:"};
	char lpERR5[40]={"Write port ERROR:"};
	char lpERR6[40]={"Close port ERROR:"};
	DWORD Mem1;
	LPCTSTR Par1        ="%lu";

		//data com port	
	HANDLE HWNDCOM;
	LPCTSTR lpNumCOM="COM1:";
	LPCTSTR COMSETTING="Com1: baud=1200 parity=N data=8 stop=1";
	char Buf[255];
	DWORD LenBuf;
	DCB DCB1;

	
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);

void PurgeBuf()
{
	int a;
	for (a=0;a<255;a++)
	{
		Buf[a]=0x20;
	}
	return;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	
	MSG msg;
	WNDCLASSEX wcex;
	HWND hWnd;
    hInst=hInstance;

	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wcex.hIconSm		= 0;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(4);
	wcex.lpszMenuName	= 0;
	wcex.lpszClassName	= szWindowClass;
	RegisterClassEx(&wcex);

	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,20, 20, 800, 200, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, SW_SHOWNORMAL);
   UpdateWindow(hWnd);


	

	while (GetMessage(&msg, NULL, 0, 0)) 
	{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
	}

	return 0;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{	
	int wmId, wmEvent;
	int Retval;
	switch (message)

	{
		case WM_COMMAND:
				wmId    = LOWORD(wParam); 
				wmEvent = HIWORD(wParam); 
				switch (wmId)
			{
				case 101: //open port
					HWNDCOM=CreateFile(lpNumCOM, GENERIC_READ|GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, NULL,NULL);
               
					if (HWNDCOM==INVALID_HANDLE_VALUE)
						{
							Mem1= GetLastError();
							wsprintf(&lpERR1[16],Par1,Mem1);
							MessageBox(0,lpERR1,lpCapERR,0);
						}
					else
						{   
							wsprintf(&lpApp1[17],Par1,HWNDCOM);
							MessageBoxA(0,lpApp1,lpCapApp,0);
							Retval=BuildCommDCB(COMSETTING,&DCB1);
							if (Retval==0)	//error DCB
								{
									Mem1= GetLastError();
									wsprintf(&lpERR2[20],Par1,Mem1);
									MessageBox(0,lpERR2,lpCapERR,0);
								}
							Retval=SetCommState(HWNDCOM,&DCB1);
							if (Retval==0)	//error SetCom
								{
									Mem1= GetLastError();
									wsprintf(&lpERR3[23],Par1,Mem1);
									MessageBox(0,lpERR3,lpCapERR,0);
								}
			   

						}
							break;

				case 102:			//close port
					Retval=CloseHandle(HWNDCOM);
					if (Retval==0) //error close port
						{
							Mem1= GetLastError();
							wsprintf(&lpERR6[17],Par1,Mem1);
							MessageBox(0,lpERR6,lpCapERR,0);
						}
					else
						{
							MessageBox(0,lpApp2,lpCapApp,0);
						}
					break;

				case 103:		//read port
					PurgeBuf();
					Retval= ReadFile(HWNDCOM,&Buf, 255,&LenBuf, NULL);
					if (Retval==0) //error read port
						{
							Mem1= GetLastError();
							wsprintf(&lpERR4[16],Par1,Mem1);
							MessageBox(0,lpERR4,lpCapERR,0);
						}
					else
						{
							SendMessageA(HWNDEDT1,WM_SETTEXT,sizeof Buf,(LPARAM) Buf);
							MessageBox(0,lpApp3,lpCapApp,0);
						}
           
						break;
				case 104:		//write port
					PurgeBuf();
					SendMessage(HWNDEDT2,WM_GETTEXT,sizeof Buf,(LPARAM) Buf);
					Retval= WriteFile(HWNDCOM,&Buf, sizeof Buf,&LenBuf, NULL);
					if (Retval==0) //error write port
						{
							Mem1= GetLastError();
							wsprintf(&lpERR5[17],Par1,Mem1);
							MessageBox(0,lpERR5,lpCapERR,0);
						}
					else
						{
							MessageBox(0,lpApp4,lpCapApp,0);
						}
						break;
				default:
						{ 
							return DefWindowProc(hWnd, message, wParam, lParam);
						}
			}
			break;
		case WM_CREATE:
			HWNDBTN1= CreateWindowEx( 0,CLSBUTN,CPBUT1,STYLBTN,10,10,100,20,hWnd,ID_BTN1,hInst,0);
			HWNDBTN2= CreateWindowEx( 0,CLSBUTN,CPBUT2,STYLBTN,10,40,100,20,hWnd,ID_BTN2,hInst,0);
			HWNDBTN3= CreateWindowEx( 0,CLSBUTN,CPBUT3,STYLBTN,10,70,100,20,hWnd,ID_BTN3,hInst,0);
			HWNDBTN4= CreateWindowEx( 0,CLSBUTN,CPBUT4,STYLBTN,10,100,100,20,hWnd,ID_BTN4,hInst,0);
			HWNDEDT1= CreateWindowEx(0,CLSEDIT,CPEDT1,STYLEDT,120,70,600,20,hWnd,0,hInst,0);
			HWNDEDT2= CreateWindowEx(0,CLSEDIT,CPEDT2,STYLEDT,120,100,600,20,hWnd,0,hInst,0);

			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}





// stdafx.cpp : source file that includes just the standard includes
//	COMAPIc.pch will be the pre-compiled header
//	stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file




// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)
#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

#include 


// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)


Источники информации:
1. American National Standart. ANSI/TIA/EIA-232-F-1997 30.09.1997
Interface Between Data Terminal Equipment and Data Circuit-Terminating Equipment Employing Serial Binary Data Interchange
2. ITU-T v.24 02.2000
List of definitions for interchange circuits between data terminal equipment (DTE) and data circuit-terminating equipment (DCE)
3. ITU-T v.28 03.1993
ELECTRICAL CHARACTERISTICS FOR UNBALANCED DOUBLE-CURRENT INTERCHANGE CIRCUITS
4. ГОСТ 18145-81
Цепи на стыке С2 аппаратуры передачи данных с оконечным оборудованием при последовательном вводе-выводе данных.
5. National Semiconductor. DataSheet.
PC16550D Universal Asynchronous Receiver/Transmitter with FIFOs. June 1995.

Назад   Главная