Программирование - интерфейс RS-232

Сдавался/использовался1999г.
Загрузить архив:
Файл: 240-1935.zip (121kb [zip], Скачиваний: 141) скачать

              ПРОГРАММИРОВАНИЕ ПОСЛЕДОВАТЕЛЬНОГО ПОРТА

    Последовательный порт в системе MS-DOS обеспечиваетвходво

внешниймир.  Основнойзадачей последовательного порта является

направление и получение данных по шине в виде  потокабитов.(В

противоположность параллельному порту,в котором внутренний байт

передается целиком). Вы можете использовать последовательный порт

дляподключения к системе "мыши",направления данных на принтер

или для установления автоматической телефонной связи с  использо-

ванием модема. Хотя системы MS-DOS не нуждаются для работы в пос-

ледовательном порте,эти порты стали стандартной периферией сис-

темы.

    Последовательный порт в системах MS-DOS способен поддерживать

стандарт асинхронной передача данных RS-232C.  Хотя даже посредс-

твом ROM-BIOS, стандартной части всех систем MS-DOS, MS -DOS сама

посебе  включаетнекоторуюподдержку  программирования портов

RS-232C (например,прерывание номер 14h), эта поддержка не отве-

чает требованиям высокоскоростной связи.Если Вы хотите включить

в свою прикладную программуэффективныевозможности  последова-

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

порту на аппаратном уровне.В этой главе показано, как это дела-

ется.

Основы асинхронной последовательной связи

    Говоря о передаче данных,мы интересуемсяпередачей  байтов

данных от одного устройства к другому, например, от персонального

компьютера к модему или кпоследовательномупринтеру.  Еслимы

имеемвосемь линий между двумя устройствами,то мы можем назна-

чить каждой линии бит и послать сразу один байт данных. Это будет

параллельнаяпередача.  Таким образом работает параллельный порт

персонального компьютера, кроме того, в дополнение к восьми лини-

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

передаче данных.

    С другой стороны,если мы имеем одну линию для передачи сиг-

налов, то необходимо посылать каждый байт данных последовательно,

по одному биту.Более того,мы может посылать данные синхронно,

таким образом,что каждый байт посылается вранее  определенное

время (скажем, один байт каждые х секунд), или асинхронно со ско-

ростью, которую предварительно определять необязательно.

    Последовательная связьдешевле,  чемпараллельная,так как

требует меньше линий передачи данных - минимум две для двусторон-

ней связи. Кроме того режим асинхронной передачи оказывает значи-

тельно меньшее воздействие на аппаратуру ввиду того,  что не тре-

буетсядополнительноеспециальное  оборудованиедляподдержки

синхронизации между передатчиком и приемником.

    Таким образом,асинхронная  последовательнаясвязь является

предпочтительным решением ввиду низкой стоимости и  простотыис-

пользуемых аппаратных средств. Конечно, в этом режиме передачи мы

должны преобразовывать каждый байт данных в серию битов иуказы-

вать приемнику начало и конец каждого байта.На рисунке 8-1 про-

иллюстрирована концепция асинхронной последовательной связи.

    Предположим, что мы умеем преобразовывать каждый байт в поток

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

среду связи (например,телефонную линию).В самом деле, универ-

сальный асинхронный приемопередатчик (UART), как мы увидим в сле-

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

время как линия находится в режиме ожидания, для демонстрации то-

го, что линия в порядке, по ней передается единица, обозначая не-

занятость линии. С другой стороны, когда линия находится в состо-


┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┐

                                 Восстанавливается один байт

│                               └7  654  3221 ┘└──┐

   ┌───Принимается один символ────┐└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘ ┌─┐|

│  |A||B||7||6||5||4||3||1||0||C|  ^^^  ^^^  ^^    ||

--> └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘ ┌─────┬─────────┬─────┐|─┘└┐

┌──────────────────────────────────|D  |         |     |  |   |

|│    от модема                   └─────┴─────────┴─────┘|───|

|UART на приемном конце             скорость в бодах      |   |

|└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─|   |

|                                                           |───|

|  ┌───────┐                                                |   |

└──|       |──┐                                             |───|

   └───────┘│                                      Принимающий

              │        Телефонная линия                 компьютер

             ┌┼┐___________________________┌─┐

             └─┘      <--                  └┼┘

                                            │

                                            │

                                            │

                                            │       ┌───────┐

                                            └───────| модем |───|

      ┌────────┐                                    └───────┘   |

      │        │                                                |

      │   PC   │                                                |

   ┌──┴────────┴──┐                                             |

   │              │                                             |

   └┐┌────────────┘                                             v

    ||  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ──┐

    ||  │ ┌──────── Байт───────────┐

    ||      765  432  21                              |

    |└──┘  └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘┌───Посылаемыйодин символ──┐

    └───┐                          |A||B||7||6||5||4||3||1||0||C|

           ┌─────┬─────────┬─────┐ └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘

        |  |     |         |  D  |──────────────────────────────┘

           └─────┴─────────┴─────┘         к модему -->         |

        |  скорость в бодах   UART в последовательном адаптере PC

        └ ─ ─ ─ ─ ─ ─ ─ ─ ─── ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

        A-стоп; B-четность; C-начало; D-сдвиговый регистр

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

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

рассматриваются, соответственно, как MARK и SPACE.

          Рис.8-1. Асинхронная последовательная связь.

    В асинхроннойсвязи изменение условия состояния линии с MARK

на SPACE означает начало символа (смотри рисунок 8-2).Это назы-

вается стартовым битом. За стартовым битом следует комбинация би-

тов,представляющая символ, и затем бит контроля четности. Нако-

нец,   линия   переходит   всостояние  ожиданияMARK,которая

представляет собой стоповый бит и означает конец текущего  симво-

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

ется длиной слова и обычно бывает равно семииливосьми.  Конт-

рольныйбит используется для выполнения элементарной проверки на

наличие ошибки.

<---------     Направление передачи

Линия                                     Линия возвращается в

свободна                                   свободное состояние

        A

B ────┐  ┌ ─ ┬ ─ ┬ ─ ┬ ─ ┬ ─ ┬ ─ ┬ ─ ┬ ─ ┬ ─ ┬───┬───────┐┌ ─ ─

      │  │ 0   1   2   3   4   5   6   7     │           │

C ─ ─ └──┘ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ┴ ─ ─ ─ └──┘ ─ ─

       ^ └──────── 7 или 8 бит данных ───┘ ^   ^           ^

   Стартовый                       бит четности│   Начало другого

     бит                                       │      символа

                                        бит стоповый

                Время ----->

          A-длительность 1 бита; B-MARK или 1; C-SPACE или 0

        Рис.8-2. Представление в асинхроннойпоследовательной

                   связи формата одиночного символа

    Как передатчик(или  приемник) узнают о длительности каждого

бита?Действительно,и передатчик,  и приемник должны знать его

длительность или детектирование битов будет невозможно.  Длитель-

ность каждого бита определяется генераторами  тактовыхимпульсов

приемника и передатчика. Отметим, однако, что генераторы в прием-

нике и передатчике должны иметь одну и ту же частоту,  но не тре-

буется, чтобы они были синхронизированы. Выбор частоты генератора

зависит от скорости передачи в бодах,которая означает число из-

менений состояния линии каждую секунду. Номинально  тактовая час-

тота "16-кратная скорость передачи в бодах" означает,что  линия

проверяетсядостаточно часто для надежного распознавания старто-

вого бита.

    Существует однообычное состояние линии,которое иногда ис-

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

