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

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

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

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

6.3. Использование прерываний COM-порта

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

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

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

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

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

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

  • Изменилось состояние линии приемника: произошло переполнение приемника, произошла ошибка четности или синхронизации, линия перешла в состояние BREAK
  • Данные приняты и доступны для чтения через регистр данных. Обработчик прерывания должен прочитать их и сохранить в буфере для дальнейшей обработки
  • Регистр передатчика пуст. Обработчик прерывания может записать в COM-порт следующий байт
  • Изменилось состояние модема: изменилось состояние линий CTS, RI, DCD, DSR. Состояние этих линий позволяет программе определить, установлена ли связь с удаленным модемом, есть ли звонок на телефонной линии и т. д.
  • Вы можете отдельно запрещать или разрешать эти прерывания. Для этого необходимо установить соответствующие биты в регистре управления прерываниями.

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

    COM-портЛиния IRQПрерывание
    COM1IRQ4INT 0Ch
    COM2IRQ3INT 0Bh
    COM3IRQ4INT 0Ch
    COM4IRQ3INT 0Bh

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

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

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

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

    Разрешить обработку прерываний

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

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

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

    Биты D2 D1Причина прерывания
    00Прерывание по линии состояния
    01Буфер передатчика пуст
    10Данные приняты
    11Изменилось состояние модема

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

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

    Считать регистр состояния линии и уточнить причину прерывания (данное прерывание сбрасывается после чтения регистра состояния линии). Если это необходимо, подать основной программе сигнал о произошедшей ошибке с целью ее устранения. Например, в случае определения на линии сигнала BREAK (удаленный модем повесил трубку), надо попытаться возобновить связь.

    Прерывание по принятию данных

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

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

    Прерывание происходит в случае, если буфер передатчика пуст и можно передать COM-порту очередной символ. Можно организовать буфер передатчика программы, в который программа будет записывать данные, предназначенные для передачи через COM-порт. В этом случае, когда придет прерывание, надо считать очередной символ из буфера передатчика программы и записать его в регистр данных. Прерывание сбрасывается после записи очередного символа в регистр данных UART. Если нет данных для передачи (программный буфер передатчика пуст), можно запретить это прерывание через регистр управления прерываниями.

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

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

    Считать регистр идентификации прерывания

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

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

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

    mov	al,20h
    out	20h,al

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

    6.3.2. Последовательность работы программы

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

    Установить обработчик прерываний

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

    Выполнить инициализацию COM-порта

    Сначала надо перевести в неактивное состояние линии DTR и RTS. Затем сбросить регистр состояния линии, регистр состояния модема и регистр данных.

    После того как мы сбросили регистры UART, можно приступить к инициализации COM-порта. Во время инициализации задается формат данных - длина слова, количество стоповых битов, наличие контроля по четности и скорость обмена.

    Последним шагом в инициализации регистров UART является установка регистра управления прерываниями. Например, чтобы разрешить генерацию прерываний при приеме очередного символа, надо записать значение 01h в регистр управления прерываниями:

    outp(port_adr+ICR, 1); // ICR - адрес регистра // управления прерываниями

    На этом этап инициализации регистров UART можно считать законченным. Теперь COM-порт подготовлен для обмена данными с модемом, но модем пока еще не будет воспринимать данные от компьютера. Чтобы перевести его в рабочее состояние, надо передать ему сигналы DTR и RTS. В ответ на эти сигналы модем должен вернуть компьютеру сигналы DSR и CTS.

    Выполнить инициализацию контроллера прерываний

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

    
    // Считываем состояние регистра маски прерываний 
    
    mov	dx,21h
    in 	dx,al
    
    // Разрешаем прерывания от порта COM1
    and	al,11101111b
    
    // Записываем новое значение в регистр маски прерываний
    out	dx,al

    Выполнить инициализацию модема и установить связь

    После установки обработчика прерываний и инициализации регистров COM-порта и контроллера прерываний можно передавать модему AT-команды и принимать от него ответ на них. При этом данные можно считывать (записывать) из COM-порта через буфер обработчика прерываний.

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

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

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

    Завершить программу

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

    // Считываем состояние регистра маски прерываний 
    mov	dx,21h
    in 	dx,al
    
    // Запрещаем прерывания от порта COM1
    or 	al,00010000b
    
    // Записываем новое значение в регистр маски прерываний
    out	dx,al

    Затем нужно восстановить старый вектор обработчика прерываний.

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