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

       

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


Библиотеки трансляторов 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.h>            // необходимо включить при

                                                         // использовании _bios_serialcom()

#include <stdio.h>

#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_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 изменила состояние


Содержание раздела