ниемлинии  являетсяMARK (или 1) и начало символа определяется

переходом SPACE (0). Если линия находится в состоянии SPACE в те-

чение периода времени большем,чем время,которое она затратила

бы на получение всех битов символа,тогда мы говорим, что насту-

пилосостояние  BREAK.Вкодах ASCII отсутствует представление

BREAK - это означает,что линия"умерла"на  непродолжительный

промежуток времени, который составляет BREAK.

Контроль по четности и обнаружение ошибок

    Ранее мы упоминали, что бит контроля четности полезен для об-

наруженияошибок.  Например,если выбрана проверка на четность,

этот бит устанавливается таким образом,что общее число единиц в

текущемслове  является четным (такая же логика используется для

проверки на нечетность).В приемнике четность вычисляется заново

и сравнивается с битом контроля четности.Если они не равны,то

приемник сообщает,что имеет место ошибка четности.Главный не-

достаток обнаружения ошибки посредством проверки на четность зак-

лючается в том,что можно только обнаружить ошибки, которые вли-

яют на один единственный бит.Например,битовая комбинация 0100

0001 0 (ASCII A),переданная восемью битами с проверкой начет-

ность, может измениться (скажем,из-за шума в линии) на 0100 01110

(ASCII G), однако приемникнеобнаружит ошибку, так как провер-

ка на четность выполняется.

Связь с использованием стандарта RS-232C.

    Ранее мы  упоминалиопередаче по телефонной линии единиц и

нулей.   Несмотря на то,что в персональном компьютере мыпред-

ставляем единицы и нули посредством уровней напряжения,  сигналы,

передаваемые по телефонной линии обычно являются тонами различной

частоты.Устройство,  которое находится между аппаратурой персо-

нального компьютера и передающей линией и делает возможнойпере-

дачу данных,   называется модемом (модулятор/демодулятор).Модем

может преобразовывать информацию в  представление "напряжение/нет

напряжения" цифровых схем и обратно,а так же аналоговые сигналы

(например,тоны), предназначенные для передачи по телефонной ли-

нии.Стандарты, такие как RS-232C (выдвинутый Ассоциацией элект-

ронной промышленности,EIA),описывают метод обмена информацией

междумодемом  (или,всоответствии с терминологией ассоциации

EIA,"аппаратура передачи данных,DCE") и  связнойаппаратурой

