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

         

Как заполнить или модифицировать структуру DCB


На этом мы заканчиваем описание структуры DCB. В заключение приведем несколько советов по модификации полей этой структуры.

Структура DCB заполняется двумя функциями - OpenComm и BuildCommDCB. Однако существует много полей в структуре DCB, которые нельзя изменить с помощью этих функций. Для этого надо непосредственно записать новые значения в поля структуры, а затем воспользоваться функцией SetCommState, чтобы внесенные изменения отразились на работе COM-порта.

Если вам нужно изменить какое-либо поле этой структуры, следует сначала узнать текущее значение полей структуры DCB, с помощью функции GetCommState. Затем внесите все необходимые изменения в поля структуры и вызовите функцию SetCommState, чтобы соответственно изменился режим COM-порта.

Такой алгоритм гарантирует, что остальные поля структуры DCB перед вызовом SetCommState будут содержать правильные значения.

В качестве альтернативного способа изменения структуры DCB можно воспользоваться функцией BuildCommDCB. Этой функции передается в качестве параметра строка, имеющая формат команды MODE операционной системы MS-DOS. Данная строка может содержать значения скорости передачи данных, количества бит данных и стоповых бит в слове.

Функция BuildCommDCB заполняет структуру DCB, но не изменяет состояния COM-порта. Для этого следует воспользоваться функцией SetCommState.

В начале работы с COM-портом приложение должно открыть его с помощью функции OpenComm. Функция OpenComm с помощью функции BuildCommDCB заполняет временный, недоступный программисту, блок DCB значениями по умолчанию. Скорость обмена устанавливается равной 9600 бит/с., проводится проверка на четность, передаваемые символы содержат 7 информационных и один стоповый бит. Затем функция OpenComm выполняет внутренний вызов функции SetCommState с подготовленной структурой DCB, устанавливая начальный режим COM-порта. Затем можно создать собственную структуру DCB и установить новый режим COM-порта, вызвав функцию SetCommState.

Функция SetCommState принимает в качестве параметра указатель на заполненную структуру DCB и устанавливает режим работы COM-порта в соответствии с данными из этой структуры.

Вы также можете узнать текущее состояние COM-порта с помощью функции GetCommState.



Команда MODE операционной системы MS-DOS


Операционная система MS-DOS позволяет задать режим работы портов асинхронного последовательного адаптера (COM1, COM2, COM3, и COM4) непосредственно из строки системного приглашения с помощью команды MODE. Команда MODE позволяет установить скорость передачи данных, режим проверки на четность, количество информационных и стоповых бит в передаваемых словах (символах).

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

MODE COMm[:] [b[,p[,d[,s[,r]]]]]

MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s] [RETRY=r]

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

Параметр COMm задает номер COM-порта. Этот параметр может принимать значения от 1 до 4.

Параметр b задает скорость передачи информации. Может состоять из двух цифр, являющихся первыми двумя цифрами устанавливаемой скорости. В следующей таблице представлены возможные значения для параметра b и соответствующие им скорости передачи информации в битах за секунду.



Параметр b

Скорость передачи, бит за секунду (baud)

11

110

15

150

30

300

60

600

12

1200

24

2400

48

4800

96

9600

19

19200

Параметр p определяет, как будет использоваться бит четности при передаче данных по линии. Параметр может принимать одно из четырех значений - N, E, O, M, S. В следующей таблице описаны эти значения:

Параметр p

Режим проверки на четность

N

Проверка на четность не производится

E

Проверка на четность. Этот режим применяется по умолчанию

O

Проверка на нечетность

M

Бит четности всегда установлен

S

Бит четности всегда сброшен

Параметр d определяет количество бит в символах. Может принимать значения от 5 до 8. По умолчанию устанавливается значение 7.

Параметр s    задает количество стоповых бит, определяющих конец символа. Возможные значения 1, 1.5 или 2. Если устанавливается скорость передачи 110, то по умолчанию используются два стоповых бита. При других скоростях используется один стоповый бит.

Параметр r используется при работе с принтерами, подключенными к асинхронному последовательному адаптеру, и нами не рассматривается.



Команды модемов с протоколом MNP, CCITT V.42 и V.42 bis


Для управления модемами, аппаратно поддерживающими протоколы коррекции ошибок и сжатия передаваемой информации, расширенный набор AT-команд был дополнен новыми командами. В этом разделе мы опишем эти дополнительные команды. У модемов без аппаратной поддержки этих протоколов данные команды отсутствуют.

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



Коммуникационная программа


Теперь мы приступим к самому интересному - приведем подробный алгоритм коммуникационной программы, а затем - исходный текст такой программы.

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

Итак, приступим. Как мы сказали ранее, первым шагом при программировании модема надо считать инициализацию COM-порта (микросхемы UART), к которому подключен модем.

Программа, представленная в предыдущей главе, имеет один большой недостаток: она должна постоянно выполнять опрос регистра состояния линии с тем, чтобы определить момент, когда от модема поступит очередной символ. В результате становится трудной, а иногда невозможной, обработка поступающих символов. Например, если вы сразу отображаете символы, получаемые от COM-порта, на экране, то при использовании для этого функции putch отдельные символы могут быть потеряны. Дело в том, что функция putch работает слишком медленно и на скоростях 2400 бит/с и выше модем может успеть передать в COM-порт несколько новых символов, в то время как функция putch еще не вывела на экран ни одного символа. В этом случае происходит ошибка переполнения входного буфера микросхемы UART (см. бит D2 регистра состояния линии).

Таким образом, имеет смысл организовать прием и передачу символов модему в фоновом режиме, используя прерывания по окончании приема и передачи символа.


             printf("\nFOSSIL-драйвер неустановлен\n");

             exit(-1);

      }

      // Определяем возможность эмуляции FOSSIL-драйвером

      // протокола MNP

      _asm {

             mov   ah,0E0h

             mov   al,6h

             xor   bx,bx

             int   14h

             mov   signatura,bx

      }

      mnp = ( signatura != 0x4D58 ) ? 0 : 1;

      printf("Эмуляция MNP %s.\n\n", (mnp) ? "поддерживается"

                                                     : "не поддерживается");

      if(mnp)

             printf("PageUp - режим вызова, "

                                      "PageDown - режим ответа\n\n");

      _asm {

             // Устанавливаем скорость обмена и формат данных

             xor   ah,ah

             mov   al,0A3h

             mov   dx,com_port_num

             int   14h

             // Устанавливаем сигнал DTR в активное состояние

             mov   ah,6

             mov   al,1

             mov   dx,com_port_num

             int   14h

             // Запрещаем использование режима управления потоком

             mov   ah,0Fh

             xor   al,al

             mov   dx,com_port_num

             int   14h

      }

      // Начинаем обмен данными между компьютером и модемом

      do_chat();

}

//********************************************************

// Функция do_chat

//********************************************************

void do_chat( void ) {

      while(1) {

             unsigned char key,stey;

             unsigned i,j;

             // Если пользователь нажал на клавиатуру, получаем код

             // нажатого символа и передаем его модему

             if( kbhit() ) {

                   key =  getch();

                   if(( key == 0 ) && mnp) {

                         key =  getch();

                         if( key == 73 )      origin();

                         else if( key == 81 ) answer();

                         continue;

                   }



                   // По нажатию клавиши Esc выходим из программы

                   if( key == 27 ) {

                         _asm {

                                // Сбрасываем сигнал DTR

                                mov   ah,06h

                                xor   al,al

                                mov   dx,com_port_num

                                int   14h

                                // Отключаем FOSSIL-драйвер

                                mov   ah,05h

                               mov   dx,com_port_num

                                int   14h

                         }

                         return;

                   }

                   // Если нажата клавиша Enter переводим строку

                   if( key == '\r' ) {

                         key = 13;

                         putch('\n');

                   }

                   // Выводим ASCII код нажатого на клавиатуре символа

                   // на экран

                   putch(key);

                   // Передаем ASCII код нажатого на клавиатуре символа

                   // FOSSIL-драйверу, для дальнейшей передачи его модему

                   _asm {

                         mov   dx,com_port_num

                         mov   ah,1

                         mov   al,key

                         int   14h

                   }

             }

             // Определяем состояние приемного буфера FOSSIL-драйвера

             _asm {

                   mov   dx,com_port_num

                   mov   ah,3

                   int   14h

                   and   ah,01h

                   mov   stey,ah

             }

             // Если приемный буфер содержит данные, выводим их

             // на экран дисплея

             if( stey > 0 ) {

                   _asm {

                         mov   dx,com_port_num

                         mov   ah,2

                         int   14h

                         mov   stey,al

                   }

                   putch(stey);

             }



      }

}

//********************************************************

// Функция help

//********************************************************

void help( void ) {

      printf(" Неправильно задан параметр программы \n"

                    "FOSSILEX n, где n - номер порта от 0 до 3\n");

      exit(0);

}

//********************************************************

// Функция origin

//********************************************************

void  origin(void) {

      // Переключаем эмулятор MNP в режим вызова удаленного модема

      _asm {

             mov   ah,0E0h

             mov   al, 2

             mov   bl,0

             mov   bh,1

             mov   dx,com_port_num

             int   14h

      }

      putch(7);

}

//********************************************************

// Функция answer

//********************************************************

void  answer(void){

      // Переключаем эмулятор MNP в режим ответа на

      // вызов удаленного модема

      _asm {

             mov   ah,0E0h

             mov   al,2

             mov   bl,1

             mov   bh,1

             mov   dx,com_port_num

             int   14h

      }

      putch(7);

      putch(7);

}


Контроль качества связи (команда %E)


Команда %En управляет контролем качества связи. Данная команда имеет особенности на различных моделях модемов. Для получения более подробной информации обратитесь к документации на ваш модем.

%E0     команда запрещает контроль качества связи.

%E1     команда разрешает выполнение контроля качества связи и соответствующую перенастройку модема.



Коррекция ошибок и сжатие информации


Практически все современные модемы обеспечивают при передаче информации по телефонным линиям автоматическую коррекцию ошибок и компрессию данных. Это позволяет резко повысить качество связи и скорость передачи информации.



Коррекция ошибок и сжатием информации


Модемы c аппаратной коррекцией ошибок обеспечивают следующие режимы передачи данных:

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

         Режим прямой передачи. Данный режим соответствует обычному модему. Передаваемые данные не буферизуются, аппаратная коррекция ошибок не выполняется

         Режим с коррекцией ошибок и буферизацией. Это стандартный режим работы при связи двух модемов, поддерживающих коррекцию ошибок. Если удаленный модем не поддерживает коррекцию ошибок, связь не устанавливается и модем освобождает телефонную линию

         Режим с коррекцией ошибок и автоматической настройкой. Режим используется, когда заранее неизвестно, поддерживает ли удаленный модем протокол MNP, CCITT V.42 и CCITT V.42 bis. В начале сеанса связи после определения режима удаленного модема устанавливается один из трех других режимов.

При использовании модемов с аппаратной поддержкой протоколоа сжатия информации, например, MNP5 или CCITT V.42 bis, следует установить скорость работы последовательного порта вдвое выше скорости модема.



Литература


1.         Microsoft Windows. Users Guide. Microsoft Corporation

2.         Microsoft Windows & MS-DOS 6. Operating Systems Plus Enhanced Tools. Microsoft Corporation

3.         Windows Resource Kit: Complete Technical Information for the Support Professional for the Microsoft Windows Operating System

4.         Crafting C Tools for the IBM PCs. Joe Campbell.

5.         Managing UUCP and Usenet.

6.         А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 4. Программирование модемов. Москва, "Диалог-МИФИ", 1993

7.         А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Тома 11-13. Операционная система Microsoft Windows 3.1 для программиста. Часть 1-3. Москва, "Диалог-МИФИ", 1994

8.         А. В. Фролов, Г. В. Фролов. Персональный компьютер. Шаг за шагом. Том 2. Операционная система Microsoft Windows 3.1. Москва, "Диалог-МИФИ", 1994

9.         А. В. Фролов, Г. В. Фролов. Библиотека системного программиста. Том 10. Компьютер IBM PC/AT, MS-DOS и Windows. Вопросы и ответы. Москва, "Диалог-МИФИ", 1994



Маскирование прерываний


Часто при выполнении критических участков программ для того, чтобы гарантировать выполнение определенной последовательности команд целиком, приходится запрещать прерывания. Это можно сделать командой CLI. Ее нужно поместить в начало критической последовательности команд, а в конце расположить команду STI, разрешающую процессору воспринимать прерывания. Команда CLI запрещает только маскируемые прерывания, немаскируемые всегда обрабатываются процессором.

Если вы используете запрет прерываний с помощью команды CLI, следите за тем, чтобы прерывания не отключались на длительный период времени, так как это может привести к нежелательным последствиям. Например, будут отставать часы.

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



Механизм прерываний


Для обработки событий, происходящих асинхронно по отношению к выполнению программы, лучше всего подходит механизм прерываний. Прерывание можно рассматривать как некоторое особое событие в системе, требующее моментальной реакции.

Аппаратные прерывания вызываются физическими устройствами и приходят асинхронно. Эти прерывания информируют систему о событиях, связанных с работой устройств, например, о том, что наконец-то завершилась печать символа на принтере и неплохо было бы выдать следующий символ, или о том, что получен очередной символ из последовательного порта и его надо записать в буфер.

