Модемы и факс-модемы. Программирование для MS-DOS и Windows.
© Александр Фролов, Григорий Фролов
Том 16, М.: Диалог-МИФИ, 1993.
Библиотеки трансляторов Borland C++ и Turbo C содержат
две функции управления портами асинхронного последовательного адаптера - bioscom
и _bios_serialcom. Обе эти функции обладают одинаковыми возможностями, но
функция _bios_serialcom совместима с функцией _bios_serialcom из библиотек
трансляторов фирмы Microsoft. Функция bioscom помечена в документации как
устаревшая и оставлена для совместимости с ранними версиями трансляторов фирмы
Borland.
Функции _bios_serialcom и bioscom управляют асинхронным
последовательным портом компьютера через прерывание BIOS INT 0x14. Вследствие
этого функция bioscom может не работать со скоростями больше чем 9600 бит/сек.
Если вам нужны программы, обеспечивающие более высокие скорости, необходимо
использовать непосредственное программирование портов асинхронного
последовательного адаптера.
Рассмотрим функцию _bios_serialcom более подробно. Она
объявлена в файле BIOS.H следующим образом:
unsigned _bios_serialcom( unsigned service, unsigned
serial_port, unsigned data );
Первый аргумент функции - serial_port - определяет номер
порта. Для порта COM1 этот аргумент должен быть равен 0, для COM2 - 1 и так
далее.
Второй аргумент - service - определяет производимое
функцией действие и может содержать одну из следующих констант:
Константа |
Назначение |
_COM_INIT |
Инициализация последовательного порта |
_COM_RECEIVE |
Принять байт |
_COM_SEND |
Передать байт |
_COM_STATUS |
Определить состояние порта |
Назначение третьего аргумента функции - data - зависит
от значения аргумента service. Если аргумент service установлен на _COM_RECEIVE
или _COM_STATUS, то значение аргумента data безразлично. Если аргумент service
установлен как _COM_INIT, то этот аргумент может состоять из одного или
нескольких констант, объединенных булевой операцией ИЛИ. Данные константы
приведены в следующей таблице:
Константа |
Назначение |
_COM_CHR7 |
Передавать семь битов на символ |
_COM_CHR8 |
Передавать восемь битов на символ |
_COM_STOP1 |
Использовать один стоповый бит |
_COM_STOP2 |
Использовать два стоповых бита |
_COM_NOPARITY |
Не выполнять проверки на четность |
_COM_EVENPARITY |
Выполнять проверку на четность |
_COM_ODDPARITY |
Выполнять проверку на нечетность |
_COM_110 |
Установить скорость 110 бит/с |
_COM_150 |
Установить скорость 150 бит/с |
_COM_300 |
Установить скорость 300 бит/с |
_COM_600 |
Установить скорость 600 бит/с |
_COM_1200 |
Установить скорость 1200 бит/с |
_COM_2400 |
Установить скорость 2400 бит/с |
_COM_4800 |
Установить скорость 4800 бит/с |
_COM_9600 |
Установить скорость 9600 бит/с | По умолчанию
используется один стоповый бит, проверка на четность не выполняется, обмен
происходит со скоростью 110 бит/с.
Функция возвращает 16-битное целое число. В старшем
байте возвращаемого значения содержатся биты, определяющие состояние
последовательного порта. Содержимое младшего байта зависит от значения параметра
service, с которым вызывалась функция.
Назначение отдельных бит старшего байта представлено в
следующей таблице:
Бит |
Если бит установлен |
15 |
Исчерпан лимит времени (тайм-аут) |
14 |
Регистр сдвига передатчика свободен (пуст) |
13 |
Регистр передатчика свободен (пуст) |
12 |
Произошел разрыв связи (состояние BREAK) |
11 |
Ошибка в управляющих битах (ошибка
синхронизации) |
10 |
Ошибка четности |
9 |
Ошибка переполнения |
8 |
Данные готовы |
Когда аргумент service равен _COM_SEND, бит 15
устанавливается в единицу, если данные не могут быть переданы.
Если аргумент service равен _COM_RECEIVE и чтение байта
произошло успешно, он находится в младшем байте возвращаемого функцией значения.
Если чтение произошло с ошибками, это отражается битами 9, 10, 11 или 15.
Если атрибут service равен _COM_INIT или _COM_STATUS,
биты младшего байта определяются следующим образом:
Бит |
Значение |
7 |
Состояние линии DCD |
6 |
Состояние линии RI |
5 |
Состояние линии DSR |
4 |
Состояние линии CTS |
3 |
Линия DCD изменила состояние |
2 |
Линия RI изменила состояние |
1 |
Линия DSR изменила состояние |
0 |
Линия CTS изменила состояние | Приведем
небольшой пример использования функции. В этом примере функция _bios_serialcom()
сначала инициализирует последовательный порт, а затем передает символы,
набранные на клавиатуре в порт, а символы, считанные из порта, - на экран
компьютера (см. листинг 5.10).
Для того чтобы введенные символы отображались на экране,
надо соединить выход COM-порта с входом. Или использовать два компьютера,
соединенных нуль-модемом, запустив программу одновременно на обоих
компьютерах.
Листинг 5.10. Файл SERIAL.C
// Программа иллюстрирует доступ к последовательному порту
// через функцию _bios_serialcom()
#include // необходимо включить при
// использовании _bios_serialcom()
#include
#define COM1 0 // первый последовательный порт
#define DATA_READY 0x100 // данные приняты и готовы для
// чтения
int main(void) {
unsigned in, out, status;
// Инициализируем последовательный порт
// устанавливаем скорость 1200 бит/с, 8 битов на символ, один
// стоповый бит
_bios_serialcom( _COM_INIT, COM1, _COM_1200 |
_COM_CHR8 | _COM_STOP1);
printf("\n\n Для выхода нажмите клавишу [ESC]\n");
for(;;) {
// Определяем состояние последовательного порта
status = _bios_serialcom(_COM_STATUS, COM1, 0);
// Если данные готовы, считываем их из
// последовательного порта и выводим на экран дисплея
if(status & DATA_READY)
if((out = _bios_serialcom(_COM_RECEIVE, COM1, 0) &
0x7F) != 0)
putch(out);
// Проверяем, не нажата ли клавиша на клавиатуре?
if(kbhit()) {
// Если нажата клавиша [ESC] выходим из программы
if((in = getch()) == 0x1b)
break;
// В противном случае передаем код нажатой клавиши
// на асинхронный последовательный порт
_bios_serialcom(_COM_SEND, COM1, in);
}
}
return(0);
}
Теперь рассмотрим функцию bioscom() из библиотеки
трансляторов Borland C++ и Turbo C. Эта функция отмечена в документации на
Borland C++ версии 4.0, как устаревшая:
int bioscom(int service, char data, int
serial_port);
Функция аналогична функции _bios_serialcom(), за
исключением следующих моментов:
Отличается порядок следования аргументов функции;
Не соответствуют типы аргументов, имеющие одинаковый
смысл;
Рассмотрим подробнее аргументы функции bioscom(). Первый
аргумент функции - serial_port - определяет номер порта. Для COM1 этот аргумент
должен быть равен 0, для COM2 - 1 и так далее.
Назначение второго аргумента функции - data - зависит от
значения аргумента service. Если аргумент service равен единице (_COM_RECEIVE)
или тройке (_COM_STATUS), то значение аргумента data безразлично. Если аргумент
service равен нулю (_COM_INIT), то этот аргумент может состоять из одного или
нескольких битовых полей (констант), объединенных булевой операцией ИЛИ (|).
Данные константы приведены в следующей таблице:
Константа |
Значение |
0x02 (_COM_CHR7) |
Передавать семь битов на символ (байт) |
0x03 (_COM_CHR8) |
Передавать восемь битов на символ |
0x00 (_COM_STOP1) |
Использовать один стоповый бит |
0x04 (_COM_STOP2) |
Использовать два стоповых бита |
0x00 (_COM_NOPARITY) |
Не проводить проверки на четность |
0x18 (_COM_EVENPARITY) |
Проводить проверку на четность |
0x08 (_COM_ODDPARITY) |
Проводить проверку на нечетность |
0x00 (_COM_110) |
Установить скорость 110 бит/с |
0x20 (_COM_150) |
Установить скорость 150 бит/с |
0x40 (_COM_300) |
Установить скорость 300 бит/с |
0x60 (_COM_600) |
Установить скорость 600 бит/с |
0x80 (_COM_1200) |
Установить скорость 1200 бит/с |
0xa0 (_COM_2400) |
Установить скорость 2400 бит/с |
0xc0 (_COM_4800) |
Установить скорость 4800 бит/с |
0xe0 (_COM_9600) |
Установить скорость 9600 бит/с |
По умолчанию используется один стоповый бит, не
проводится проверка на четность, обмен происходит со скоростью 110 бит/с.
Третий аргумент - service - может принимать следующие
значения:
Константа |
Значение |
0 (_COM_INIT) |
Инициализация последовательного порта |
1 (_COM_RECEIVE) |
Принять байт |
2 (_COM_SEND) |
Передать байт |
3 (_COM_STATUS) |
Определить состояние порта | Аналогично
функции _bios_serialcom() функция bioscom() возвращает 16-битовое целое число. В
старшем байте возвращаемого значения содержатся биты, определяющие состояние
последовательного порта. Содержимое младшего байта зависит от значения параметра
service, с которым вызывалась функция.
Возможные значения для старшего байта представлены в
следующей таблице:
Бит |
Если бит установлен |
15 |
Исчерпан лимит времени (тайм-аут) |
14 |
Регистр сдвига передатчика свободен (пуст) |
13 |
Регистр передатчика свободен (пуст) |
12 |
Произошел разрыв связи (состояние BREAK) |
11 |
Ошибка в управляющих битах (ошибка
синхронизации) |
10 |
Ошибка четности |
9 |
Ошибка переполнения |
8 |
Данные готовы | Если атрибут
service равен _COM_INIT или _COM_STATUS, биты младшего байта используются
следующим образом:
Бит |
Значение |
7 |
Состояние DCD
линии |
6 |
Состояние RI
линии |
5 |
Состояние DSR
линии |
4 |
Состояние CTS
линии |
3 |
Линия DCD изменила
состояние |
2 |
Линия RI изменила
состояние |
1 |
Линия DSR изменила
состояние |
0 |
Линия CTS изменила
состояние |
|