персональногокомпьютера  (или"оконечнаяаппаратура обработки

данных,DTE"). Модем может работать в двух режимах: полудуплекс-

номи  дуплексном.В полудуплексном режиме модем может осущест-

влять передачу только в одном направлении в один промежуток  вре-

мени,   в   то   время   как   приработев  дуплексномрежиме

осуществляется независимая двухсторонняя связь.  Стандарт RS-232C

обеспечивает управление такими сигналами, как "запрос-на-передачу

(RTS)" и "открыт-для -передачи (CTS)", которые могут быть исполь-

зованыдля координации процесса передачи и приема данных. Термин

"квитирование установления связи" используется для описания коор-

динации приема и передачи сигналов.Как показано на рисунке 8-3,

стандарт RS-232C соответствует кабелю и соединителям,  используе-

мым для связи персонального компьютера и модема.

    Несмотря  на то, что мы использовали модем в качестве примера

аппаратуры передачи данных (DCE),другие устройства,такиекак

"мышь" или принтер с соответствующей схемой,  также могут обмени-

ваться данными с персональным компьютеромчерез последовательный

порт.Таким образом, в этой главе все упоминания о модеме прием-

лемы в равной степени как к последовательному принтеру  такик

последовательной "мыши".


          ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ── ─ ─ ─ ─ ┐

           ОАОД   ┌─────   Номер контакта ──────┐   DCE

          |  ┌─────┐                          ┌─────┐|

             |    2|─────────────ПД───────────| 2   |

          |  |    3|──────────────П───────────| 3   |  |

             |    4|─────────────ЗП───────────| 4   |

          |  |    5|────────────ОДП───────────| 5   |  |

             |    6|────────────ГПД───────────| 6   |         к

          |  | ┌──7|───────────Общий──────────| 7──┐|телефонной

             |    8|───────────ДСПЛ───────────| 8   |       линии

          |  |   20|────────────ТДГ───────────|20   |  |        ^

             |   22|─────────────RI───────────|22   |           |

          |  |    .|                          | .   |  |────┐   |

             |    .|                          | .   |       |   |

        ┌─||    .|                          | .   |  |    |   |

RS ---> |    └─────┘                          └─────┘       |   |

        | └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ── ─ ─ ─ ─ ┘    |   |

    ┌───┴────┐                                              |   |

    │        │                                           |--|   |

    │        │                                           |   ---|

┌──┴────────┴──┐                                      ┌─┴───┴─┐

│              │                                      |       |

└──────────────┘                                      └───────┘

    PC или ОАОД                                          Модем ил

     ОАОД-оконечная аппаратура обработки данных;RS-кабельRS-232C;

     ПД - передача данных; П-прием данных;ЗП -запрос на передачу;

     ОДП - открыт для передачи; ГПД - готов к передаче данных;

     ДСПЛ - детектор сигнала приемной линии; ТДГ -терминал данных

     готов;  АПД - или аппаратура передачи данных

                          Рис.8-3. Связь RS-232C.

              Управление потоком с помощью XON/XOFF

    В дополнение к квитированиюустановления  связипосредством

аппаратных сигналов RTS/CTS,для достижения управления потоком с

использованием программного обеспечения  применяютсяспециальные

управляющиесимволы  ASCII(Control-Q/Control-S или XON/ XOFF).

Управлять потоком необходимо ввиду того, что иногда либо передат-

чиклибо  приемник не могут поддерживать скорость передачи и они

должны иметь возможность информировать другую сторону о необходи-

мостиостановки  на время,требуемое для того,чтобы отставшая

сторона смогла догнать другую.

    Предположим, что приемник имеет буфер для храненияпоступаю-

щих символов. Как только буфер после заполнения закрывается, при-

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

передача должна быть приостановлена. Конечно, приемник должен по-

нять значение XOFF и прекратить передачу символов.  Затем,когда

приемник обработает символы (скажем,запишет их в файл на диске)

и буфер освободится,тогда посылается символ XON,показывающий,

что передача может быть продолжена.Эта схема управления потоком

широко применяется ввиду ее простоты.  Большинство связныхпрог-

рамм предоставляют возможность дуплексной связи с управлением по-

током, основанном на применении символов XON/XOFF.

       Последовательный порт с точки зрения программиста

    Аппаратура последовательного порта в системах MS-DOS известна

как последовательный адаптер или асинхронный связной адаптер (да-

леемы  будем называть его последовательным адаптером).Адаптер

основан на Intel 8259 UART (универсальный асинхронный приемопере-

датчик), имеет порт RS-232C для подключения к модему и, как адап-

тер дисплея,программируется посредством набора регистров.Мик-

ропроцессоримеет  доступкрегистрам через ранее определенные

адреса порта ввода/вывода.

    Универсальный асинхронныйприемопередатчик Intel 8250 управ-

ляется посредством записи в набор восьмибитовых регистров ичте-

ния из них.Эти регистры доступны программисту через адреса пор-

та.Адреса портов задаются последовательно,поэтому  достаточно

знатьадрес  первого порта.Он также известен как базовый адрес

последовательного адаптера. В персональном компьютере IBM PC двум

последовательным портам COM1 и COM2 присвоены базовые адреса пор-

та 3F8h и 2F8h соответственно. Так, для последовательного адапте-

ра COM1 первый регистр имеет адрес 3F8h, следующий 3F9h и так да-

лее.

    В 8250  имеется семь физических регистров и они описываются в

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

Как показано нарисунке 8-4,базовый адрес порта имеет один ре-

гистр,который делится на два,как приемный буферный регистри

регистр хранения передачи (THR),который используется для хране-

ния одного передаваемого или принимаемого символа.  Затем следует

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

ния или блокировки генерации прерываний последовательнымадапте-

ром.Третий регистр, называемый регистром идентификации прерыва-

ний,    содержит    сообщение     универсального     асинхронного

приемопередатчикаоб идентичности прерывания.Затем следует ре-

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

связныхпараметров,  таких как длина слова,количество стоповых

битов,четность и скорость передачи в бодах. Пятый регистр - это

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

дему сигналов,таких как DTR (терминал готов) и RTS(запросна

передачу). Наконец, два последних регистра, регистр состояния ли-

нии и регистр состояния модема, показывают соответственно состоя-

ние линии и модема.

    Первые два регистра применяются также для установкискорости

передачив  бодах.Скоростьпередачи  в бодах определяется как

16-битовый делитель тактовой частоты, используемой для последова-

тельного адаптера (1.8432 МГц в большинстве систем MS -DOS). Зна-

чение делителя вычисляется по формуле

                        1,843,200

    делитель= ------------------------------

              16 Х скорость передачи в бодах

    Чтобы установить скорость передачи в бодах,Вы должны проде-

лать следующее:

    1. Установить в 1 наиболее значимый битрегистрауправления

       линией  (онназывается битом защелки доступа делителя или

       DLAB).

    2.Загрузить младший и старший байты делителя соответственно в

       приемный буфер и регистр разрешения прерываний.

    3. Установить DLAB в 0 для обеспечения нормальной работы уни-

       версального асинхронного приемопередатчика.


   A     Приемный буфер/регистр хранения передачи

   B     ┌───┬───┬───┬───┬───┬───┬───┬───┐

(COM1-3F8| 1.|   |   |   |   |   |   | 2.|

COM2-2F8)└───┴───┴───┴───┴───┴───┴───┴───┘

         Регистр разрешения прерывания

   B+1   ┌───┬───┬───┬───┬───┬───┬───┬───┐

         | 0 | 0 | 0 | 0 | 3.| 4.| 5.| 6.|

         └───┴───┴───┴───┴───┴───┴───┴───┘

         Установить бит в 1 для разрешения

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

   B+2   ┌───┬───┬───┬───┬───┬───┬───┬───┐

         | 0 | 0 | 0 | 0 | 0 |   |   | 7.|

         └───┴───┴───┴───┴───┴───┴───┴───┘

                             └─3-битовый идентификатор прерывания

                              110 = состояние линии

                              100 = приемные данные

                              010 = буфер передачи свободен

                              000 = состояние модема

         Регистр управления линией

   B+3   ┌───┬───┬───┬───┬───┬───┬───┬───┐

         | 8.|   |    9.     |10.|  11.|

         └───┴───┴───┴───┴───┴───┴───┴───┘

               └─BREAK: 1 устанавливает линию в SPACE

         Регистр управления модемом

   B+4   ┌───┬───┬───┬───┬───┬───┬───┬───┐a. - OUT2

         | 0 | 0 | 0 |12.| a.| b.| c.| d.|b. - OUT1

         └───┴───┴───┴───┴───┴───┴───┴───┘c. - RTS

                           └── 13.          d. - DTR

         Регистр состояния линии

   B+5   ┌───┬───┬───┬───┬───┬───┬───┬───┐

         | 0 |14.|15.|16.|17.|18.|19.|20.|

         └───┴───┴───┴───┴───┴───┴───┴───┘

         Регистр состояния модема          a. - RLSD

   B+6   ┌───┬───┬───┬───┬───┬───┬───┬───┐b. - Delta RLST

         | a.| RI|DSR|CTS| b.| c.| d.| e.|c. - Delta RI

         └───┴───┴───┴───┴───┴───┴───┴───┘d. - Delta DSR

                                            e. - Delta CTS

A - адрес порта или регистр

B - базовый адрес; 1. - бит 7 данных;2. - бит 0 данных;

3. - состояние модема; 4. - состояние линии приема;

5. - регистр хранения передачи свободен; 6. - прием данных

разрешен; 7. - 0 означает, что прерывание ждет;

8. - бит доступа к защелке; 9. - четность:000=нет,

001=нечетность, 011=четность; 10. - число стоповых битов;

11. - длина слова: 10-7, 11-8; 12. - проверка обратного цикла;

13. - должен быть 1 дляпрерывания ввода/вывода персонального

компьютера; 14. - передача свободна; 15. - регистр хранения пере-

дачи свободен; 16. - обнаружен BREAK; 17. - ошибка кадровой

синхронизации; 18. - ошибка четности;19. - ошибка выхода за

границы; 20. - данные для приема готовы;

                    Рис.8-4. Регистры в 8250 UART.

    Применяя этот подход Вы можете установить любое значение ско-

рости передачи в бодах.Обратите внимание, что максимальновоз-

можной скоростью передачи является1/16тактовой  частоты,или

115,200бод (для этой скорости передачи делитель равен 1).Этот

предел вытекает из того, что делитель не может быть меньше едини-

цы.Для  установки скорости передачи в бодах Вы можете также ис-

пользовать прерывание BIOS 14h. Мы рассмотрим применение BIOS да-

лее в этой главе.

      Управляемый прерываниями последовательный ввод/вывод

    Существует два общих метода ввода/вывода в любой вычислитель-

ной системе:упорядоченный и управляемый прерываниями.Упорядо-

ченность относится к повторяющейсяпроверкесостояния  регистра

устройства ввода/вывода для инициализации требуемой транзакции. В

упорядоченном вводе/выводе программа, запрашивающая символ ввода,

многократно считывает состояние регистра в устройстве ввода/выво-

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

(илидотех пор,пока программа не решит,что "время закончи-

лось"). Когда состояние указывает, что имеется готовый для работы

символ, программа считывает его из соответствующего регистра уст-

ройства ввода/вывода.Сходная последовательность "ждать,до тех

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

волов на устройство ввода/ вывода.Таким образом, дальнейшее вы-

полнениепрограммы  приостанавливаетсядо завершения выполнения

операции ввода/вывода.

    Большой проблемойдля упорядоченного ввода/вывода через ком-

муникационный порт является то,что при скоростипередачи  выше

300бод  программе трудно что-либо сделать с получаемым символом

кроме как отображать его на экране.Рассмотрим следующий пример.

Предположим,чтомы читаем символы со скоростью 300 бод и имеем

следующие связные параметры:длина слова 7 бит, проверка на чет-

ность и один стоповый бит, который вместе со стартовым битом, до-

бавляет до 10 бит на символ. Вы ожидаете получать около 30 симво-

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

1/30 секунды для выполнения других операций. ЕслиВы нежелаете

потерять какие-либо символы,то в это время Вы должны снова начать

упорядочение порта.Что произойдет,когда скорость возрастет до

9600 бод?Временной интервал между символами слишком мал для вы-

ведения символа на экран дисплея,не позволяетинтерпретировать

специальные символы и эмулировать терминал.

    В подходе,  основанном на управлении прерываниями,  программа

предоставляетвозможность  прерываниямустройстваввода/вывода

поступать непосредственно на центральный процессор,  который про-

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

устройство готово к вводу/выводу, оно сигнализирует об этом цент-

ральному процессору посредством аппаратуры.  Получив этот сигнал,

центральный процессор сохраняет свое текущее состояние и вызывает

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

таблице векторов прерываний.Эта подпрограмма выполняет операцию

ввода/вывода,затем восстанавливает состояние машины и возвраща-

ется в прерванную программу.Учитывайте регистр символов, посту-

пающих в коммуникационный порт персонального компьютера.  Органи-

зовав где-нибудьнекоторые  ячейкипамяти(буфер),  Выможете

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

быстро считывает символ из коммуникационногопортаи  сохраняет

его в следующей доступной ячейке памяти в буфере.  Символы не бу-

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

прерыванийперед поступлением следующего символа.Эта несложная

задача достаточно проста для выполнения в короткие временные  ин-

тервалы   между   поступающимисимволамипри  скорости передачи

9600 бод.Прелесть этого метода заключается в том, что время об-

работки главной программой символов, хранящихся в буфере, не име-

ет значения. Конечно, существует риск переполнения буфера, но эта

проблемаможет быть решена простым увеличением его размера. Если

этот способ не очень хорош,то для избежания переполнения буфера

можно использовать управление потоком с помощью XON/XOFF.

    Из наших рассуждений должно стать очевидным,что управляемая

прерываниями буферная связь с использованием управления потоком с

помощью XON/XOFF, предпочтительнее упорядоченной связи.

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

    Последовательный адаптерперсонального компьютера может быть

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

всякийраз как только происходит одно из четырех событий (смотри

рисунок 8-5). Универсальный асинхронный приемопередатчик присваи-

вает приоритет каждому из четырех событий. В таблице 8-1 перечис-

лены четыре прерывания.


                                                Таблица 8-1

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

───────────────┬────────────────────────────────────────────────

    Приоритет  |Идентификатор прерывания

───────────────|────────────────────────────────────────────────

       1       |Состояние приемной линии (RLS)

       2       |Доступность данных для приема (RDA)

       3       |Регистр хранения передачи свободен (THRE)

       4       |Состояние модема (MS)

───────────────|────────────────────────────────────────────────

      Символы ASCII

    ┌─┬─┬─┬─┬─┬─┬─┬─┐        ┌─────────────────────────────────┐

    └─┴─┴─┴─┴─┴─┴─┴─┘        |  Регистр разрешения    1 2 3 4|

                             |         прерывания    ┌─┬─┬─┬─┐ |

                             |                       └─┴─┴─┴─┘ |

                             |                           │     |

                             ||

                             |Идентификация        ┌─┬─┬─┬─┐ |

                             |    прерывания         └─┴─┴─┴─┘ |

Последовательный |                 ┌────────┘      |

                 адаптер     └──────────────┐                  |

                                            │ ││││││││││││││││ |

                                            └─┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴─┘

                                            ┌─┐

                  Прерывание к 8259A       ─┘ └──

         Рис.8-5. Прерывания последовательного адаптера

    Событием высшего приоритетаявляется  прерывание"состояние

приемнойлинии"  (RLS),которое обрабатывается чтением регистра

состояния линии. Прерывание RLS имеет место, когда происходит од-

но из следующих событий:

    - Линия  отключается(логический 0) на период времени больше

      требуемого для получения символа.

    - Символ  получен до того,как был считан предыдущий (ошибка

      выхода за границы).

    - Ошибка при проверке на четность.

    - При восстановлении символа из полученных битов не обнаружен

      стоповый бит (ошибка кадровой синхронизации).

    Затем следуетпрерывание  "доступностьданныхдля  приема"

(RDA),которое возникает при готовности символадля  чтенияиз

приемного буферного регистра.Оно может быть сброшено путем счи-

тывания символа из регистра.

    Следующий приоритетимеет прерывание "регистр хранения пере-

дачи свободен" (THRE). Как следует из имени прерывания, оно имеет

место,когда регистр, хранящий символ, предназначенный для пере-

дачи (имеет тот же адрес порта,что и регистр приемного буфера),

свободен.Прерывание  обрабатываетсязаписью в этот регистр или

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

метод сброса этого прерывания, так как иногда даже через прерыва-

ния универсального асинхронного приемопередатчика сообщается, что

буфер передачи пуст и, возможно, отсутствует информация для пере-

дачи.

    Самый низкийприоритет  имеетпрерывание "состояние модема"

(MS). Оно имеет место, когда модем:

    - Получает (посылает) сигнал "открыт для передачи" (CTS).

    - Показываетсвою  готовность установкой линии "набор данных

      готов" (DSR).

    - Получает  сигнал,устанавливающий линию "индикатор кольца"

      (RI) в логическую 1.

    - Определяетсигнал  переноса (тот тон,который Вы слышите,

      когда вызываете номер и модем отвечает), устанавливая линию

      "определение сигнала приемной линии" (RLSD) в 1.

Прерывание состояниямодема может быть сброшено чтением регистра

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

    Эти прерываниямогут  включаться и выключаться индивидуально

установкой соответствующих битов в регистре  разрешенияпрерыва-

ний. В последовательно-параллельном адаптере фирмы IBM (также как

и в асинхронном адаптере фирмы IBM) бит с именем OUT2в регистре

управления модемом должен быть установлен в 1 до того, как преры-

вания универсального асинхронного приемопередатчика могут достичь

центральный процессор.Когда имеют место прерывания,последова-

тельный адаптер собирает их согласно приоритету и направляет пре-

рываниевысшего  приоритетав регистр идентификации прерывания.

Адаптер прекращает отвечать на последующие прерывания равного или

меньшего приоритета до тех пор, пока не определит, что текущее не

обслужено подпрограммой обслуживанияпрерываний. Программируемый

контроллер прерываний 8259A.

    В  системахMS-DOSцентральный  процессор   (микропроцессор

80х86) непосредственно не принимает  прерывания,поступающиеот

аппаратных средств,таких как последовательный адаптер. Прерыва-

ния аппаратуры сначала обслуживаются чипом программируемого конт-

роллерапрерываний  Intel 8259A.8259A действует как "приемщик"

центрального процессора.Контроллер 8259A,как  программируемое

устройство, принимает до восьми различных прерываний и может мас-

кировать (игнорировать) прерывания индивидуально.  8259A отвечает

накаждое незамаскированное или разрешенное прерывание и направ-

ляет его центральному процессору при условии,что никакое другое

прерывание высшего приоритета не обслуживается в настоящее время.

    Как контроллер 8259A присваивает приоритеты?Каки  универ-

сальный асинхронный приемопередатчик имеет свой метод определения

приоритетов прерываний последовательного адаптера, 8259A обладает

своей схемой присваивания приоритетов прерываниям. Последователь-

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

могут направлять прерывания контроллеру 8259A.Каждое устройство

жестко смонтировано или соединено проводниками с различными вход-

ными устройствами, известными как входные устройства запроса пре-

рываний (IRQ) контроллера 8259A.Поэтому, обычно говорят об IRQ,

присвоенном аппаратному прерыванию.Другой характеристикой, свя-

занной с IRQ прерывания,является номер прерывания, используемый

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

IBM PC этот номер равен восьми плюс IRQ. Когда имеет место преры-

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

декса в таблице,известной как таблица векторов прерываний (рас-

положенав  начале памяти),которая содержит адрес подпрограммы

обработки данного прерывания.Так как контроллер 8259A связывает

высшие приоритеты с низкими IRQ, аппаратные устройства, требующие

максимального внимания,имеют низкие IRQ. Таким образом, систем-

ный таймер имеет IRQ0, клавиатура имеет IRQ1 и так далее.

    Несмотря  на то,что MS-DOS 3.3 поддерживает четыре коммуни-

кационных порта, с COM1 по COM4, эта поддержка не означает ничего

кроме обладания четырьмя драйверами с этими  именами,каждыйиз

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

дом/выводом.Так как мы  интересуемсяуправляемыми прерываниями

последовательным вводом/выводом, детали поддержки системой MS-DOS

коммуникационных портов не относятся к данному вопросу.

    В персональномкомпьютере  IBMPCтолько два первых порта,

COM1 и COM2,имеют определенные номера IRQ и номерапрерываний.

Другиепоследовательные порты,такие как COM3 и COM4 могут быть

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

тановкиадаптеров  иприсваивания номеров IRQ посредством соот-

ветствующей установки перемычек. Как только станет известен номер

IRQ, программирование портов COM3 и COM4 выполняется таким же об-

разом,как и портов COM1 и COM2. Более того, до конца этой главы

мы будем рассматривать только порты COM1 и COM2.

    Двум последовательным портам COM1 и COM2 присвоенысоответс-

твенно IRQ4и IRQ3,  то есть номера прерываний 12 и 11 (десятич-

ные).Между прочим,  номера прерываний должны быть известны, так

какфункциональные вызовы DOS (посредством программного прерыва-

ния 21h) с функциональными номерами 35h и 25h могут быть  исполь-

зованы соответственно для получения и установки векторов прерыва-

ний.

    Есть еще  несколько моментов,о которых необходимо упомянуть

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

товдля управляемогопрерываниями  ввода/вывода. Микропроцессор

80х86 автоматически делает невозможными все прерывания в то время

когдаон передает управление обслуживающей подпрограмме текущего

прерывания.Несмотря на то, что контроллер 8259A во время обслу-

живания прерывания задерживает последующие прерывания того же или

меньшего приоритета, прерывания старшего приоритета все еще полу-

чают подтверждение о приеме, если установлен флаг прерывания. Ес-

ли мы вновь немедленно не разрешим прерывание до начала  обслужи-

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

важные системные функции,передаваемые прерываниями(такие  как

системный таймер,клавиатура и контроллер диска),обслуживаться

не будут.Важно, поэтому, используя команду STI (установить флаг

прерывания)переключить прерывание как только обслуживающая под-

программа примет на себя управление. Это предоставит  возможность

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

обслуживания последовательногопорта,позволяя  функционировать

другим устройствам.

    Как мы сможем сообщить контроллеру 8259A о том, что обработка

последовательного прерывания завершена?Наша служебнаяподпрог-

рамма должна направить 8259A команду "конец прерывания" (EIO) пе-

ред возвращением управления центральному процессору.  Несмотря на

то,что существуют способы требования EIO для различных IRQ, для

схемы приоритета,используемой в персональном компьютере, доста-

точно направить контроллеру 8259A то,что известно как "неспеци-

фический" EOI (код 20h).Название "неспецифический" вытекаетиз

того,что эта команда не определяет, какое прерывание обслужива-

лось. Она просто говорит контроллеру, что обслуживание прерывания

высшего приоритета завершено. Это разрешает обслуживание прерыва-

ний того же или высшего IRQ.

               Программирование контроллера 8259A

    Управляемый прерываниями ввод/вывод требует правильнойуста-

новки контроллера 8259A.В противном случае, прерывания, генери-

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

ропроцессором80х86.  Таким образом,важно выяснить сначала то,

как мы можем программировать 8259A.

    Как  всяаппаратураперсонального  компьютера,контроллер

8259A программируется посредством двух имен  команд(регистров).

Онирасположены в адресах 20h и 21h порта ввода/вывода соответс-

твенно (рисунок 8-6). Регистр с адресом 21h используется исключи-

тельно для маскирования прерываний.Прерывание маскируется (т.е.

не принимается) в том случае,если бит,соответствующийсвоему

IRQ(считая справа налево,причем самому правому биту присвоено

значение IRQ0),установлен в логическую единицу.Порт по адресу

20hиспользуется  для направления команды прерывания контроллеру

8259A.Как мы отметили ранее, в системах MS-DOS это делается за-

писью 20h в этот порт.


                             Прерывание к CPU ───┐

                                                 |

┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┴─ ─ ─ ─ ─ ─ ┐

               ┌───┬───┬───┬───┬───┬───┬───┬───┐ конец

│    Порт 20h  |   |   |   ||   |   |   |   | прерывания   |

               └───┴───┴───┴───┴───┴───┴───┴───┘ EOI=20h

│                             └──── 20h                       |

   8259A                                          IRQ

│               ┌───┬───┬───┬───┬───┬───┬───┬───┐ 1=a.        |

                | 0 | 0 | 0 | 0 | 3.| 4.| 5.| 6.| 0=b.

│               └───┴───┴───┴─┬─┴─┬─┴───┴───┴───┘             |

Программируемый контроллер прерываний

└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ | ─ | ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘

                              |   |         ┐ Последовательные

                              |   └─── COM2:│ порты

                              └─────── COM1:│ персонального

                                            ┘ компьютера

a. - замаскировать прерывание; b. - разрешить прерывание;

      Рис.8-6. Программируемый контроллер прерываний 8259A

    В системах  MS-DOSпервомупоследовательномупорту  (COM1)

присвоен номер IRQ4 (прерывание номер 12),в то время как второй

(COM2) имеет IRQ3 (прерывание 11).Как указывалось ранее,порты

COM3 и COM4 могут обрабатываться таким жеобразом,предполагая,

чтоизвестны номера IRQ,присвоенные этим портам во время уста-

новки (только порты COM1 и COM2 имеют заранее  присвоенные номера

IRQ).Поэтому,  контроллер 8259A может быть запрограммирован для

получения прерываний от порта COM1 чтением с порта 21h и обратной

записью содержания, логически умноженного на EFh. Прерывания пор-

та COM1 могут быть замаскированы не только повторением предыдущих

действий, но логическим сложением с 10h, вместо логического умно-

жения.Таким образом, контроллер 8259A может быть запрограммиро-

вандля  разрешенияпрерыванийпорта COM1 с помощью следующего

фрагмента программы

IN     AL,21H       ;получить текущуюмаску прерывания

AND    AL,EFH       ;разрешить IRQ4

OUT    21H,AL       ;снова записать его обратно

    Когда прерыванияпорта  COM1 снова выключаются,8259A может

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

IN     AL,21H       ;получить текущую маску прерывания

OR     AL,10H       ;запретить IRQ4

OUT    21H,AL       ;снова записать его обратно

    Подобное программирование устройств,выполняемое считыванием

содержание регистра с последующей записью его обратно с соотвест-

вующе измененным битом, рекомендуется ввиду того, что мы не нару-

шаем предварительной установки битов.

    Кроме разрешенияи запрещения приема прерываний,контроллер

8259A должен быть проинформирован о завершении обработки обычного

прерывания.Как указывалось ранее,это выполняется направлением

20h в адрес 20h порта ввода/вывода следующим образом:

MOV      AL,20H    ;код конца прерывания

OUT      20H,AL    ;в порт 20Н контроллера 8259A

        Использование средств MS-DOS для программирования

                   последовательного порта

    Если Вы  знаете назначение каждого регистра последовательного

адаптера, программирование последовательного порта включает в се-

бя правильную установку регистров,разрешение прерываний и уста-

новку программы обработки прерываний.Мы уже рассказалиотом,

какпрограммироватьконтроллер  прерываний.Теперь мы готовы к

рассмотрению остальных деталей программирования последовательного

адаптера.

              Драйвер, TSR или автономная программа

    Существует несколько способов получения доступа кпоследова-

тельному адаптеру в системе MS-DOS.Вы можете управлять последо-

вательным портом через устанавливаемый драйвер устройства, выпол-

няющийввод/вывод через этот порт.В главе 6   "Устанавливаемые

драйверы устройств"   рассматриваютсядетали  разработкитакого

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

связанные с доступом к драйверу через DOS, а достоинством то, что

любаяпрограмма,  которая знает о Вашем драйвере,  может его ис-

пользовать.Если Вы выбрали этот способ,то можете обеспечить в

драйвере возможности IOCTL таким образом,что связные параметры,

такие как скорость передачи в бодах и длина слова, могут быть ус-

тановлены вызовами DOS IOCTL (номер функции DOS 44h).

    Вторым подходом является установка программы TSR (завершенная

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

вания BIOS RS-232C (14h) и расширяет свою функциональность  обес-

печением управляемого прерываниями ввода/вывода. Этот метод также

дает любой программе доступ к последовательному порту посредством

Вашегодрайвера  TSR в то время как Вы подтверждаете необходимые

установки регистра при использовании новых коммуникационных функ-

ций TSR.Механизм доступа будет таким же, как вызов функции BIOS

RS-232C, который мы вскоре опишем.

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

которая включает в себя служебную подпрограмму обработки прерыва-

нийпоследовательногопорта.  Вэтом случае,при запуске этой

прикладной программы,Вы можете установить обработчик прерываний

последовательногопорта  и сбросить его после прекращения работы

программы. Этот способ создает возможности организации высокоско-

ростного (9600 бод) последовательного ввода/вывода ввиду наличия

в нем меньшего количества недостатков по сравнению с двумя други-

ми методами.

    Независимо  от того,какой подходВы  выберите,управление

последовательным портом останется таким же.Далее мы уделим осо-

бое внимание деталям.

          Использование BIOS для последовательной связи

    Вы, вероятно, спросите, можно ли реализовать эффективный ввод

/вывод через BIOS. К сожалению, нет. BIOS не предоставляет эффек-

тивной возможностиуправления последовательнымадаптером.  Для

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

RS-232C, доступную через прерывание 14h. К сожаления, эта функция

поддерживаеттолько упорядоченный ввод/вывод,   который не очень

эффективен ввиду недостатков, изложенных ранее. Тем не менее, эта

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

порта, как скорость передачи в бодах, длина слова и стоповый бит,

использующий прерывание 14h BIOS.

   Установка коммуникационных параметров с использованием BIOS

    Даже при использовании в последовательномвводе/выводеBIOS

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

посмотреть,как коммуникационные параметры (скорость передачив

бодах, длина слова, четность и стоповые биты) могут быть установ-

лены с использованием функций BIOS RS-232C, доступных по прерыва-

нию 14h.

    Прерывание 14h с нулем в АН устанавливает параметрыпоследо-

вательного порта.Номер порта должен находиться в DX.Нуль в DX

указывает на порт COM1,в то время,как  единицауказываетна

COM2. Выбранные коммуникационные параметры направляются в регистр

AL в упакованном формате, показанном на рисунке 8-7. Скорость пе-

редачиопределяется  3-битовымзначением,четность - 2-битовым

значением,число стоповых битов - одним битом идлина  слова-

2-битовым значением. В таблице 8-2 показаны кодированные значения

каждого коммуникационного параметра. Учтите, что скорость переда-

чидрайверов  черезпортCOM в системе DOS 3.3 может достигать

19200 бод,в то время,  как ROM-BIOS ограничивается 9600 бодами.

Для достижения скорости передачи,не указанной в таблице 8-2, Вы

можете использовать возможность программирования скорости переда-

чиуниверсального асинхронного приемопередатчика,рассмотренную

ранее.


          Скорость                Длина

        ┌передачи в ┬Чет-сть┬ a.┬ слова ┐

        |  бодах    |       |   |       |

        ┌───┬───┬───┬───┬───┬───┬───┬───┐

        |   |   |   |   |   |   |   |   |

        └───┴───┴───┴───┴───┴───┴───┴───┘

Боды      Четность   Стоп-битыДлина слова

        ┌─────┬─────┐  ┌──┬──┐   ┌──┬──┐    ┌────┬────┐

        | 000 | 110 ||00|  |   |0 | 1|    | 10 | 7  |

        |─────|─────||──|b.|   |──|──|    |────|────|

        | 001 | 150 ||10|  |   |1 | 2|    | 11 | 8  |

        |─────|─────||──|──|   └──┴──┘    └────┴────┘

        | 010 | 300 ||01|c.|

        |─────|─────||──|──|

        | 011 | 600 ||11|d.|

        |─────|─────|└──┴──┘

        | 100 |1200 |

        |─────|─────|

        | 101 |2400 |

        |─────|─────|

        | 110 |9600 |

        |─────|─────|

        | 111 |     |

        └─────┴─────|

   a.- стоповые биты; b. - нет; c. - нечетность; d. - четность

Рис.8-7. Коммуникационные параметры,упакованные в одиночный

         байт в формате, требуемом прерыванием 14h BIOS


                                                Таблица 8-2

             Кодированные значения коммуникационных

                параметров для прерывания 14h

──────────────┬──────────────────────┬─────────────────────────

Имя параметра | Фактическое значение | Кодированное  значение

──────────────|──────────────────────|─────────────────────────

Скорость пе-|          110         |           0

редачи в бодах|          150         |           1

              |          300         |           2

              |          600         |           3

              |         1200         |           4

              |         2400         |           5

              |         4800         |           6

              |         9600         |           7

              |                      |

Четность      |           Нет        |        0 или 2

              |       Нечетность     |           1

              |        Четность      |           3

              |                      |

Стоповые биты |           1          |           0

              |           2          |           1

              |                      |

Длина слова   |           7          |           2

              |           8          |           3

──────────────┴──────────────────────┴─────────────────────────

    Подготовить упакованнуюформу  параметров просто.Например,

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

достичь результата следующим образом:

pckd_commparams = (baudrate << 5) | (parity <<3) |

                  (stopbits << 2) | (wordlength);

Мы использовалиоператоры сдвига бита и поразрядного логического

сложенияязыка  Си.Переменныеbaudrate,  parity,stopbitsи

wordlengthдолжны быть кодированными значениями коммуникационных

параметров из последней колонки таблицы 8-2. Как только параметры

примут такой формат, Вы можете вызывать BIOS прерыванием 14h. Ис-

пользование функции int86 компилятора MicrosoftС иллюстрируется

следующим фрагментом программы:

#include

#defineBIOS_RS232  0x14

                  /* номер прерывания для обслуживания BIOS */

static union REGS xr, yr;

    .

xr.h.ah = 0;        /* номер функции для вызова BIOS RS-232 */

xr.h.al = pckd_commparams;             /* связные параметры */

xr.x.dx = port_number;/* 0 означает COM1, 1 означает COM2 */

int86(BIOS_RS232, &xr, &yr);               /* сделать вызов */

    .

    Компилятор Microsoft C версии 5.0 облегчает вызов подпрограмм

BIOS: функция _bios_serialcomm служит интерфейсом между Вашей  Си

программой и прерыванием BIOS 14h.Например,если  Вывыберете

8-битовуюдлину  слова,1 стоповый бит,отсутствие проверки на

четность и скорость передачи 300 бод, то достаточно вызвать

_bios_serialcom(_COM_INIT, COM1, (_COM_CHR8 | _COM_STOP1 |

                                  _COM_NOPARITY | _COM_300) );

Вызов функции _bios_serialcom

status = _bios_serialcomm(service_code, port_number, data);

принимает три параметра,выраженных целым без знака и возвращает

кодсостояния  тогожетипа данных для демонстрации результата

требуемой операции.Параметр service_code используется для опре-

делениятребуемой  операциииport_number принимает значение 0

(COM1) или 1 (COM2).Значение data зависит от требуемойуслуги.

Подробности использования этой функции изложены в Microsoft C 5.0

Run-time Library Reference.

Получение адреса последовательного порта

    Другим полезным встроенным свойством BIOS является то, что на

этапе самотестирования при включении (POST) она проверяет наличие

последовательных адаптеров COM1/COM2 (хотя MS-DOS 3.3 поддержива-

ет порты COM3 и COM4, BIOS распознает только COM1 и COM2) и, если

находит тот или другой,адрес первого регистра каждогоадаптера

заноситсяв  областьпамяти,начиная со смещения нуля сегмента

14h.Так как в персональном компьютере 20-битовый физический ад-

рес равен 10h * 16-битовый сегмент + 16-битовое смещение,  и если

Ваша система MS-DOS имеет один последовательный порт, назначенный

как COM1, то тогда слово в физической ячейке 400h будет содержать

3F8h (если так же присутствует COM2, следующее слово в ячейке 402

h будет содержать 2F8h).Таким образом, Вы можете получить адрес

последовательного адаптера из этой области данных BIOS на  смеще-

нии 0 и сегменте 40h.Например,в Microsoft C Вы можете устано-

вить базовый адрес порта следующим образом:

#define BIOS_DATA ((short far *)(0x40000L))

static short comport,    /* для базового адреса порта */

       port_number;      /* 0 для COM1, 1 для COM2 */

   .

   .

   .

comport = *(BIOS_DATA + port_number);

if(comport == 0) /* последовательный адаптер не установлен */

{

    printf("Последовательный адаптер не установлен! ";

    exit(1);

}

    Так как инициализируется переменная comport,все другиере-

гистры последовательного адаптера могут быть доступны прибавлени-

ем соответствующих смещений к базовому адресу.  В языке Си Вы мо-

жетеиспользовать  директиву препроцессора #define для установки

адресов этих регистров.Например, если инициализируется comport,

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

порта по их именам, определив их следующим образом:

#define IER (comport + 1) /* регистр разрешения прерывания */

#define IIR (comport + 2) /* определение прерывания */

#define LCR (comport + 3) /* регистр управления линией */

#define MCR (comport + 4) /* регистр управления модемом */

#define LSR (comport + 5) /* регистр состояния линии */

#define MSR (comport + 6) /* регистр состояния модема */

     Настройка на управляемый прерываниями последовательный

                           ввод/вывод

    После получениябазового адреса порта из области данных BIOS

Вы должны настроить последовательный порт и установить обработчик

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

ного ввода/вывода.Номер прерывания и IRQ прерыванияпоследова-

тельного порта зависит от того, какой порт используется, COM1 или

COM2. Как только Вы получили номер прерывания, Вы должны получить

адрес текущего обработчика и сохранить его.Таким образом, после

выхода из программы Вы можете восстановить первоначальное  значе-

ние вектора прерываний. Функции MS-DOS 35h и 25h, соответственно,

получают и устанавливают обработчики для заданных номеров  преры-

ваний.Для  этойцелиMicrosoft C  предоставляетподпрограммы

_dos_getvect и _dos_setvect.Используя язык Си Вы можете проделать

это следующим образом:

short int_number;    /* номер прерывания для связного порта */

void interrupt far s_inthndlr(void);

                     /* установить обработчик */

static void(interrupt far *old_handler)()

                     /* место для прежнего */

    .

/* получить вектор прежнего прерывания и сохранить его */

    old_handler = _dos_getvect(int_number);

/* установить новый обработчик с именем s_inthndlr

* запретить прерывания во время замены обработчика

*/

    _disaple();

    _dos_setvect(int_number, s_inthndlr);

    _enable();

    В приведенном примере мы представили обработчиккакфункцию

типа interrupt,которая является новым ключевым словом, содержа-

щимся в Microsoft C 5.0.В следующем разделе продемонстрировано,

какимобразом  атрибут interrupt позволяет Вам писать обработчик

прерываний непосредственно в Microsoft C 5.0 (Turbo C  1.5имеет

такую же возможность).

    Следует обратить внимание на использование функций _disable и

_enable.Эти две функции соответствуют ассемблерным командам STI

и CLI.Таким образом,мы выключаем прерывания во время перехода

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

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

может привести к тому, что может произойти сбой центрального про-

цессора, так как вектор прерывания не являлся адресом какого-либо

действующего обработчика.

    После того,  как обработчик прерываний займет свое место,Вы

можете установить коммуникационные параметры и разрешить последо-

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

шить распознавание этих прерываний контроллером 8259A. Еще раз Вы

должны запретить прерывания до тех пор,пока порт и 8259A не бу-

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

Microsoft C 5.0.

/* разрешает маску, зависящую от порта */

short intmask,int_enable_mask;

    .

    .

    .

/* включает прерывания коммуникационного порта.

* устанавливает 8259A

*/

    _disable();

/* устанавливает регистр управления модемом (порт =MCR) */

    outp(MCR, MCRALL);

/* разрешает все прерывания последовательной платы

* (порт = IER)

*/

    outp(IER, IERALL);

/* считывает регистр маски прерывания 8259A и записывает его

* обратно после логического умножения с _int_enable_mask

*/

    intmask = inp(P8259_1) & int_enable_mask;

    outp(P8259_1, intmask);

    _enable();

    С этой точки зрения последовательный порт начнетработатьв

управляемом прерываниями режиме.Происходящие события зависят от

обработчика прерываний, который мы сейчас рассмотрим.

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

    Наш обработчик, s_inthndlr, будет вызван при генерации после-

довательным портом прерывания.Мыдолжны  немедленноразрешить

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

приоритетные задачи (такие как таймер) могли обрабатываться  мик-

ропроцессором.

    Следующий шаг - идентификация точной причины, вызвавшей гене-

рацию прерывания последовательного порта.Для получения информа-

ции Вы должны считать содержание регистра идентификации  прерыва-

ния(IIR).  Кактолькоопределится  причина прерывания,можно

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

универсальному асинхронному приемопередатчику.

    Так как последовательный порт способен генерироватьпрерыва-

ние в то время,пока Вы обрабатываете другое,необходимо прове-

рять бит 0 (последний значащий бит) IIR на это условие. Если этот

бит равен нулю,то имеется другое прерывание и его следует обра-

ботать.С другой стороны, если значение бита равно единице, оче-

редные прерывания отсутствуют.В этом случае Вы должны направить

контроллеру 8259A сигнал "конец прерывания" и выйти из обработчи-

ка.Таким  образом,обработчикпредставляет  собой бесконечный

цикл, который продолжает обрабатывать последовательные прерывания

до тех пор, пока не прекратится их поступление. В Microsoft C 5.0

обработчик может быть реализован как

void interrupt far s_inthndlr(void)

{

    int c;

    register int int_id, intmask;

/* прерывания разрешаются немедленно */

    _enable();

    while (TRUE)

    {

/* чтение регистра идентификации прерываний, IRR */

         int_id = inp(IRR);

         if (bit0(int_id) == 1)

         {

/* если бит 0 равен 1, тогда прерывания не поступают. послать

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

* прерываний 8259A и затем вернуться.

*/

             outp(P8259_0, END_OF_INT);

             return;

         }

/* если есть прерывание получения данных, разрешить прерывания

* для "свободен регистр хранения передачи"

*/

         if (int_id) >= RXDATAREADY)

                           turnon_int(THEREINT,intmask);

/* обработать прерывание в соответствии с идентификатором.

* Следующий список составлен согласно возрастанию приоритета.

*/

        switch (int_id)

        {

           case MDMSTATUS:/* состояние готовности модема */

                              .

                             break;

           case TXREGEMPTY:/* послать символ */

                              .

                             break;

           case RXDATAREADY: /* читать символ */

                              .

                             break;

           case RLINESTATUS: /* читать состояние линии */

                              .

                             break;

/* пропустить, если идентификатор не является одним из

* перечисленных */

        }

    }

}

    Обратите внимание,что мы  воспользовалисьключевымсловом

interrupt,имеющемсяв Microsoft C 5.0 и позволяющем писать обра-

ботчик на языке Си.Это ключевое слово используется как специфи-

катор функции,которую Вы желаете установить в качестве обработ-

чика прерываний определенного номера прерывания.  Притрансляции

функциис атрибутом interrupt компилятор генерирует код для пер-

воначального помещения в стек регистров AX,CX,DX, BX, SP, BP,

SP,SI,  DI,DS и ES. Затем он устанавливает регистр DS в режим

ссылки на сегмент данных указанной функции.После этой начальной

последовательностиследует код функции.В заключении компилятор

использует команду IRET вместо обычной команды RET для  выхода из

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

бута interrupt.В компиляторе Turbo C также имеется это ключевое

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

    Когда Вы пишете обработчик прерываний на языке Си, то необхо-

димо соблюдать такие же предосторожности, как и при написании об-

работчиков на языке ассемблера.Например, Вы не должны использо-

вать какую-либо библиотечную подпрограмму, вызывающую функцию DOS

(доступ к ним осуществляется посредством команды прерывания 21h).

Такимифункциями  вязыке Си являются подпрограммы ввода/вывода

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

подпрограмм   манипулирования   строками,   хранятся   вфункции

interrupt.

                 Очереди обработчика прерываний

    Целью обработчика прерываний последовательного порта является

скорейшее сохранение поступающих символов.  Наилучшим образом это

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

восстанавливать из этого буфера символы сосвоейскоростью,  не

беспокоясь о потере какого-либо символа,потому что она работает

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

обработчику прерываний через другой буфер.

    Каждый из этих буферов должен вести себя каклинияпроверки

регистра.Символы  поступают в линию один за другим и программа,

считывающая символы,принимает первый из них и обрабатывает его,

затем принимает следующий и так далее. Буфер такого типа известен

как "первый пришел - первый вышел" (FIFO) буфер.  Это также назы-

вается очередью.

    На рисунке 8-8 показанаконцептуальнаяреализация  очереди.

Очередь, естественно, имеет начало и конец. В реальной реализации

размер очереди,т.е.максимального числа символов,которое она

может содержать,фиксировано. Удобно считать ячейки памяти, свя-

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

ячейку,мы возвращаемся к первой. Это делает эффективным исполь-

зование ограниченного пространства, доступного для очереди. Такая

реализация очереди называется циклической.

        ┌───┬───┬───┬───┬───┬───┐

        |   |   |   |   |   |   |

        |───|───┴───┴───┴───|───|

        |   |               |   |

        |───|               |───|

        |   |Задние   Первые|   |

        |───|───┐       ┌───|───|

        |   |   │─┐   ┌─|   |   |

        └───┴───┘ |   | └───┴───┘

                ^ |   | v

              Вход    Выход

Рис.8-8. Циклический буфер FIFO (очередь)

                 Уборка перед закрытием магазина

  После того, как Ваша прикладная программа перестает нуждаться

в дальнейшем последовательном вводе/выводе,  необходимо восстано-

вить порт в его обычное состояние. Восстановление включает в себя

установкувсех битов регистра разрешения прерываний порта в ноль

и выключение всех сигналов управления модемом.Затемконтроллер

8259Aдолжен быть запрограммирован для прекращения приема преры-

ваний последовательного порта.В заключение,векторпоследова-

тельного прерывания необходимо сбросить в начальное значение, ко-

торое было сохранено при инициализации ввода/вывода.  Вот как это

реализуется в Microsoft C 5.0:

    int intmask;

    .

    .

    .

/* Запретить прерывания на время очистки */

    _disable();

/* Сначала сбросить регистр разрешения прерываний порта */

    outp(IER,IEROFF);

/* Выключить все биты регистра управления модемом */

    outp(MCR,MCROFF);

/* Затем запретить распознавание контроллером 8259A прерываний

   последовательного порта */

    intmask = inp(P8259_1) | int_disable_mask;

    outp(P8259_1, intmask);

/* Восстановить первоначальный вектор прерываний */

    _dos_setvect(int_number, old_handler);

/* Снова разрешить прерывания */

    _enable();

                        Пример программы

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

ли, какие действия необходимо выполнить дляпрограммирования порта

в целях организации эффективного  управляемогопрерываниями вво-

да/вывода.Осталось только объединить отдельные части, для того,

чтобы показать, каким образом создается завершенная коммуникацион

наяпрограмма.  Мыделаемэто в листинге 8-1, который содержит

основную коммуникационную программу,написанную наMicrosoftC

версии 5.0.

   Листинг 8-1. Коммуникационная программа на Microsoft C 5.0

                       Заключение

    В этой  главерассмотреныхарактеристики аппаратных средств

последовательного порта в системах MS-DOS и  представленыметоды

его программирования. Также содержится небольшая коммуникационная

программа,написанная на Microsoft C 5.0, для иллюстрации реали-

зации этих методов на практике. Программирование последовательно-

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

следующим образом:

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

       из области данных BIOS на сегменте 40h и со смещением 0.

    2. Используя функцию MS-DOS 35h,получить адрес старойпод-

       программы обслуживания прерывания дляномерапрерывания,

       соответствующего данному адаптеру, и сохранить его.

    3. Используя функцию MS-DOS 25h, установить для номера преры-

       вания  Вашу собственную подпрограмму обслуживания прерыва-

       ния.

    4. С  использованием функции BIOS 14h установить коммуникаци-

       онные параметры адаптера.

    5. Установить очереди приема и передачи для содержания входя-

       щих и исходящих символов.

    6. Включить в регистре управления модемом необходимые сигналы

       (например,DTR - терминал готов и RTS - запрос на переда-

       чу).

    7. Разрешить все прерывания адаптера (установкой битов с 0 по

       3 в регистре разрешения прерывания в 1).

    8. Так же включить бит OUT2 в регистре управления модемом для

       разрешения прерываний последовательного адаптера.

    9. Запрограммировать контроллер 8259A для распознаванияпре-

       рываний с IRQ этого адаптера (путем установки соответству-

       ющего бита регистра маски прерывания, доступного через ад-

       рес порта 21h, в 0).

    При выполнениинекоторых операций,если пользователь решает

прервать сеанс работы,должна быть вызвана подпрограмма"очист-

ки". Очистка выполняется следующим образом:

    1. Выключить прерывания последовательного адаптера.

    2. Сбросить биты регистра управления модемом.

    3. Восстановить старую подпрограмму обработки прерывания.

    4. Замаскировать прерывания для этого IRQ в 8259A.