Использование прерываний при работе с медленными внешними устройствами позволяет совместить ввод/вывод с обработкой данных в центральном процессоре и в результате повышает общую производительность системы.

Иногда желательно сделать систему нечувствительной ко всем или отдельным прерываниям. Для этого используют так называемое маскирование прерываний, о котором мы еще будем подробно говорить.

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



Меню "Edit"


Меню "Edit" изображено на рис. 4.3.

Рис. 4.3. Меню "Edit"

Строки этого меню позволяют вам выполнять различные операции над фрагментами текста, такие как выделение, копирование и вставка, а также некоторые другие, специфические для программы Terminal, действия.

Строки "Copy" и "Paste" меню "Edit" имеют одинаковое на­значение во всех программах Microsoft Windows. Они предназначены для работы с Clipboard - универсальным буфером обмена данными между прог­раммами Windows.

Для того чтобы скопировать фрагмент текста в Clipboard, необходи­мо его выделить и затем выбрать строку "Copy" из меню "Edit".

Для того чтобы вставить содержимое Clipboard в окно, следует вначале установить в нужное место документа текстовый курсор. Это можно сделать либо при помощи мыши, щелкнув в нужном месте ле­вой кнопкой, либо при помощи клавиш перемещения курсора, расположенных на клавиатуре. После этого надо выбрать строку "Paste" из меню "Edit". Содержимое Clipboard будет отображено на экране и передано удаленному модему.

Строка "Send" позволяет скопировать выделенный текст в Clipboard и одновременно передать его модему. Такая возможность полезна для передачи модему повторяющихся текстовых последовательностей.

Строка "Select All" меню "Edit" предназначена для выделения сразу всего текста в один большой фрагмент. Вы можете затем скопировать весь текст в Clipboard.

Последняя строка в меню "Edit" - "Clear Buffer". Она предназначена для очистки экрана и внутреннего буфера приложения Terminal.



Меню "File"


Для того чтобы сохранить конфигурацию приложения Terminal, определенную в диалоговых панелях меню "Settings", вам понадобится меню "File". Меню "File" изображено на рис. 4.2.

Рис. 4.2. Меню "File"

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

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

Строка "Save" предназначена для сохранения текущих изменений в файле конфигурации. Если вы только что создали но­вый файл конфигурации и пытаетесь сохранить его командой "Save", вместо этой команды будет выполнена команда "Save As...", которая тоже со­храняет файл конфигурации, но позволяет выбрать для него имя файла, диск и каталог.

Строка "Save As...", позволяет вам со­хранить файл конфигурации, указав его имя и путь к файлу. С помощью этой строки вы также можете создать копию файла конфигурации, хранящуюся в дру­гом каталоге или под другим именем.

Если вы желаете выводить всю информацию, поступающую от модема, на печать и выбрали в меню "Settings" строку "Printer Echo", вам следует указать, какой фор­мат бумаги и какой принтер вы собираетесь использовать. Для этого предназначена строка "Print Setup...".

Завершить работу программы Terminal можно при помощи строки "Exit".



Меню "Phone"


Меню "Phone" предназначено для вызова удаленного модема и разрыва связи после окончания обмена данными.

Рис. 4.13. Меню "Phone"

Меню "Phone", изображенное на рис. 4.13, состоит из двух строк "Dial" и "Hangup". При выборе из меню "Phone" строки "Dial" приложение Terminal начинает набирать телефонный номер, определенный в диалоговой панели "Phone Number" (см. строку "Phone Number..." из меню "Settings"). Набрав номер удаленного модема, Terminal устанавливает с ним связь. Чтобы прекратить сеанс связи и повесить телефонную трубку, достаточно выбрать строку "Hangup" из меню "Phone".



Меню "Settings"


Меню "Settings" приложения Terminal изображено на рис. 4.4.

Рис. 4.4. Меню "Settings"

Меню "Settings" предназначено для настройки различных параметров приложения Terminal - телефонного номера, режима работы терминала, выбора протоколов для обмена текстовыми и двоичными файлами, параметров порта асинхронного адаптера к которому подключен модем, а также ввода AT-команд управления модемом.

В первую очередь вам необходимо определить к какому порту асинхронного адаптера подключен модем. Для этого выберите из меню "Settings" строку "Communications...". На экране появится диалоговая панель "Communications" (см. рис. 4.5).

Рис. 4.5. Диалоговая панель "Communications"

Выберите из списка "Connector" имя COM-порта, к которому подключен модем.

Если у вас внутренний модем, то COM-порт, используемый им, определяется при помощи перемычек, расположенных на самой плате. Чтобы узнать, какой COM-порт использует модем, проще всего взять в руки документацию модема и проверить по ней положение переключателей.

Для внешнего модема, подключаемого к разъему асинхронного адаптера с помощью кабеля, узнайте номер соответствующего COM-порта из документации компьютера.

Установите, с какой скоростью будет происходить передача данных через выбранный COM-порт. Выбор скорости производится при помощи переключателя с зависимой фиксацией "Baud Rate". Выберите скорость, соответствующую максимально возможной скорости, с которой модем может передавать данные.

Так, если у вас простой модем, поддерживающий скорость обмена 2400 бит/с и соответствующий рекомендации CCITT V.22 bis, можно установить переключатель в положение 2400.

Если ваш модем обладает возможностью аппаратного сжатия передаваемой информации, следует выбрать более высокую скорость, чем может обеспечить модем. Например, если у вас модем соответствующий рекомендации V.32 (максимальная скорость передачи по линии 9600 бит/с) и он выполняет аппаратную компрессию данных в соответствии с протоколами V.42 bis или MNP5, установите переключатель "Baud Rate" в положение "19200".


В том случае, если у вас высокоскоростной модем со скоростью передачи информации по линии 9600 бит/с и выше или вы выбрали переключателем "Baud Rate" более высокую скорость, чем обеспечивает модем, тогда, чтобы избежать возможной потери данных, вам необходимо включить протокол управления потоком.

Протокол управления потоком согласует производительность компьютера и модема, позволяя избежать ситуации, в которой модем не справляется с поступающим от компьютера потоком данных.

Существуют две различных модификации протокола управления потоком - аппаратная и программная. В аппаратной реализации  протокола управления потоком модем и компьютер сообщают о переполнении своих буферов сигналами COM-порта (RTS и CTS). Программный метод использует для управления потоком данных символы XON и XOFF.

Чтобы выбрать метод управления потоком данных, установите переключатель "Flow Control". Положение "Xon/Xoff" устанавливает программный метод управления потоком. Положение "Hardware" - аппаратный метод управления потоком, а в положении "None" управления потоком не производится.

Если вы выбрали протокол управления потоком, то вам надо соответствующим образом настроить модем выбрав из меню "Settings" строку "Modem Commands...".

Теперь установите формат данных, передаваемых через COM-порт. Переключателем "Data Bits" выберите количество бит в передаваемых символах. В большинстве случаев необходимо установить этот переключатель в положение 8 (8 бит на символ). Переключателем "Stop Bits" задайте количество стоповых бит на передаваемый символ. Мы будем использовать один стоповый бит.

Затем переключателем "Parity" надо определить режим контроля четности. Если используется режим контроля четности, то вместе с каждым символом передается бит четности. В зависимости от положения переключателя "Parity" этот бит используется по-разному.

В следующей таблице описаны отдельные позиции этого переключателя.



Положение переключателя "Parity"

Режим контроля четности

None

Контроль четности не выполняется

Odd

Выполняется контроль четности. Бит четности устанавливается таким образом, чтобы в передаваемых символах было установлено нечетное число бит

Even

Выполняется контроль четности. Бит четности устанавливается таким образом, чтобы в передаваемых символах было установлено четное число бит

Mark

Бит четности устанавливается равным единице

Space

Бит четности не устанавливается

Чтобы включить режим контроля четности, недостаточно установить переключатель "Parity", надо также включить переключатель Parity Check.

Последний орган управления на диалоговой панели "Communications" называется "Carrier Detect". Если вам требуется, чтобы приложение Terminal реагировало на внезапный разрыв соединения с удаленным модемом, включите этот переключатель.

Когда вы закончили заполнение диалоговой панели "Communications", нажмите на кнопку "OK". Теперь Terminal подключен к COM-порту и модем готов к приему AT-команд. Для проверки модема можно передать модему команду ATZ. Для этого достаточно набрать в главном окне приложения строку "ATZ" и нажать клавишу <Enter>. Команда будет передана модему. Если модем подключен правильно и работает, он воспримет команду и передаст компьютеру результат OK. В главном окне, ниже команды "ATZ", появится строка "OK".

Вы даже можете передать модему команду набора номера. Для этого наберите строку "ATDP 999-99-99" и нажмите клавишу <Enter>. Модем наберет номер 999-99-99. Если по этому номеру подключен другой модем, они установят связь и на экране появится сообщение модема об установлении соединения с удаленным модемом - CONNECT.

Передав компьютеру сообщение CONNECT, модем переходит в режим передачи данных удаленному модему. Теперь все, что вы набираете на клавиатуре, передается удаленному модему, а от него - удаленному компьютеру. Одновременно с вашим модемом после установления соединения удаленный модем также переключается в режим передачи данных и все, что удаленный компьютер передает своему модему, будет отображаться на экране нашего компьютера.



Запустите на двух компьютерах, снабженных модемами, приложение Terminal. Одному модему передайте команду ATS0=1. Эта команда означает, что когда позвонит телефон, модем сразу снимет трубку и попытается установить связь с удаленным модемом. На другом компьютере передайте модему команду набора номера первого модема (ATDP 999-99-99).

Когда модемы установят связь и на экране компьютеров появятся строка CONNECT, вы сможете обменяться сообщениями, набрав их на клавиатуре и прочитав ответ от удаленного компьютера в окне Terminal.

Набор номера методом непосредственного ввода команды ATD неудобен. Если номер занят, то вам придется снова набирать его. Приложение Terminal позволяет автоматизировать эту процедуру.

Сначала вам надо определить команды для инициализации модема, набора номера и разрыва связи. Выберите из меню "Settings" строку "Modem Commands...". На экране появится диалоговая панель "Modem Commands" (см. рис. 4.6).

 

Рис. 4.6. Диалоговая панель "Modem Commands"

В правой нижней части диалоговой панели "Modem Commands" находится переключатель "Modem Defaults". Переведите данный переключатель в положение, соответствующее типу вашего модема. Как правило, для большинства модемов вы можете выбрать положение "Hayes".

В групповом окне "Commands" находятся пять строк, содержащих команды для модема, используемые при наборе номера - Dial, разрыве связи - Hangup, передачи двоичных данных - Binary TX, приеме  двоичных данных - Binary RX, инициализации модема - Originate. Все команды, кроме команды инициализации модема, могут состоять из двух частей - префикса и суффикса.

Вам необходимо изменить префикс команды набора номера, заменив команду ATDT на ATDP. Команда ATDT выбирает тональную систему набора номера. Отечественные АТС используют не тональный, а импульсный метод набора номера. Для выбора импульсной системы предназначена команда ATDP.

Команду для разрыва связи можно оставить без изменения. Эта команда работает следующим образом. Когда из меню "Phone" вы выбираете строку "Hangup", приложение Terminal, выдержав интервал задержки, передает модему Escape-последовательность из трех символов '+'. Модем, получив Escape-последовательность, переходит из режима передачи данных в командный режим. Затем Terminal передает модему команду разорвать связь и положить трубку - ATH.



Следующие две строки Binary TX и Binary RX не содержат команд. Оставьте их без изменения.

Последняя строка Originate содержит команду инициализации модема. По умолчанию выбрана команда инициализации ATQ0V1E1S0=0. Она инструктирует модем возвращать ответ на все передаваемые модему команды (Q0) в текстовом виде на английском языке (V1). Модем должен возвращать все символы, ему компьютером обратно (E1). Модем не должен сам снимать трубку (S0=0).

Следующая по важности строка меню "Settings" называется "Phone Number...". При ее выборе на экране появляется диалоговая панель "Phone Number" (см. рис. 4.7).



Рис. 4.7. Диалоговая панель "Phone Number"

В поле "Dial" введите телефонный номер удаленного модема, с которым надо соединиться. На рисунке 4.7 введен номер 999-99-99. Чтобы набрать этот номер, достаточно выбрать из меню "Phone" строку "Dial".

В поле "Timeout If Not Connected In" задается интервал времени (в секундах), в течение которого модем должен успеть набрать номер и установить связь с удаленным модемом. Если за указанное время связь не будет установлена, модем прервет процесс соединения. Так как набор номера довольно длительная процедура, то можно увеличить этот интервал до 50-60 секунд.

Приложение Terminal предоставляет пользователю возможность автоматического дозвона до удаленного абонента. В этом режиме Terminal будет повторно набирать номер до тех пор, пока не установиться соединение. Чтобы установить этот режим, достаточно включить переключатель "Redial After Timing Out". Если переключатель "Redial After Timing Out" не включен, тогда номер будет набран только один раз.

Последний орган управления в диалоговой панели "Phone Number" - переключатель "Signal When Connected". Если он установлен, то после удачного установления связи, когда модем возвращает ответ CONNECT и переходит в режим передачи данных, компьютер подает звуковой сигнал.



