Сведения для программирования

 

Программирование последовательного порта IBM-совместимого персонального компьютера /ПК/ возможно различными способами. Ниже рассмотрен наиболее простой способ с использованием программного прерывания BIOS.

Суть использования программного прерывания в данном случае заключается в том, что в состав базовой системы ввода-вывода /Base Input-Output System, сокращенно BIOS/ входит большое количество специализированных программ, предназначенных для работы с аппаратной частью ПК. Вызвать требуемую программу можно, если выполнить программное прерывание с заранее известным номером. Передать параметры вызываемой программе можно через регистры процессора. Какое прерывание надо вызвать для выполнения той или иной функции при работе с аппаратурой ПК, какие параметры надо этой функции передать и в какие регистры их поместить – все это стандартизованные сведения, описанные в руководствах и справочниках. Логически, оказалось удобно назначить одному номеру прерывания несколько функций, различая их по номерам. Так и говорят: «Первая функция четырнадцатого прерывания».

Для программирования последовательного порта, точнее, для программирования контроллера последовательного порта, используют прерывание 14h (Внимание! 14h –шестнадцатиричная величина, а не обычное десятичное число.). При использовании 14h прерывания доступны четыре функции, из которых мы будем использовать три. А именно:

0 – нулевая – инициализация последовательного порта

1 – передача байта через последовательный порт

2 – прием байта из последовательного порта

 

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

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

Скорость передачи

Как обращаться с признаком четности

Количество стоповых бит в информационной посылке

Количество информационных бит в информационной посылке.

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

 

Таблица 1

Разряд, разряды

За что отвечает

Пример

5,6,7

Скорость обмена данными

111 – 9600 бод

3,4

Как учитывать и учитывать-ли вообще признак четности

00 – не учитывать

2

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

0 – один стоповый бит в информационной посылке

0,1

Количество информационных бит

11 – восемь информационных бит

 

Таким образом, если нам необходимо установить режим работы последовательного порта такой: максимальная скорость передачи 9600 бод, без учета признака четности, с одним стоповым и восемью информационными битами в информационной посылке, константа инициализации, которую надо записать в регистр AL процессора будет равна 11100011 или E316. Следует понимать, что для правильного приема и преобразования информации, принятой по последовательному каналу, передающий и принимающий контроллеры должны быть настроены одинаковым образом. В случае соединения между собой ПК, как в предлагаемой лабораторной работе необходимо при инициализации записать одну и ту же константу в регистр AL на каждом ПК.  

Какие еще регистры используют при инициализации контроллера последовательного порта? AH и DX.

В регистр AH записывают номер функции, в данном случае, для функции инициалиизации 0.

В регистр DX записывают номер порта. Как правило, на ПК имеется несколько последовательных портов, обозначаемых COM1, COM2 и т.п. Для того, чтобы указать, что мы инициализируем порт COM1, надо записать в регистр DX 0, для инициализации COM2 – 1. Надо отметить, что можно по-разному настроить разные порты одного и того же ПК.

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

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

AH=0

AL= E316

DX=1

Int 14h

 

Как это написать на Pascal?

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

 

Uses DOS;

Var

         R: registers;

Begin

         R.AH:=0;

         R.AL:=$E3;

         R.DX:=1;

         Intr($14,R);

 Примечания:

  1. Регистр символов не важен
  2. Переменная R может быть названа не только R, но и как угодно по правилам указания имен переменным в языке Pascal.
  3. Функция Intr($14,R) на языке Pascal означает вызов прерывания с номером 1416 и переменной, описывающей регистры R
  4. Другие переменные, операторы и элементы программы, непосредственно не имеющие отношения к вызову указанного прерывания, не указаны, что, однако, не означает, что их не должно или не может быть в вашей конкретной программе.

  

Передача байта.

Передаче байта через последовательный порт соответствует функция 1.

Передаваемый байт должен быть записан в регистр AL.

Через какой именно порт COM1 или COM2, будет происходить передача байта, необходимо указать в регистре DX.

Это означает, что на псевдоассемблере эта передача байта 100 через COM2 будет выглядеть так:

AH=1

AL= 100

DX=1

Int 14h

 

Прием байта

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

Принятый байт будет сохранен в регистре AL.

Из какого именно порта COM1 или COM2 будет происходить прием байта, необходимо указать в регистре DX. Есть особенность при программировании приема байта из последовательного порта. Мы не знаем, передан ли уже байт с другого ПК к моменту нашего обращения к функции приема на данном ПК или нет. Ведь ПК работают асинхронно. Для этого предусмотрен анализ состояния контроллера последовательного порта после выполнения функции приема байта. А именно: если байт был успешно принят, то после выполнения прерывания в регистре AH будет записан 0. Если байт был принят с ошибками или совсем не принят, то в различных разрядах байта регистра AH будут установлены единицы, характеризующие, что именно было не так при приеме байта. В нашу задачу не входит детальный анализ кода состояния контроллера после приема байта, поэтому будем просто проверять 0 в регистре AH или не 0. Если после выполнения прерывания при приеме байта в регистре AH 0, то можно считать, что байт, который записан в регистр AL, принят правильно.

На псевдоассемблере прием байта из COM2 будет выглядеть так:

AH=2

DX=1

Int 14h

Если AH=0, использовать, например вывести на экран, байт AL

Иначе – повторить прием.