Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Модемы и факс-модемы. Программирование для MS-DOS и Windows.

© Александр Фролов, Григорий Фролов
Том 16, М.: Диалог-МИФИ, 1993.

[Назад] [Содеожание] [Дальше]

5.9. Стандартные функции библиотеки Си

Библиотеки трансляторов 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 изменила состояние


[Назад] [Содеожание] [Дальше]