Самая полезная возможность, предоставляемая приложением Terminal, заключается в передаче двоичных файлов по телефонной линии. Как правило, передача файлов происходит в соответствии со специальными протоколами передачи файлов. Эти протоколы позволяют гарантировать целостность передаваемых данных при максимальной скорости передачи.

Более подробно о протоколах передачи файлов вы узнаете позже. Сейчас мы отметим, что для правильной передачи файла оба компьютера должны использовать одинаковые протоколы. Приложение Terminal поддерживает два протокола XModem CRC и Kermit. Эти протоколы не самые эффективные, но зато поддерживаются практически всеми телекоммуникационными программами.

Чтобы выбрать протокол, который будет использоваться при передаче и приеме файлов выберите из меню "Settings" строку "Binary Transfers...". На экране появится диалоговая панель "Binary Transfers" (см. рис. 4.8).



Рис. 4.8. Диалоговая панель "Binary Transfers"

Она содержит только один переключатель с двумя положениями XModem/CRC и Kermit. Выберите любой протокол и нажмите кнопку "OK".

Terminal обладает возможностью передавать текстовые файлы с помощью отдельного протокола. Но так как при этом пропадут русские символы и вы не сможете передать файлы архивов, мы оставим эту возможность без рассмотрения.

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

Чтобы установить тип терминала, эмулируемого приложением Terminal, выберите из меню "Settings" строку "Terminal Emulation...". На экране появится диалоговая панель "Terminal Emulation" (см. рис. 4.9).



Рис. 4.9. Диалоговая панель "Terminal Emulation"

Выбрав тип терминала, вы можете провести более тонкую настройку. Выберите из меню "Settings" строку "Terminal Preferences...". На экране появится диалоговая панель "Terminal Preferences" (см. рис. 4.10).





Рис. 4.10. Диалоговая панель "Terminal Preferences"

Первая группа органов управления, расположенная в диалоговой панели "Terminal Preferences", называется "Terminal Mode".

Переключатель "Line Wrap" устанавливает режим свертки длинных строк. Если свертка включена, при достижении текстовым курсором правой границы окна редактирования курсор автоматически переходит на следующую строку. Если свертка выключена, при достижении правой границы окна весь текст сдвигается влево для того, чтобы вы могли продолжить ввод.

Переключатель "Local Echo" вызывает вывод на экран всех набираемых на клавиатуре символов. Так как в строке инициализации модема выбрано возвращение всех передаваемых ему символов обратно в компьютер, то, если установить этот переключатель, каждый символ, набранный на клавиатуре, будет дублироваться на экране два раза. Переключатель "Sound" разрешает приложению выдавать звуковые сигналы.

Группа CR -> CR/LF определяет, как реагирует приложение на нажатие клавиши <Enter> и поступление от модема символа CR (возврата каретки). Если переключатель "Inbound" включен, то при приходе от модема символа CR курсор не только перемещается в начало строки, но также переходит на следующую строку, как при приходе символа LF (перевода строки). Если установлен переключатель "Outbound", то при нажатии на клавишу <Enter>, приложение Terminal передает модему два символа CR и LF.

Группа "Columns" содержит один переключатель с зависимой фиксацией, позволяющий выбрать ширину окна - 80 или 132 символов.

Группа "Cursor" предназначена для управления курсором. Вы можете выбрать курсор в виде прямоугольника (Block) или подчеркивания (Underline). Если вы желаете, чтобы курсор мигал, установите переключатель "Blink".

В группе "Terminal Font" можно выбрать название и размер шрифта, а группа "Translations" позволяет учесть различия в кодировке символов для операционных систем Windows и MS-DOS.



Переключатель "Show Scroll Bars" добавляет к оформлению главного окна приложения горизонтальную и вертикальную полосы просмотра.

Все символы, отображаемые на экране, одновременно записываются во внутренний буфер приложения. Размер этого буфера в строках текста задается в поле "Buffers Lines".

Переключатель "Use Function, Arrow, and Ctrl Keys for Windows" определяет, что функциональные клавиши, клавиши управления курсором и комбинации различных клавиш с клавишей <Ctrl> передаются Windows и не передаются модему.

Вы можете параллельно с выводом на экран печатать всю информацию, поступающую от модема, на принтере. Для этого достаточно выбрать в меню "Settings" строку "Printer Echo".

Приложение Terminal позволяет назначить для функциональных клавиш клавиатуры выполнение различных действий, например, ввод пароля, адреса или стандартного приветствия.

Для определения функциональных клавиш выберите из меню "Settings" строку "Function Keys...". На экране появится диалоговая панель "Function Keys". Она содержит восемь строк для функциональных клавиш <F1> - <F8>. Каждая строка состоит из двух полей "Key Name" и "Command". В поле "Key Name" можно ввести название команды, а в поле "Command" команду, выполняемую при нажатии соответствующей функциональной клавиши.

Команда может состоять из текста, непосредственно передаваемого приложению и специальных управляющих кодов. В следующей таблице перечислены управляющие коды, которые можно использовать в поле "Key Name".

Управляющий код

Действие

^A-^Z

Передать удаленному компьютеру управляющий символ Ctrl-A - Ctrl-Z

^$Dnn

Приложение Terminal выполняет задержку nn секунд

^$B

Приложение Terminal передает сигнал BREAK в течение 117 миллисекунд

^$C

Набирает телефонный номер, как если бы вы выбрали строку Dial из меню Phone

^$H

Разрывает связь с удаленным модемом, как если бы вы выбрали строку Hangup из меню Phone

^$L1-^$L4 

Выбрать другой набор функциональных клавиш

^^

Передать символ ^ удаленному компьютеру

^@

Передать удаленному компьютеру символ с кодом 0

^[n

Передать удаленному компьютеру одну или несколько Escape-последовательностей. Переменная n представляет одну или несколько Escape-последовательностей

<


Для удобства использования функциональных клавиш можно включить переключатель "Keys Visible". После этого в нижней части главного окна приложения Terminal появится ряд кнопок, по одной для каждой функциональной клавиши. Названия кнопок соответствует полю "Key Name" диалоговой панели "Function Keys" (см. рис. 4.11).



Рис. 4.11. Диалоговая панель "Function Keys"

Если для вас не достаточно восьми функциональных клавиш, то Terminal позволяет создать четыре различных набора функциональных клавиш и переключаться между ними по мере необходимости. Чтобы определить в диалоговой панели "Function Keys" несколько наборов клавиш, предназначен переключатель с зависимой фиксацией "Key Level".

После того как вы определили первый набор функциональных клавиш, переведите переключатель "Function Keys" в следующее положение и снова заполните поля "Key Name" и "Command".



Рис. 4.12. Приложение "Terminal - BOOK.TRM"

На рисунке 4.12 представлен внешний вид приложения Terminal, для которого в соответствии с рисунком 4.11 определен набор функциональных клавиш.

Чтобы выполнить действие, соответствующее функциональной клавише, можно либо нажать ее на клавиатуре, либо нажать кнопку в нижней части главного окна Terminal. Если вы определили несколько наборов функциональных клавиш, то переключаться между ними можно, нажимая на кнопку "Level", расположенную в правой  части верхнего ряда кнопок приложения.

Если в диалоговой панели "Function Keys" вы установили переключатель "Keys Visible", то вместе с набором кнопок, соответствующих функциональным клавишам появится кнопка с часами.

Вместо названия на этой кнопке отображается текущее время или значение таймера. Чтобы переключиться с отображения текущего времени на таймер и обратно, достаточно нажать на эту кнопку. Сбросить таймер можно, выбрав из меню "Settings" строку "Timer Mode". Таймер удобно использовать, чтобы следить за временем соединения.


Меню "Transfers"


Команды из меню "Transfers" позволяют организовать обмен текстовыми и двоичными файлами с удаленным компьютером. Прием и передача двоичных файлов будет происходить в соответствии с протоколом, выбранным в диалоговой панели "Binary Transfers". Чтобы открыть эту диалоговую панель выберите из меню "Settings" строку "Binary Transfers...".

Меню "Transfers" приложения Terminal изображено на рис. 4.14.

Рис. 4.14. Меню "Transfers"

Допустим, вы соединились с удаленным компьютером, на котором также работает приложение Terminal. Чтобы передать файл с одного компьютера на другой, выберите на первом компьютере из меню "Transfers" строку "Send Binary File...", а на втором строку "Receive Binary File...".

После того как вы выбрали из меню "Transfers" строку "Send Binary File...", на экране появляется диалоговая панель "Send Binary File". Выберите файл, который необходимо передать удаленному компьютеру, и нажмите кнопку "OK". В нижней части главного окна приложения Terminal появляется сообщение о том, что началась передача файла.

Когда на удаленном компьютере из меню "Transfers" выберут строку "Receive Binary File...", появится новая диалоговая панель "Receive Binary File". В ней необходимо указать каталог и имя файла, в который будет записан принятый файл. После выбора имени файла следует нажать на кнопку "OK". Начинается прием файла. В нижней части окна Terminal появляется сообщение, о том что начался прием файла.



Модемы и факс-модемы


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

В тоже время уже существует телефонная сеть, охватывающая весь земной шар. Однако телефонные линии позволяют передавать только аналоговый сигнал, компьютер же работает только с дискретным цифровым сигналом.

Поэтому были разработаны специальные устройства, предназначенные для преобразования дискретных цифровых сигналов в аналоговую форму, передачи полученного сигнала по телефонной линии и приема аналогового сигнала из телефонной линии с последующим преобразованием его в цифровую форму для передачи компьютеру. Такое устройство получило название модем. На рисунке 2.1 показана общая схема соединения компьютеров при помощи модемов.

Рис 2.1. Передача данных по телефонной линии с помощью модема

Чтобы модемы могли обмениваться друг с другом информацией, надо, чтобы они использовали одинаковые способы преобразования цифровых данных в аналоговые и обратно. Другими словами, модемы должны применять одинаковые способы модуляции и демодуляции сигналов.

Чтобы все модемы, производимые различными фирмами, могли соединяться друг с другом, было решено определить ряд рекомендаций, которым они должны соответствовать.

Для разработки стандартов передачи данных был создан специальный международный консультативный комитет по телеграфии и телефонии (International  Consultative  Committee for Telegraphy and Telephony - CCITT).

В настоящее время этот комитет разработал большое количество различных рекомендаций, определяющих способы модуляции и демодуляции сигналов, алгоритм соединения модемов, протоколы коррекции ошибок, протоколы сжатия передаваемой информации и т. д. Все рекомендации CCITT пронумерованы и практически все, относящиеся к модемам, имеют в своем названии (перед номером) префикс V.

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

Международный консультативный комитет по телеграфии и телефонии разделил такие устройства на несколько групп. В настоящее время практически все факсимильные аппараты относятся к группе 3 (Group 3 Fax machines).

По мере развития вычислительной техники многие фирмы выпустили на рынок платы расширения к персональным компьютерам, позволяющие компьютеру обмениваться факсимильными сообщениями с факсимильными аппаратами группы 3. Такая плата получила название "факс-платы". Выпускались две их разновидности - позволяющие только передавать факсы или передавать и принимать их.

Так как факс-платы основывались на тех же принципах передачи информации, что и обыкновенные модемы, то эти два устройства были объединены вместе и названы факс-модемом.



Модемы и операционная система Windows


Данная глава книги будет посвящена программированию асинхронных последовательных адаптеров и модемов в среде операционной системы Windows. В ней вы найдете подробное описание функций программного интерфейса Windows, сообщений и структур данных, предназначенных для взаимодействия с устройствами (модемами, факс-модемами), подключенными к асинхронному последовательному адаптеру.

В этой главе нами приведены исходные тексты небольших телекоммуникационных программ, предназначенных для работы в среде операционной системы Windows.



Модуляция сигнала


Большинство современных модемов используют четыре основных метода модуляции сигнала, передаваемого по телефонной линии:

         Метод амплитудной модуляции (Amplitude Shift Keying - ASK). Наименее эффективный метод модуляции, в котором информация кодируется за счет изменения амплитуды передаваемого сигнала. Применяется только на очень медленных скоростях - до 100 бит за секунду

         Метод частотной модуляции (Frequency Shift Keying - FSK). Информация кодируется за счет изменения частоты передаваемого сигнала. Применяется на скоростях до 1200 бит за секунду

         Метод фазовой модуляции (Phase Shift Keying - PSK). Информация кодируется за счет изменения фазы передаваемого сигнала. Применяется на скоростях до 2400 и 4800 бит за секунду

         Метод квадратурно-амплитудной модуляции (Quadrature Shift Keying - QSK). Является комбинацией фазовой и амплитудной модуляции. Позволяет передавать данные со скоростью больше, чем 9600 бит за секунду



Начать обмен данными с удаленным модемом


Установив связь с удаленным модемом, оба модема переходят в режим обмена данными. Теперь можно начинать передавать и принимать данные.

Передача и прием данных от удаленного модема осуществляются так же, как передача модему команд и прием от него сообщений.



Настройка программы Telix


После того как вы установили на своем компьютере Telix, его следует настроить. Для этого нажмите комбинацию клавиш <Alt+O>. На экране появится меню "Configure Telix" (см. рис. 4.27).

Рис. 4.27. Меню "Configure Telix"

Выбирая различные строки из этого меню можно настроить различные параметры программы. После внесения всех необходимых изменений, закройте меню, выбрав из него строку "Exit" или просто нажав клавишу <Esc>.

Строка меню

Назначение

Screen and color

Выбор режима отображения информации на экране и изменение цветов

Terminal options

Выбор режима работы COM-порта

General options

Общие параметры

Modem and dialing

Команды управления модемом

Filenames and paths

Пути каталогов

Ascii transfers

Способ передачи ASCII-файлов

Protocol options

Параметры протоколов передачи файлов

Kermit transfers

Параметры протокола Kermit

Comm port setup

Выбор адресов и прерываний для COM-портов

Write setup to disk

Сохранить изменения конфигурации на диске

Exit

Закрыть меню

Наиболее важные параметры, связанные с настройкой COM-порта, можно изменить, выбрав из меню "Configure Telix" строку "Terminal options". При этом на экране появится диалоговая панель "Terminal options', изображенная на рисунке 4.28.

Рис. 4.28. Диалоговая панель "Terminal options'

Сначала необходимо определить COM-порт, к которому подключен модем. Нажмите клавишу <B>. На экране появится список COM-портов от COM1 до COM8. Выберите тот COM-порт, к которому подключен модем.

Затем следует настроить характеристики выбранного порта. Нажмите клавишу <A>. На экране будут последовательно появляться списки, из которых следует выбрать скорость обмена информацией, количество бит данных в передаваемых символах и количество стоповых бит.

Теперь надо выбрать протокол подтверждения связи и протокол управления потоком. Для высокоскоростных модемов, модемов поддерживающих аппаратную коррекцию ошибок или аппаратную компрессию передаваемых данных, отключите программное управление потоком по протоколу XON/XOFF и включите аппаратное управление потоком.


Нажмите клавишу <J>. Отключите программное управление потоком по протоколу XON/XOFF. Для этого в появившемся на экране меню "Use of XON/XOFF software flow control" выберите строку "Off". Нажмите клавишу <K>. Включите аппаратное управление потоком при помощи сигналов CTS и RTS, выбрав из меню "Use of CTS/RTS hardware flow control". Нажмите клавишу <L>. Включите протокол подтверждения связи при помощи сигналов DSR и DTR, выбрав из меню "Use of DSR/DTR hardware flow control". После внесения всех необходимых изменений нажмите клавишу <Enter>.

Закончив установку параметров COM-порта, следует определить команды управления модемом. Для этого из меню "Configure Telix" необходимо выбрать строку "Modem and dialing". На экране появится диалоговая панель "Modem and dialing parameter setup" (см. рис. 4.29).



Рис. 4.29. Диалоговая панель "Modem and dialing parameter setup"

На диалоговой панели "Modem and dialing parameter setup" расположены несколько строк, определяющих команды управляющие модемом и особенности набора номера. В следующей таблице описаны строки этой панели. Последовательно нажимая клавиши <A>, <B> - <N>, вы можете изменить эти команды.

Клавиша вызова

Имя строки

Назначение

<A>

Init string

Команда инициализации модема

<B>

Dialing prefix 1

Первый префикс команды набора номера. Telix может запомнить три различных префикса команды набора номера. Для вызова удаленного абонента вы сможете воспользоваться любым префиксом

<C>

Dialing prefix 2

Второй префикс команды набора номера

<D>

Dialing prefix 3

Третий префикс команды набора номера

<E>

Dialing suffix

Суффикс команды набора номера

<F>

Connect string

Сообщение модема об установлении связи

<G>

No connect strings

Сообщение модема о невозможности установить связь (занято, нет гудка в линии и т. д.)

<H>

Hang-up string

Команда разрыва связи

<I>

Auto answer string

Команда перевода модема в режим автоответа

<J>

Dial cancel string

Команда отмены набора номера

<K>

Dial time

Время, в течение которого модем должен установить связь

<L>

Redial pause

Время, после которого модем повторяет попытку установить связь с удаленным модемом

<M>

Auto baud detect

Автоматический режим определения скорости. Модем выравнивает скорость обмена через COM-порт в соответствии со скоростью на которой модемы установили связь

<N>

Drop DTR to hangup

Для выполнения разрыва связи с удаленным модемом сбросить сигнал DTR


Нуль-модем


Соединить компьютер и модем не составляет труда, так как интерфейс RS-232-C как раз для этого и предназначен. Но если вы пожелаете связать вместе два компьютера при помощи такого же кабеля, который вы использовали для связи модема и компьютера, то у вас возникнут проблемы.

Для соединения двух терминальных устройств - двух компьютеров - как минимум необходимо перекрестное соединение линий TR и RD.

Однако в большинстве случаев этого недостаточно, так как для устройств DTE и DCE функции, выполняемые линиями DSR, DTR, DCD, CTS и RTS, асимметричны.

Устройство DTE подает сигнал DTR и ожидает получения сигналов DSR и DCD. В свою очередь, устройство DCE подает сигналы DSR, DCD и ожидает получения сигнала DTR. Таким образом, если вы соедините вместе два устройства DTE кабелем, который вы использовали для соединения устройств DTE и DCE, то они не смогут договориться друг с другом. Не выполнится процесс подтверждения связи.

Теперь перейдем к сигналам RTS и CTS, управления потоком данных. Иногда для соединения двух устройств DTE эти линии соединяют вместе на каждом конце кабеля. В результате получаем, что другое устройство всегда готово для получения данных. Поэтому, если при большой скорости передачи принимающее устройство не успевает принимать и обрабатывать данные, возможна потеря данных.

Чтобы решить все эти проблемы, для соединения двух устройств типа DTE используется специальный кабель, в обиходе называемый нуль-модемом.

Имея два разъема и кабель, вы легко можете спаять его самостоятельно, руководствуясь схемами, изображенными на рисунке 5.3.

Нуль-модемный кабель, представленный в левой части рисунка 5.3, на схеме 1, содержит значительно меньше проводов, чем нуль-модемный кабель, изображенный справа. За счет того, что на каждом конце кабеля линии RTS, CTS и DSR, DCD, DTR  соединены вместе, процедуры подтверждения связи и управления потоком всегда будут заканчиваться успешно. На больших скоростях это может привести к потере информации, поэтому мы рекомендуем использовать вторую схему.




Рис. 5.3. Нуль-модем

Для полноты картины рассмотрим еще один аспект, связанный с механическим соединением портов RS-232-C. Из-за наличия двух типов разъемов - DB25 и DB9 - часто бывают нужны переходники с одного типа разъемов на другой. Например, вы можете использовать такой переходник для соединения COM-порта компьютера и кабеля нуль-модема, если на компьютере установлен разъем DB25, а кабель оканчивается разъемами DB9.

Схему такого переходника мы приводим на рисунке 5.4.



Рис. 5.4. Переходник для разъемов DB25 и DB9

Заметим, что многие модемы можно настроить таким образом, что они не будут проверять состояние сигналов DTR и RTS. Более подробно эти возможности описаны в разделе "Расширенный набор AT-команд".


Обработать конец прерывания


Передать контроллеру прерываний команду обработки конца прерывания. Для этого в порт с адресом 20h посылается команда конца прерывания:

mov     al,20h

out       20h,al

Теперь можно закончить обработку прерывания, выполнив команду iret.



Обработка аппаратных прерываний и контроллер прерываний


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

Для того чтобы система "не растерялась", решая, какое прерывание обслуживать в первую очередь, существует специальная схема приоритетов. Каждому прерыванию назначается свой уникальный приоритет. Если происходит одновременно несколько прерываний, то система отдает предпочтение самому высокоприоритетному, откладывая на время обработку остальных прерываний.

Система приоритетов реализована на двух микросхемах Intel 8259 (для машин класса XT - на одной такой микросхеме). Каждая микросхема обслуживает до восьми приоритетов. Микросхемы можно объединять (каскадировать) для увеличения количества уровней приоритетов в системе.

Уровни приоритетов обозначаются сокращенно IRQ0 - IRQ15 (для машин класса XT существуют только уровни IRQ0 - IRQ7).

Для машин XT приоритеты линейно зависели от номера уровня прерывания. IRQ0 соответствовало самому высокому приоритету, за ним шли IRQ1, IRQ2, IRQ3 и так далее. Уровень IRQ2 в машинах класса XT был зарезервирован для дальнейшего расширения системы. И начиная с машин класса AT IRQ2 стал использоваться для каскадирования контроллеров прерывания 8259. Добавленные приоритетные уровни IRQ8 - IRQ15 в этих машинах располагаются по приоритету между IRQ1 и IRQ3.

Приведем таблицу аппаратных прерываний, расположенных в порядке приоритета:

Номер

Описание

08h

IRQ0 - прерывание интервального таймера, возникает 18,2 раза в секунду

09h

IRQ1 - прерывание от клавиатуры. Генерируется при нажатии и при отжатии клавиши. Используется для чтения данных с клавиатуры

0Ah

IRQ2 - используется для каскадирования аппаратных прерываний в машинах класса AT

70h

IRQ8 - прерывание от часов реального времени

71h

IRQ9 - прерывание от контроллера EGA

72h

IRQ10 - зарезервировано

73h

IRQ11 - зарезервировано

74h

IRQ12 - зарезервировано

75h

IRQ13 - прерывание от математического сопроцессора

76h

IRQ14 - прерывание от контроллера жесткого диска

77h

IRQ15 - зарезервировано

0Bh

IRQ3 - прерывание асинхронного порта COM2

0Ch

IRQ4 - прерывание асинхронного порта COM1

0Dh

IRQ5 - прерывание от контроллера жесткого диска для XT

0Eh

IRQ6 - прерывание генерируется контроллером флоппи-диска после завершения операции

0Fh

IRQ7 - прерывание принтера. Генерируется принтером, когда он готов к выполнению очередной операции

<
Из таблицы видно, что самый высокий приоритет - у прерываний от интервального таймера, затем идет прерывание от клавиатуры.

Для управления схемами приоритетов необходимо знать внутреннее устройство контроллера прерываний 8259. Поступающие прерывания запоминаются в регистре запроса на прерывание IRR. Каждый бит из восьми в этом регистре соответствует прерыванию. После проверки на обработку в настоящий момент другого прерывания запрашивается информация из регистра обслуживания ISR. Перед выдачей запроса на прерывание в процессор проверяется содержимое восьмибитового регистра маски прерываний IMR. Если прерывание данного уровня не замаскировано, то выдается запрос на прерывание.

Программируемый контроллер прерываний 8259 предназначен для обработки до восьми приоритетных уровней прерываний. Возможно каскадирование микросхем, при этом общее число уровней прерываний будет достигать 64.

Контроллер 8259 имеет несколько режимов работы, которые устанавливаются программным путем. В персональных компьютерах XT и AT за первоначальную установку режимов работы микросхем 8259 отвечает BIOS. У программиста, скорее всего, не возникнет потребность перепрограммировать контроллер - это небезопасно, так как неправильное программирование контроллера приведет к нарушению логики работы всей системы.

Однако часто возникает необходимость изменения текущего режима работы (запрет или разрешение прерываний определенного или всех уровней, обработка конца прерывания) или опроса состояния внутренних регистров контроллера. Для этого необходимо ознакомиться со справочными данными на микросхему 8259, где детально описано как первоначальное программирование контроллера, так и управление им во время работы.

Каждому приоритетному уровню прерывания микросхема ставит в соответствие определенный, задаваемый программно, номер прерывания.

Если контроллеры 8259 каскадированы, то ведомой микросхеме присваивается код (выдачей в микросхему соответствующего командного слова). Этот код равен номеру входа IRQ_ведущей микросхемы, с которым соединен выход запроса прерывания INT ведомой микросхемы. Внутри микросхемы приоритет зависит от номера IRQ и задается программно. Для компьютеров XT и AT самым высоким приоритетом внутри группы, обслуживаемой каждым контроллером, является вход IRQ0. Однако возможно программное изменение приоритетов в рамках так называемого приоритетного кольца. При этом дно приоритетного кольца имеет самый низкий приоритет.



Приведем возможные варианты задания приоритетов:

Вход

Уровни приоритета

IRQ0

7 6 5 4 3 2 1 0

IRQ1

0 7 6 5 4 3 2 1

IRQ2

1 0 7 6 5 4 3 2

IRQ3

2 1 0 7 6 5 4 3

IRQ4

3 2 1 0 7 6 5 4

IRQ5

4 3 2 1 0 7 6 5

IRQ6

5 4 3 2 1 0 7 6

IRQ7

6 5 4 3 2 1 0 7

Наиболее высокий приоритет у входа IRQ с обозначением 0 приоритетного кольца, наиболее низкий - с обозначением 7.

Для обработки прерываний контроллер имеет несколько внутренних регистров. Это регистр запросов прерываний IRR, регистр обслуживания прерываний ISR, регистр маски прерываний IMR. В регистре IRR хранятся запросы на обслуживание прерываний от аппаратуры. После выработки сигнала прерывания центральному процессору соответствующий разряд регистра ISR устанавливается в единичное состояние, что блокирует обслуживание всех запросов с равным или более низким приоритетом. Устранить эту блокировку можно либо сбросом соответствующего бита в ISR, либо командой специального маскирования.

Имеется два типа команд, посылаемых программой в контроллер 8259, - команды инициализации и команды операции. Возможны следующие операции:

         Индивидуальное маскирование запросов прерывания;

         Специальное маскирование обслуженных запросов;

         Установка статуса уровней приоритета (по установке исходного состояния, по обслуженному запросу, по указанию);

         Операции конца прерывания (обычный конец прерывания, специальный конец прерывания, автоматический конец прерывания);

         Чтение регистров IRR, ISR, IMR.

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

Рассмотрим команды операций. Существует три типа команд операций:

1. Маскирование запросов прерывания.

2. Команды обработки конца прерывания.

3. Опрос регистров и специальное маскирование.



Байты команды маскирования запросов прерывания выводятся соответственно в порты 21h и A1h для первого и второго контроллера 8259 компьютера AT. Команды операций второго и третьего типа используют порты с адресами 20h и A0h.

Для маскирования какого-либо уровня прерывания надо записать в регистр маски IMR по адресу 21h или A1h единицу в разряд регистра, соответствующий этому уровню. Например, для маскирования прерываний от НГМД в порт 21h надо заслать двоичное число 01000000.

В листинге 5.8 приведен пример программы LOCKFDD, маскирующей прерывание от флоппи-диска.

Листинг 5.8. Файл LOCKFDD.C

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

void main(void);

void main(void) {

      outp(0x21,0x40);

      printf("\nПрерывания от флоппи-диска запрещены.\n");

      exit(0);

}

Чтобы "оживить" флоппи-диски, запустите программу UNLOCK, которая размаскирует все прерывания (в том числе и от флоппи-диска). Исходный текст этой программы представлен в листинге 5.9.

Листинг 5.9. Файл UNLOCK.C

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

void main(void);

void main(void) {

      outp(0x21,0);

      printf("\nПрерывания от флоппи-диска разрешены.\n");

      exit(0);

}

Заметьте, что мы только что замаскировали прерывание именно от флоппи-диска, все остальные устройства продолжали нормально работать. Если бы мы выдали машинную команду CLI, то отключились бы все аппаратные прерывания. Это привело бы, например, к тому, что клавиатура была бы заблокирована.

Еще одно замечание, касающееся обработки аппаратных прерываний. Если вы полностью заменяете стандартный обработчик аппаратного прерывания, не забудьте в конце программы выдать команду обработки конца прерывания. Эти действия необходимы для очистки регистра обслуживания прерывания ISR. При этом разрешается обработка прерываний с более низким приоритетом, чем то, которое только что обрабатывалось.

Команды обработки конца прерывания приведем в виде таблицы:

Биты байта команды

D7 D6 D5 D4 D3 D2 D1 D0


Описание

0  0  1  0  0  0  0  0

Обычный конец прерывания

0  1  1  0  0  B2 B1 B0

Специальный конец прерывания, B0...B2 - двоично-десятичный код сбрасываемого разряда в регистре обслуживания прерывания ISR

1  0  1  0  0  X  X  X

Циклический сдвиг уровней приоритета с обычным концом прерывания. Дно приоритетного кольца устанавливается по обслуженному запросу

1  1  1  0  0  B2 B1 B0

Циклический сдвиг уровней приоритета со специальным концом прерывания, B0...B2 - двоично-десятичный код дна приоритетного кольца

1  0  0  0  0  X  X  X

Разрешение вращения уровней приоритета

0  0  0  0  0  X  X  X

Сброс разрешения вращения уровней приоритета

1  1  0  0  0  B2 B1 B0

Циклический сдвиг уровней приоритета без завершения прерывания, B0...B2 - двоично-десятичный код дна приоритетного кольца

<


Команды третьего типа выдаются также в порты с адресами 20h и A0h. Они имеют следующий формат:

Биты байта команды

D7 D6 D5 D4 D3 D2 D1 D0


Описание

0  0  0  0  1  1  X  X

Установка режима опроса

0  0  0  0  1  0  1  1

Разрешение чтения регистра ISR

0  0  0  0  1  0  1  0

Разрешение чтения регистра IRR

0  1  1  0  1  0  0  0

Разрешение триггера специального маскирования

0  1  0  0  1  0  0  0

Сброс триггера специального маскирования

По команде обычного конца прерывания устанавливается в нулевое состояние разряд ISR, соответствующий последнему обслуженному запросу.

Команда специального конца прерывания устанавливает в нулевое состояние тот разряд ISR, номер которого указан в разрядах B0...B2 команды.

Команда циклического сдвига уровней приоритета с обычным концом прерывания устанавливает в ноль разряд ISR, соответствующий последнему обслуженному запросу, и этому же номеру запроса присваивается низший уровень приоритета.

Аналогично работает команда циклического сдвига уровней приоритета со специальным концом прерывания, только низший уровень приоритета присваивается тому входу IRQ, номер которого указан в разрядах B0...B2 команды.

Команда циклического сдвига уровней приоритета устанавливает статус уровней приоритета без выполнения операции конца прерывания. Разряды B0...B2 указывают дно приоритетного кольца.

После выполнения команд разрешения чтения регистров ISR или IRR при выполнении команды ввода из порта 20h и A0h считывается соответственно содержимое регистров ISR и IRR. Для получения содержимого регистра IMR необходимо выполнить чтение портов с адресами соответственно 21h и A1h.

Команда разрешения триггера специального маскирования блокирует действие тех разрядов ISR, которые замаскированы командой типа 1 (маскирования индивидуальных приоритетных уровней запроса прерывания). Специальное маскирование используется для обслуживания такого запроса, который блокируется старшим или равным по уровню приоритета обслуженным запросом, хранящимся в ISR, не сбрасывая последний.

Чтение регистров ISR и IRR может использоваться резидентными программами при проверке возможности своей активизации - можно проверить, не выполняется ли в настоящий момент обработка какого-нибудь прерывания, которая может конфликтовать с действиями резидентной программы.


Обработка прерываний асинхронного адаптера


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

         Изменилось состояние линии приемника: произошло переполнение приемника, произошла ошибка четности или синхронизации, линия перешла в состояние BREAK

         Данные приняты и доступны для чтения через регистр данных. Обработчик прерывания должен прочитать их и сохранить в буфере для дальнейшей обработки

         Регистр передатчика пуст. Обработчик прерывания может записать в COM-порт следующий байт

         Изменилось состояние модема: изменилось состояние линий CTS, RI, DCD, DSR. Состояние этих линий позволяет программе определить, установлена ли связь с удаленным модемом, есть ли звонок на телефонной линии и т. д.

Вы можете отдельно запрещать или разрешать эти прерывания. Для этого необходимо установить соответствующие биты в регистре управления прерываниями.

Как мы указывали ранее, каждому COM-порту соответствует, кроме базового адреса его регистров, линия IRQ (см. главы "Последовательный асинхронный адаптер" и "COM-порт и номера IRQ"):

COM-порт

Линия IRQ

Прерывание

COM1

IRQ4

INT 0Ch

COM2

IRQ3

INT 0Bh

COM3

IRQ4

INT 0Ch

COM4

IRQ3

INT 0Bh

Заметим, что в данной таблице представлен только один возможный вариант соответствия номеру COM-порта линии IRQ. Некоторые платы асинхронных адаптеров и некоторые внутренние модемы имеют перемычки для выбора номера COM-порта (адреса базового регистра) и номера линии IRQ.

Что представляет из себя обработчик прерываний асинхронного адаптера? На рисунке 6.1 мы привели блок схему такого обработчика прерываний.

Рис. 6.1. Блок схема обработчика прерываний

Теперь опишем алгоритм обработки прерываний от асинхронного последовательного адаптера. Этот алгоритм реализован в программе CHATINT, представленной ниже.



Обработка прерываний COM-порта


Так как процесс последовательной передачи данных протекает достаточно медленно, имеет смысл выполнять его в фоновом режиме, используя прерывания по окончании передачи или приема символа. Напомним, что, как правило, портам COM1 и COM3 соответствует аппаратное прерывание INT0Ch, а COM2 и COM4 - INT 0Bh.

Для разрешения прерываний необходимо установить биты регистра управления прерываниями асинхронного адаптера, соответствующие тем прерываниям, которые мы желаем обрабатывать.

Когда произошло прерывание, программа-обработчик прерывания должна проанализировать причину прерывания, прочитав содержимое регистра идентификации прерывания с адресом base_adr + 2.

Может случиться так, что одновременно произойдет несколько прерываний. В этом случае бит 0 регистра идентификации прерывания будет установлен в 1. Если такая ситуация имеет место, перед завершением обработки прерывания вам надо снова прочитать регистр идентификации прерывания и обработать следующее прерывание.

Так следует поступать до тех пор, пока бит 0 регистра идентификации прерывания не станет равным нулю.

Если вы решили воспользоваться прерываниями, вырабатываемыми портами асинхронного адаптера, необходимо соответствующим образом запрограммировать контроллер прерываний компьютера.

В предыдущих томах из серии "Библиотека системного программиста" мы рассказывали о контроллере прерываний и о механизме прерываний в персональном компьютере IBM PC/XT/AT. Без умения работать с контроллером прерываний вы не сможете использовать режим прерываний при программировании последовательного асинхронного порта.

Ниже мы приведем полезные сведения о контроллере прерываний, необходимые для написания телекоммуникационных программ, работающих под управлением прерываний.



Оглавление


Аннотация.................................................................................................................................................................................. 2

Предисловие.............................................................................................................................................................................. 2

1.     Зачем нужны модемы и факс-модемы....................................................................................................................... 5

2.     Модемы и факс-модемы................................................................................................................................................ 7

2.1.       Основные понятия................................................................................................................................................. 8

2.1.1.       Боды, биты за секунду и символы в секунду   8

Биты за секунду........................................................................................................... 8

Символы за секунду................................................................................................... 8

Боды................................................................................................................................ 8

2.1.2.       Модуляция сигнала    9

2.1.3.       Дуплексный и полудуплексный режимы   9

2.1.4.       Асинхронная и синхронная передача данных  9

2.2.       Рекомендации CCITT для модемов................................................................................................................. 10

2.2.1.       CCITT V.21 10

2.2.2.       CCITT V.22 10

2.2.3.       CCITT V.22 bis 10

2.2.4.       CCITT V.23 11

2.2.5.       CCITT V.32 11

2.2.6.       CCITT V.32 bis 11

2.2.7.       CCITT V.34 11

2.2.8.       Bell 103, Bell 212A  11

2.3.       Коррекция ошибок и сжатие информации................................................................................................... 11



Определение доступных портов


Драйвер асинхронного последовательного адаптера VCD предоставляет приложениям Windows программный интерфейс через точку входа, адрес которой можно определить, вызвав мультиплексное прерывание INT 2Fh.

Реализация этих функций зависит от конкретного драйвера VCD. Если у вас установлен драйвер, не совместимый с драйвером VCD из DDK, то эти функции могут не работать.

В листинге 7.3. мы приводим исходный текст приложения FINDPORT, которое определяет порты асинхронного последовательного адаптера, доступные приложениям Windows, посредством вызова функции драйвера VCD.

Листинг 7.3. Файл FINDPORT.CPP

#define            STRICT

#include          <windows.h>

#include          <bwcc.h>

// Прототип функции

BYTE FAR FindCOMPorts( void );

// =========================================================

// Функция WinMain

// =========================================================

#pragma argsused

int PASCAL

WinMain( HINSTANCE hInstance,

                  

HINSTANCE hPrevInstance,

                  

LPSTR lpCmdLine,

                  

int nCmdShow )

{

     

char  szMsg[ 60 ] = "";

     

BYTE  bFindPort;

     

// Определяем работает ли Windows в расширенном режиме

     

if(GetWinFlags() & WF_ENHANCED)

     

{

            

bFindPort = FindCOMPorts();

            

for (int i = 0; i < 8; i++)

            

{

                  

if (bFindPort & (BYTE) (1 << (BYTE)i))

                               

wsprintf( szMsg, "%sCOM%d ", (LPSTR) szMsg, i + 1 ) ;

            

}

            

BWCCMessageBox(NULL,

                  

szMsg, "Обнаружены COM-порты:",

                  

MB_OK | MB_ICONINFORMATION);

     

}

     

else

            

BWCCMessageBox(NULL,

                  

"Зпустите Windows в расширенном режиме", "Сообщение",

                  

MB_OK | MB_ICONSTOP);

     

return 0;

}

После запуска приложения, WinMain вызывает функцию GetWinFlags для определения режима работы Windows. Если Windows работает в стандартном режиме, приложение выводит соответствующее сообщение и завершает свою работу.


Если Windows работает в расширенном режиме, выполняется вызов функции FindCOMPorts, определяющей список доступных COM-портов. Затем полученный список доступных портов отображается на экране.

Функция FindCOMPorts возвращает байт, каждый бит которого отвечает за свой COM-порт. Младший бит соответствует порту COM1, а старший COM8. Исходный текст функции FindCOMPorts представлен в листинге 7.4.

Листинг 7.4. Файл COMM_DRV.CPP

#include    <windows.h>

#include    "comm_drv.h"

// Идентификатор драйвера асинхронного последовательного

// адаптера

#define      VCD_Device_ID  0x0E

// ===========================================================

// Функция FindCOMPorts вызывает драйвер асинхронного адаптера

// и определяет какие COM-порты установлены в компьютере и 

// доступны для использования

// ===========================================================

BYTE FAR FindCOMPorts( void )

{

      BYTE     bResult;

      FARPROC  lpCOMM;

      asm {

             // Определяем адрес точки входа программного интерфейса

             // драйвера асинхронного последовательного адаптера

             mov   ax, 1684h

             mov   bx, VCD_Device_ID

             xor   di, di

             mov   es, di

             int   2Fh

             // Проверяем значение регистров ES:DI

             mov   ax, es

             or    ax, di

             // Если в регистрах ES:DI записаны нулевые значения,

             // драйвер не имеет программного интерфейса и не доступен

             jz    FunctionFailed

             // Драйвер доступен, сохраняем адрес его интерфейса в

             // переменной lpCOMM

             mov   word ptr lpCOMM,      di

             mov   word ptr lpCOMM+2, es

             // Вызываем функцию из драйвера COM-порта

             mov   dx, 1

             call  dword ptr lpCOMM

             // Сохраняем результат, полученный в регистре AL

             mov   bResult, al

             // Завершаем выполнение функции

             jmp   FunctionQuit



      }

      FunctionFailed:

      asm {

             // В случае возникновения ошибки возвращаем нулевое

             // значение

             mov   bResult, 0

      }

      FunctionQuit:

      return( bResult ) ;

}

В исходном тексте функции FindCOMPorts нет ни вызова функции OpenComm, ни вызовов других телекоммуникационных функций, она содержит только десяток строк на языке ассемблера. Рассмотрим функцию FindCOMPorts подробней.

Сначала вызывается функция 1684h мультиплексного прерывания INT 2Fh. Для нее в регистре BX передается константа VCD_Device_ID, означающая, что необходимо получить точку входа для драйвера VCD.

mov   ax, 1684h

mov   bx, VCD_Device_ID

xor   di, di

mov   es, di

int   2Fh

Если после вызова мультиплексного прерывания в регистрах ES:DI сохраняются нулевые значения, значит драйвер VCD не поддерживает программный интерфейс и, следовательно, мы не можем получить к нему доступ. В этом случае возвращаем нулевое значение.

Если содержимое регистров ES:DI не равно нулю, значит драйвер VCD доступен. Сохраняем адрес точки входа его интерфейса в переменной lpCOMM:

mov   word ptr lpCOMM,      di

mov   word ptr lpCOMM+2, es

Затем вызываем функцию из драйвера VCD, предварительно записав в регистр DX значение 1.

mov   dx, 1

call  dword ptr lpCOMM

После возвращения из этой функции по содержимому регистра AL можно определить, какие из портов асинхронного последовательного адаптера доступны для использования.

Затем мы завершаем выполнение функции FindCOMPorts и возвращаем значение регистра AL.

Файл определения модуля приложения FINDPORT приведен в листинге 7.5.

Листинг 7.5. Файл FINDPORT.DEF

; =============================================================

; Файл определения модуля

; =============================================================

NAME OPENCOMM

DESCRIPTION 'Приложение FINDPORT, (C) 1994, Frolov G.V.'

EXETYPE windows

STUB 'winstub.exe'

STACKSIZE  5120

HEAPSIZE  1024

CODE preload moveable discardable

DATA preload moveable multiple


Определение номера версии эмулятора MNP


На входе:  AH = 0E0h;

     

AL = 06h;

     

BX = 00h.

На выходе:     BX = 4D58h;

     

AH = старшая часть номера версии эмулятора;

     

AL = младшая часть номера версии.



Определение параметров системного таймера


Данная функция используется для определения параметров системного таймера

На входе:  AH = 07h.

На выходе: AL = номер прерывания от системного таймера;

     

AH = количество прерываний от системного

            

таймера на секунду;

           

DX = интервал между прерываниями от системного

            

таймера, определяется в миллисекундах.



Определение состояния драйвера


Состояние порта асинхронного адаптера можно узнать с помощью функции 03h:

На входе:  AH = 03h;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4 и т. д.

На выходе: AH = состояние буферов драйвера;

            

D0 - принятые драйвером символы доступны

                          

для чтения;

            

D1 - приемный буфер драйвера переполнен,

                     

все символы, полученные после

                     

переполнения буфера, будут потеряны;

            

D5 - в буфере передатчика есть свободное

                     

место;

            

D6 - буфер передатчика пуст;

     

AL = состояние линии DCD;

            

D3 = 1;

            

D7 - состояние сигнала DCD.



Определение текущего положения курсора


Функция используется для определения текущего положения курсора на экране.

На входе:  AH = 12h.

На выходе:     DL = номер столбца;

     

DH = номер строки.

Данная функция аналогична функции 03h прерывания INT_10h.



Определить причину прерывания


Для этого следует считать содержимое регистра идентификации прерывания. Состояние битов D1 D2 определяют причину прерывания:

Биты D2 D1

Причина прерывания

00

Прерывание по линии состояния

01

Буфер передатчика пуст

10

Данные приняты

11

Изменилось состояние модема

В зависимости от того, какое произошло прерывание, его надо соответствующим образом обработать.



Определить состояние эмулятора MNP


На входе:  AH = 0E0h;

     

AL = 00h;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4.

На выходе:     ES:BX - указатель на структуру, содержащую

                  

информацию о текущем состоянии

                  

эмулятора MNP.

При помощи данной подфункции можно определить состояние эмулятора MNP. Подфункция возвращает в регистрах ES:BX указатель на следующую структуру:

Смещение

Размер

Смысл

0

Байт

Если байт содержит 0 - эмуляция MNP включена, 1 - эмуляция MNP отключена

1

Байт

Уровень эмулируемого протокола MNP (2, 4, 5)

2

Байт

Серийный номер MNP удаленного модема

3

Слово

Общее число переданных пакетов

5

Слово

Число повторно переданных пакетов

7

Слово

Максимальная скорость передачи

9

Слово

Общее число принятых пакетов

11

Слово

Число повторно принятых пакетов

13

Слово

Максимальная скорость приема



Определить уровень сигнала на линии (команда %L)


Команда %L позволяет узнать уровень сигнала на телефонной линии. Значение, возвращаемое модемом при передаче ему команды %L, определяет уровень сигнала на линии.



Основные понятия


Приступив к изучению модемов и факс-модемов, вы столкнетесь с большим количеством новых терминов - боды, модуляция сигнала, дуплексный режим и т. д. В этом разделе мы объясним основные термины, относящиеся к передаче информации по телефонным линиям, а затем расскажем о рекомендациях, регламентирующих различные характеристики модемов.



Основные понятия и термины


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

Рис. 5.1. Формат данных, передаваемых через COM-порт

Из рисунка видно, что исходное состояние линии последовательной передачи данных - уровень логической 1. Это состояние линии называют отмеченным - MARK. Когда начинается передача данных, уровень линии переходит в 0. Это состояние линии называют пустым - SPACE. Если линия находится в таком состоянии больше определенного времени, считается, что линия перешла в состояние разрыва связи - BREAK.

Стартовый бит START сигнализирует о начале передачи данных. Далее передаются биты данных, вначале младшие, затем старшие.

Если используется бит четности P, то передается и он. Бит четности имеет такое значение, чтобы в пакете битов общее количество единиц было четно или нечетно, в зависимости от установки регистров порта. Этот бит служит для обнаружения ошибок, которые могут возникнуть при передаче данных из-за помех на линии. Приемное устройство заново вычисляет четность данных и сравнивает результат с принятым битом четности. Если четность не совпала, то считается, что данные переданы с ошибкой. Естественно, такой алгоритм не дает стопроцентной гарантии обнаружения ошибок. Так, если при передаче данных изменилось четное число битов, то четность сохраняется и ошибка не будет обнаружена. Поэтому на практике применяют более сложные методы обнаружения ошибок.

В самом конце передаются один или два стоповых бита STOP, завершающих передачу байта. Затем до прихода следующего стартового бита линия снова переходит в состояние MARK.

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


Другая важная характеристика - скорость передачи данных. Скорость передачи данных обычно измеряется в битах за секунду (bps) или в бодах (по фамилии французского изобретателя телеграфного аппарата Emile Baudot - Э. Бодо). Боды определяют количество передаваемых битов за секунду. При этом учитываются и старт/стопные биты, а также бит четности.

В литературе иногда неправильно отождествляют термины бит за секунду и боды. Эти термины действительно равнозначны, когда говорят о передаче данных через COM-порт, но при передаче данных по телефонной линии через модем с высокой скоростью значения скорости передачи информации в битах за секунду и бодах могут различаться. Более подробно об этом можно прочитать в главе "Модемы и факс-модемы", разделе "Боды, биты за секунду и символы в секунду".

Иногда для определения скорости передачи информации используют другой термин - символы за секунду (cps). Он более реально показывает скорость передачи данных,  так как не учитываются служебные биты, не несущие полезной информации.


Отключение внешней функции обработчика


Функция 7Fh используется для отключения внешней функции, установленной при помощи функции 7Eh.

На входе:  AH = 7Fh;

     

AL = номер, присваиваемый функции;

     

ES:DX - адрес точки входа функции.

На выходе:     AX = 1954h;

     

BL = номер, присвоенный функции;

     

BH = 01h - удаление функции прошло успешно;

     

BH = 00h - произошла ошибка.



Отслеживание сигнала DCD


Если производится отслеживание сигнала DCD и сигнал DCD становится неактивным, то FOSSIL-драйвер производит перезагрузку системы.

На входе:  AH = 14h;

     

DX = номер порта:   0 - COM1, 1 - COM2, 2 - COM3,

                               

3 - COM4 и т. д.;

     

AL = 01h - производится отслеживание сигнала DCD;

     

AL = 00h - отслеживание сигнала DCD не производится.

На выходе:     не используется.



Ответ на вызов удаленного модема (команда A)


A- Команда заставляет модем снять трубку, подключиться к телефонной линии и ответить на вызов удаленного модема.

Данная команда особенно полезна, если режим автоматического ответа выключен (регистр S0 = 0). Она позволяет оператору ответить на телефонный вызов.

Команду можно использовать, если вы сами позвонили абоненту, и после обычного телефонного разговора желаете передать данные, не разрывая связи.



Ожидание ответа от модема


В зависимости от режима, в котором находится модем, он может передавать компьютеру различные сообщения. Например, если модем производит вызов удаленного модема (AT-команда ATD), то он может выдать следующие сообщения:

Сообщение

Смысл

CONNECT

Успешное соединение

BUSY

Номер занят

NO DIALTONE

На линии отсутствует сигнал коммутатора

NO ANSWER

Абонент не отвечает

NO CARRIER

Неудачная попытка установить связь

Когда приходит звонок, модем передает компьютеру сообщение RING, если регистр модема S0 равен нулю. В этом случае для ответа на звонок надо послать модему команду ATA. Если модем находится в режиме автоответа и регистр модема S0 не равен нулю, то модем автоматически пытается ответить на звонок и может выдать следующие сообщения:

Сообщение

Смысл

CONNECT

Успешное соединение

NO DIALTONE

На линии отсутствует несущая частота от удаленного модема

NO CARRIER

Неудачная попытка установить связь.

Если модем передал компьютеру сообщение CONNECT, значит, он успешно выполнил соединение и теперь работает в режиме передачи данных. Теперь все данные, которые вы передадите модему через COM-порт, будут преобразованы модемом в форму, пригодную для передачи по телефонным линиям, и переданы удаленному модему. И наоборот, данные, принятые модемом по телефонной линии, переводятся в цифровую форму и могут быть прочитаны через COM-порт, к которому подключен модем.

Если модем передал компьютеру сообщения BUSY, NO DIALTONE, NO ANSWER, NO CARRIER, значит, не удалось образовать соединение с удаленным модемом и надо попытаться повторить соединение.

Для разных модемов и разных режимов его работы набор сообщений может быть шире, чем мы указали в таблицах. Получить больше информации о сообщениях модема можно в разделе "Система команд hayes-модемов" и документации модема. Особое внимание следует обратить на команды Q, V, X.



Ожидание соединения


Данная подфункция используется для определения и задания времени после установления соединения, в течение которого драйвер пытается установить с удаленным модемом связь с использованием MNP. Время задается в 1/55 долях миллисекунды или, другими словами, количеством прерываний от системного таймера, которые должны произойти за данный промежуток времени.

На входе:  AH = 0E0h;

     

AL = 03h;

     

BH = 00h - определить интервал времени;

        

= 01h - установить интервал времени;

     

BL = интервал времени в 1/55 долях миллисекунды

            

(по умолчанию устанавливается 14);

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4.

На выходе:     BL = интервал времени.



Передача данных


Перед записью байта данных в регистр передатчика необходимо убедиться в том, что регистр хранения передатчика свободен, то есть убедиться в том, что передача предыдущего символа завершена.

Признаком того, что регистр передатчика свободен, является установленный в 1 бит 5 регистра состояния линии с адресом base_adr+ 5. Функция aux_outp (см. листинг 5.6) ждет окончания передачи текущего символа, затем посылает в асинхронный адаптер следующий символ.

Листинг 5.6. Файл AUX_OUTP.C

/**

*.Name         aux_outp

*

*.Descr        Функция дожидается готовности

*              передатчика и посылает символ.

*

*.Proto        void aux_outp(char chr, int port);

*

*.Params       char chr - посылаемый символ;

*

*              int port - номер асинхронного адаптера:

*                 0 - COM1, 1 - COM2

*

*.Return       Ничего

***/

#include <stdio.h>

#include <conio.h>

#include "sysp_com.h"

void aux_outp(char chr, int port) {

     

unsigned status_reg, out_reg;

     

status_reg = 0x3fd - 0x100 * port;

     

out_reg = status_reg - 5;

     

while( (inp(status_reg) & 0x20) == 0 );

     

outp(out_reg, chr);

}


Данная функция используется для ускорения процесса передачи в COM-порт данных из буфера передатчика драйвера. Функция не возвращает управление до тех пор, пока буфер передатчика не станет пустым.

На входе:  AH = 08h;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4 и т. д.

На выходе: не используется.



Передача факсимильного сообщения


Microsoft At Work PC Fax позволяет легко и удобно посылать факсимильные сообщения практически из любого приложения Windows. Допустим вы подготовили в текстовом редакторе Write документ, который необходимо передать удаленному факсимильному аппарату.

Для этого достаточно выбрать в качестве принтера факс-модем. Откройте меню "File" и выберите строку "Print Setup...". На экране появится диалоговая панель "Print Setup". Определите используемый для печати принтер, установив переключатель "Printer" в положение "Specific Printer" и выбрав из списка "Specific Printer" строку "Microsoft At Work PC Fax on Fax".

Теперь отправьте подготовленный вами документ на печать. На экране появится окно приложения Mail (см. рис. 4.22). В поле "To:" введите телефонный номер удаленного факс-модема или факсимильного аппарата в формате [fax:телефонный номер]. Мы ввели номер 123 45 67. В поле "Cc:" можно ввести ваш адрес или номер. В поле "Subject:" можно ввести заголовок или тему передаваемого факсимильного сообщения. Поля "Cc:" и "Subject:" можно оставить незаполненными, необходимо ввести только телефонный номер.

Рис. 4.22. Передача факсимильного сообщения

Если вы постоянно отправляете факсимильные сообщения одним и тем же абонентам, их телефонные номера можно внести в телефонную книгу приложения. Для этого достаточно нажать кнопку "Address". Из-за недостатка места мы не будем описывать телефонную книгу приложения Mail и оставляем ее вам для самостоятельного изучения.

Теперь вы уже можете отправить факс удаленному факс-модему или факсимильному аппарату. Для этого достаточно нажать кнопку "Send". Приложение выполнит инициализацию модема, наберет номер удаленного абонента и попытается установить связь. В случае успешного установления связи Mail передаст факсимильное сообщение и завершится. Если номер занят или возникнут другие проблемы, Mail повторит попытку соединения через некоторое время.


Однако перед тем как передавать факсимильное сообщение, мы советуем вам настроить его характеристики. Для этого нажмите кнопку "Options". На экране появится диалоговая панель "Options" (см. рис. 4.23).



Рис. 4.23. Диалоговая панель "Options"

В диалоговой панели "Options" вы можете задать приоритет приложения, передающего факсимильное сообщение. Для этого переведите переключатель "Priority" в соответствующее положение. Положение High устанавливает наивысший приоритет, Normal - стандартный и Low - низкий приоритеты.

В этой же диалоговой панели расположены переключатели "Save sent message" - сохранить копию переданного факсимильного сообщения и "Return receipt" - вернуть подтверждение о получении вашего сообщения удаленным устройством связи.

Теперь нажмите кнопку "Fax". На экране появится новая диалоговая панель "Fax Message Options" (см. рис. 4.24). В этой панели расположено большое количество разнообразных органов управления.



Рис. 4.24. Диалоговая панель "Fax Message Options"

Переключатель "Message Format" задает формат, в котором факсимильное сообщение передается удаленному абоненту. Если вы передаете факсимильное сообщение обыкновенному факсимильному аппарату, оно может быть передано только в факсимильном формате. Переключатель "Message Format" должен находится в положении "Facsimile Format" или "Email if available".

Если вы устанавливаете связь с факс-модемом, работающим под управлением приложения Microsoft At Work PC Fax, факсимильное сообщение можно передать в электронном формате. В этом случае получатель такого сообщения сможет выполнить его редактирование. Переключатель "Message Format" должен находится в положении "Email Format" или "Email if available".

Органы управления, расположенные в группе "Cover Page", позволяют присоединить к факсимильному сообщению титульный лист, содержащий различную информацию.



Отправляя факсимильное сообщение, вам следует определить его формат. Для этого выберите соответствующую строку из списка "Paper Size". Обычно факсимильные аппараты поддерживают форматы A3, Legal 8 и Letter 8.

Переключатель "Image Quality" позволяет установить качество передаваемого документа. Переключатель можно установить в одну из четырех позиций. Позиция "Standard" выбирает самое низкое качество факсимильного сообщения - 100 точек на дюйм,  "Fine" соответствует среднему качеству - 200 точек на дюйм, "300 dpi" устанавливает высокое качество передаваемого изображения - 300 точек на дюйм. Позиция "Best available" позволяет согласовать качество передаваемого сообщения с удаленным устройством связи и выбрать максимально возможное качество передачи.

Следует заметить, что чем выше качество передаваемого документа, тем больший объем информации необходимо передать и тем больше времени займет процесс передачи.

Органы управления, расположенные в группе "Transmission Time", позволяют установить время передачи факсимильного сообщения. Если переключатель "Transmission Time" находится в положении "ASAP" (As Soon As Possible), факсимильное сообщение будет передано настолько быстро, насколько это возможно. При необходимости можно передать факсимильное сообщение в строго заданное время, например, глубокой ночью. Для этого переведите переключатель "Transmission Time" в положение "At" и укажите рядом время вызова.

Если вы пользуетесь международной связью, вы можете захотеть передать факсимильное сообщение по самому дешевому тарифу. Для этого переведите переключатель "Transmission Time" в положение "Cheap Rates". Нажмите кнопку "Options", расположенную в группе "Transmission Time". На экране появится диалоговая панель "Transmission Options" (см. рис. 4.25).



Рис. 4.25. Диалоговая панель "Transmission Options"

В этой панели можно задать время посылки факсимильного сообщения - "Start Cheap Rates time", количество попыток установления связи - "Number of retries", интервал времени между повторными вызовами удаленного абонента и время окончания попыток передачи сообщения - "End Cheap Rates time". Если в течение промежутка времени, заданного полями "Start Cheap Rates time" и "End Cheap Rates time", факс-модем не сможет установить связь с удаленным компьютером или факсимильным аппаратом, то пересылка факса откладывается на следующий день.


Передача и прием файлов


Запустите на двух компьютерах, снабженных модемами, программу Telix. Одну программу переведите в режим автоответа, а с помощью другой наберите телефонный номер, по которому установлен первый компьютер.

Чтобы передать файл удаленному компьютеру, нажмите комбинацию клавиш <Alt+S>. На экране появится список доступных протоколов передачи файлов (см. рис. 4.32). Выберите протокол, который поддерживает удаленная программа, например, Zmodem.

Рис. 4.32. Диалоговая панель "Upload file"

Откроется диалоговая панель, в которой вы сможете ввести имена файлов, предназначенных для передачи (см. рис. 4.33). Если вы выбрали протокол Zmodem, можно передать за один раз несколько файлов. Перечислите файлы, разделяя их имена пробелами.

Рис. 4.33. Ввод имен файлов

Для начала передачи нажмите клавишу <Enter>. Появится диалоговая панель "Zmodem upload" и начнется передача файла уделенному компьютеру (см. рис. 4.34).

Рис. 4.34. Диалоговая панель "Zmodem upload"

Чтобы программа Telix на удаленном компьютере, начала принимать файл, его оператор должен нажать комбинацию клавиш <Alt+R>. В открывшейся диалоговой панели "Download file", ему необходимо выбрать протокол, в соответствии с которым, будет происходить прием файла (см. рис. 4.32). Название этого протокола  должно совпадать с протоколом, используемым для передачи файла.

Если для обмена файлами выбран протокол Zmodem, Ymodem или Kermit, тогда сразу начинается прием файла (см. рис. 4.35). Если для передачи файла используется протокол Xmodem, то перед началом приема файла надо будет определить его имя, под которым файл будет принят.

Рис. 4.35. Прием файла от удаленного компьютера



Передача сигнала BREAK


Используя данную функцию, можно перевести телефонную линию в состояние BREAK.

На входе:  AH = 1Ah;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4 и т. д.;

     

AX = 01h - начало передачи сигнала BREAK;

     

AX = 00h - конец передачи сигнала BREAK.

На выходе:     не используется.



Передача сигнала прерывания (команда \B)


В режиме без поддержки аппаратной коррекции ошибок, команда \Bn вызывает передачу сигнала прерывания - BREAK. Длительность сигнала прерывания определяется параметром n (n от 1 до 9) в десятых долях секунды. Режим обработки прерывания при получении сигнала BREAK определяется параметром команды \K.



Передача символа без ожидания


Если в буфере передатчика есть свободное место, то функция записывает передаваемый байт в буфер и возвращает в регистре AX значение 01h. Если в буфере передатчика нет свободного места, функция записывает передаваемый байт в буфер и возвращает в регистре AX значение 00h.

На входе:  AH = 0Bh;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4 и т. д.;

     

AL = передаваемый байт.

На выходе:            AX = 0001h - символ размещен в буфере

                                     

передатчика;

     

AX = 0000h - символ не размещен в буфере

                        

передатчика.



Передача символа с ожиданием


Основным достоинством FOSSIL-драйвера является буферизация передаваемых и принимаемых данных. При передаче байта он записывается программой в буфер драйвера, а затем передается драйвером в COM-порт. Для передачи используется следующая функция:

На входе:  AH = 01h;

     

DX = номер порта:         0 - COM1, 1 - COM2, 2 - COM3,

                                                              

3 - COM4 и т. д.;

     

AL = передаваемый байт.

На выходе: AX = состояние порта асинхронного адаптера

            

(см. функцию 03h).

Если в буфере передатчика есть свободное место, то функция записывает передаваемый байт в буфер и возвращает управление не дожидаясь передачи байта в регистры последовательного адаптера. Если в буфере передатчика нет свободного места, функция будет ожидать, пока в буфере передатчика не освободится место для передаваемого байта.



Переключение модема в командный режим


После окончания работы коммуникационная программа должна перевести модем в командный режим и передать ему команду положить трубку (ATH0). Для перевода модема в командный режим можно воспользоваться Escape-последовательностью +++. После того как модем перешел в командный режим, можно опять передавать ему AT-команды.



Перевод модема из командного режима в режим передачи данных (команда O)


Команда On переводит модем из командного режима в режим передачи данных. При этом модем отвечает CONNECT.

Команды О и О0 переводят модем в режим передачи данных. Инициирование последовательности сигналов проверки линии связи не выполняется. Команда может быть использована для того чтобы вернуть модем в режим передачи данных, после того как модему передали Escape-последовательность. Escape-последовательность переводит модем из режима передачи данных в командный режим. Связь с удаленным модемом при этом не разрывается.

Команда О1 переводит модем в режим передачи данных и заставляет его заново согласовать протоколы и стандарты связи с удаленным модемом.



Перезагрузка системы


Производит перезагрузку системы.

На входе:  AH = 17h.



Первая программа


Теперь, когда мы рассмотрели первые две функции, предназначенные для управления портами асинхронного последовательного адаптера, приведем исходный текст приложения OPENCOMM, использующего эти функции.

Приложение OPENCOMM последовательно открывает и закрывает все порты асинхронного адаптера, начиная с COM1 до COM8. При этом оно определяет номера доступных портов и выводит на экран их список. Главный файл приложения OPENCOMM представлен в листинге 7.1.

Листинг 7.1. Файл OPENCOMM.CPP

// ============================================================

// Определение доступных COM-портов

// ============================================================

#define      STRICT

#include    <windows.h>

// Прототип функции

BYTE FAR FindCOMPorts( void );

// ============================================================

// Функция WinMain

// ============================================================

#pragma argsused

int PASCAL

WinMain( HINSTANCE hInstance,

                  

HINSTANCE hPrevInstance,

                  

LPSTR lpCmdLine,

                  

int nCmdShow )

{

     

char  szMsg[ 60 ] = "";

     

BYTE  bFindPort;

     

// Определяем доступные для использования COM-порты

     

bFindPort = FindCOMPorts();

     

// Формируем строку результата с названиями доступных портов

     

for(int nBitNum = 0; nBitNum < 8; nBitNum++)

     

{

            

if (bFindPort & (BYTE) (1 << (BYTE)nBitNum))

            

wsprintf( szMsg, "%sCOM%d ", (LPSTR) szMsg, nBitNum + 1 ) ;

     

}

     

// Отображаем на экране сообщение с названиями доступных

     

// COM-портов

     

MessageBox(NULL, szMsg, "Обнаружены COM-порты:",

                          

MB_OK | MB_ICONINFORMATION);

     

return 0;

}

// ============================================================

// Функция FindCOMPorts вызывает функцию OpenComm

// и определяет, какие COM-порты установлены в компьютере и

// доступны для использования

// ============================================================


BYTE FAR FindCOMPorts( void )

{

      // Буфер для подготовки имени порта

      char     szCommPattern[8];    

      // Идентификатор COM-порта

      int  idComDev;

      // Переменная для формирования результата

      BYTE  bFindPort = 0;

      // Вспомогательная переменная nBitNum

      int  nBitNum = 1;

      // Пробуем открыть COM-порты COM1 - COM8

      for(int i = 0; i < 8; i++) {

                          wsprintf( szCommPattern, "COM%d", i + 1 ) ;

             // Открываем COM-порт

             idComDev = OpenComm(szCommPattern, 1024, 1024);

             if (idComDev >= 0)

             {

                   // Если COM-порт n успешно открыт, тогда устанавливаем

                   // в переменной bFindPort n-ый бит

                   bFindPort = bFindPort | nBitNum;

                   // Закрываем COM-порт

                   CloseComm(idComDev);

             }

             nBitNum <<= 1;

      }

      // Возвращаем результат

      return bFindPort;

}

После запуска приложения OPENCOMM, функция WinMain вызывает функцию FindCOMPorts, определяющую список доступных COM-портов.

Функция FindCOMPorts содержит цикл, в котором открывается очередной COM-порт:

idComDev = OpenComm(szCommPattern, 1024, 1024);

Если OpenComm возвращает значение большее или равное нулю, значит COM-порт успешно открыт. В этом случае мы устанавливаем в байте bFindPort бит с номером, соответствующим номеру открытого порта. После этого мы закрываем только что открытый порт:

CloseComm(idComDev);

Затем мы переходим к проверке следующего порта. Если функция OpenComm возвращает значение, меньшее нуля, мы считаем, что порт недоступен.

Проверив в цикле COM-порты от COM1 до COM8, функция FindCOMPorts возвращает байт bFindPort. Каждый бит этого байта отвечает за свой COM-порт.

Установлен бит

Порт доступен

0

COM1

1

COM2

2

COM3

3

COM4

4

COM5

5

COM6

6

COM7

7

COM8

Получив байт bFindPort, WinMain формирует в строке szMsg список доступных портов и выводит его на экран с помощью функции MessageBox (см. рис. 7.1).



Рис 7.1. Список доступных COM-портов

Файл определения модуля приложения OPENCOMM приведен в листинге 7.2.

Листинг 7.2. Файл OPENCOMM.DEF

; =============================================================

; Файл определения модуля

; =============================================================

NAME OPENCOMM

DESCRIPTION 'Приложение OPENCOMM, (C) 1994, Frolov G.V.'

EXETYPE windows

STUB 'winstub.exe'

STACKSIZE  5120

HEAPSIZE  1024

CODE preload moveable discardable

DATA preload moveable multiple


Первая телекоммуникационная программа


Теперь мы приведем первую телекоммуникационную программу AUX_TEST, управляющую асинхронным последовательным адаптером на уровне регистров. Программа инициализирует регистры COM-порта, устанавливая новую скорость передачи информации и формат передаваемых данных. Затем программа в цикле передает коды клавиш, нажатых на клавиатуре в COM-порт и считывает из него принятые данные, отображая их на экране.

Программа работает с асинхронным адаптером COM1. Для правильной работы необходимо замкнуть вместе контакты 2 и 3 разъема COM1. В этом случае данные передаваемые в COM-порт сразу же принимаются им обратно.

Главный файл программы AUX_TEST представлен в листинге 5.2.

Листинг 5.2. Файл AUX_TEST.C

#include <stdio.h>

#include <conio.h>

#include "sysp_com.h"

void main(void);

void main(void) {

     

AUX_MODE amd;

     

aux_stat(&amd, 0);

     

printf("\nСостояние порта COM1:"

                    

"\nКод длины символа:    %d"

                    

"\nКод числа стоп-битов: %d"

                    

"\nКонтроль четности:    %d"

                    

"\nСкорость передачи:    %lu",

                    

amd.ctl_aux.ctl_word.len,

                    

amd.ctl_aux.ctl_word.stop,

                    

amd.ctl_aux.ctl_word.parity,

                    

(unsigned long)amd.baud);

     

amd.baud = 115200;

     

aux_init(&amd, 0, 0);

     

printf("\n\nТестирование асинхронного адаптера."

                    

"\nНажимайте клавиши!"

                    

"\nДля завершения работы нажмите CTRL-C"

                    

"\n");

     

for(;;) {

            

// Вводим символ с клавиатуры и передаем его

            

// в асинхронный адаптер

            

aux_outp(getch(), 0);

            

// Вводим символ из асинхронного адаптера и

            

// отображаем его на экране

            

putchar(aux_inp(0));

     

}

}

После запуска программы AUX_TEST вызывается функция aux_stat, определенная в нашем приложении. Она заполняет структуру amd типа AUX_MODE, записывая в нее информацию о текущем режиме COM-порта.


Информация, записанная в этой структуре, отображается на экране. Изменяем поле baud структуры amd, содержащее значение скорости передачи данных, записывая в нее число 115200. Затем функция aux_init, определенная в программе, увеличивает скорость передачи информации до 115200 бит/с.

Затем начинает выполняться бесконечный цикл, в котором вводится символ с клавиатуры и передается в COM-порт:

aux_outp(getch(), 0);

Сразу после передачи кода нажатой клавиши в COM-порт, вводим символ из этого же порта и отображаем его на экране:

putchar(aux_inp(0));

Чтобы завершить работу программы, достаточно нажать комбинацию клавиш <Ctrl+C>.

Включаемый файл SYSP.H, представленный в листинге 5.3, содержит описания функций aux_stat, aux_init, aux_inp, aux_outp и определение структуры AUX_MODE.

Листинг 5.3. Файл SYSP.H

void aux_stat(AUX_MODE *mode, int port);

int  aux_init(AUX_MODE *mode, int port, int imask);

void aux_outp(char chr, int port);

char aux_inp(int port);

typedef struct _AUX_MODE_ {

 union {

   struct {

      unsigned char len : 2, // длина символа

           stop         : 1, // число стоп-битов

           parity       : 2, // контроль четности

           stuck_parity : 1, // фиксация четности

           en_break_ctl : 1, // установка перерыва

           dlab         : 1; // загрузка регистра

                                                                               // делителя

   } ctl_word;

   char ctl;

 } ctl_aux;

 unsigned long baud; // скорость передачи данных

} AUX_MODE;

Теперь перейдем к рассмотрению функций aux_stat, aux_init, aux_inp и aux_outp, определенных в программе AUX_TEST.


Поддержка асинхронного адаптера в BIOS


В этом разделе мы опишем функции BIOS, облегчающие обслуживание асинхронного последовательного адаптера. Эти функции доступны через прерывание INT 14h.

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

На входе:  AH = 00h;

     

DX = номер порта:   0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4;

     

AL = параметры инициализации (см. ниже).

На выходе: AH = состояние порта асинхронного адаптера;

     

AL = состояние модема.

При вызове этой функции регистр AL должен содержать параметры инициализации (x - состояние бита безразлично):

Биты

Смысл

D1 D0

Длина слова в битах:

00 - 5 бит;

01 - 6 бит;

10 - 7 бит;

11 - 8 бит

D2

Количество стоповых бит:

0 - 1 бит;

1 - 2 бита

D4 D3

Четность:

x0 - контроль на четность не используется;

01 - контроль на нечетность;

11 - контроль на четность

D7-D5

Скорость передачи данных:

000 - 110 бит/с

001 - 150 бит/с

010 - 300 бит/с

011 - 600 бит/с

100 - 1200 бит/с

101 - 2400 бит/с

110 - 4800 бит/с

111 - 9600 бит/с

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

Бит

Смысл

D0

Тайм-аут, если установлен этот бит, другие биты не имеют значения

D1

Регистр сдвига передатчика пуст

D2

Буферный регистр передатчика пуст

D3

Обнаружено состояние BREAK

D4

Ошибка синхронизации

D5

Ошибка четности

D6

Ошибка переполнения входного регистра

D7

Данные готовы

Регистр AL содержит байт состояния модема:

Бит

Смысл

D0

Линия CTS изменила состояние

D1

Линия DSR изменила состояние

D2

Линия RI изменила состояние

D3

Линия DCD изменила состояние

D4

Состояние линии CTS

D5

Состояние линии DSR

D6

Состояние линии RI

D7

Состояние линии DCD

Для передачи байта используется следующая функция:

На входе:  AH = 01h;

     

DX = номер порта:   0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4;

     

AL = передаваемый байт.


На выходе: AL сохраняется;

      AH = состояние порта асинхронного адаптера,

             если бит 7 регистра AH установлен в 1,

             произошла ошибка.

Функция 02h предназначена для приема байта:

На входе:  AH = 02h;

      DX = номер порта:   0 - COM1, 1 - COM2, 2 - COM3,

                                3 - COM4;

На выходе:     AL = принятый байт;

      AH = состояние порта асинхронного адаптера,

             если регистр AH не равен 0,

             произошла ошибка.

Состояние порта асинхронного адаптера можно узнать с помощью функции 03h:

На входе:  AH = 03h;

      DX = номер порта:   0 - COM1, 1 - COM2, 2 - COM3,

                   3 - COM4;

На выходе: AH = состояние порта асинхронного адаптера;

      AL = состояние модема.


Поддержка асинхронного адаптера в MS-DOS


К сожалению, MS-DOS не содержит сколько-нибудь серьезной поддержки асинхронного адаптера. Две функции прерывания INT21h с номерами 3 и 4 предназначены для чтения и записи байтов через асинхронный адаптер. Обе эти функции имеют дело с адаптером COM1 или AUX. Функция 3 получает в регистре AL символ, принятый из адаптера, функция 4 посылает в адаптер символ, записанный в регистр DL.

Основной недостаток функций MS-DOS, предназначенных для работы с адаптером, заключается в отсутствии их функциональной полноты. Используя только функции MS-DOS, вы не сможете проанализировать ошибочные ситуации и изменить режим работы асинхронного адаптера - нет соответствующих средств.

Функции BIOS, обслуживающие адаптер, более разнообразны. Однако и им присущи недостатки. Например, вы не сможете установить скорость передачи более 9600 бит/с или использовать режим фиксации четности. Нет возможности узнать текущий режим асинхронного адаптера, отсутствует поддержка модема.

Поэтому для программирования асинхронного адаптера мы рекомендуем непосредственно обращаться к портам ввода/вывода микросхемы 8250.



Подключение модема к компьютеру


Для правильной установки модема вы должны правильно определить аппаратную конфигурацию компьютера и модема. Иногда может потребоваться изменить положение переключателей, расположенных на некоторых платах компьютера. Если вы неправильно подключите модем к компьютеру, то возможна неустойчивая работа модема и неожиданные сбои в работе компьютера.

Первоначальное подключение и настройку модема лучше доверить специалисту по аппаратному и программному обеспечению компьютеров серии IBM PC. Однако услуги подобного рода могут стоить достаточно дорого, поэтому имеет смысл повысить свою квалификацию и попытаться самостоятельно установить модем.

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

Внешний модем подключается к любому COM-порту компьютера. Если же в компьютере не установлен COM-порт (что очень маловероятно), то вам необходимо его приобрести.

Затем подключите питание к модему. Большинство внешних модемов поставляются с отдельным блоком питания, который вам надо подключить к местной электросети. Выходной разъем блока питания включите в ответный разъем на корпусе модема.

Если же у вас внутренний модем, то надо установить его на материнской плате компьютера в любой свободный слот.

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

Внешний и внутренний модемы подключаются к телефонной линии и телефону одинаковым образом. Для этого предназначены два разъема RJ11, расположенные на задней панели модема. Один разъем должен быть обозначен "LINE" (линия) или "WALL" (стена). Он предназначен для подключения модема к телефонной линии. Другой разъем обозначается "PHONE" (телефон), и в него вы можете вставить разъем телефона (см. рис. 3.1).

Рис. 3.1. Подключение модема к линии и телефону

Как правило, с модемом поставляется специальный кабель для подключения модема к телефонной линии. Здесь следует отметить, что разъем RJ11 не подходит к стандартным телефонным розеткам, используемым в нашей стране. Кроме того, разъем RJ11 имеет четыре линии, а обычная городская телефонная линия только две. Если у вас нет специального переходника, вы его можете приобрести или изготовить сами (из кабеля, поставляемого с модемом и обычной телефонной вилки и розетки) в соответствии с рисунком 3.2.




Рис. 3.2. Ответная часть разъема RJ11

Согласно рисунку, вы должны подключить к телефонной линии и телефону два средних провода. Оставшиеся два провода надо оставить неподключенными.

После того как вы выполнили все указанные действия, снимите трубку телефона, не включая питания компьютера. Если слышен длинный гудок - все нормально, в противном случае проверьте соединения разъемов и кабели.

Включите питание компьютера и модема (в случае внешнего модема). Еще раз проверьте работу телефона. Если телефон не работает, проверьте разъемы и кабели. Если они в порядке, обратитесь к документации модема, возможно, что он неисправен.

Теперь можно приступить к проверке самого модема. Для этого вам надо запустить любую коммуникационную программу, находящуюся в вашем распоряжении, и попытаться связаться с другим модемом.

Обычно простые коммуникационные программы, например, BITCOM или COMIT, поставляются вместе с модемом. Вы также можете использовать приложение Terminal, которое входит в стандартную конфигурацию операционных систем Windows 3.1 и Windows for Workgroups 3.11.

Если вы приобрели факс-модем, его также надо проверить при передаче и приеме факсимильных сообщений. Чтобы послать и принять факс, вы можете воспользоваться программой, поставляемой вместе с модемом или приложением Microsoft At Work PC Fax, входящим в состав операционной системы Windows for Workgroups 3.11.