Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Системное программирование.doc
Скачиваний:
178
Добавлен:
19.03.2015
Размер:
1.96 Mб
Скачать

13.6. Упражнения

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

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

MOVAX, 40h

MOVES,AX; регистрESуказывает на область данныхBIOS

MOVDX,ES:[00] ; читаем базовый адрес порта COM1

ADDDX, 3 ; адрес регистра управления

MOVAL, 80h ; установка бита DLAB для доступа регистру делителя

OUTDX,AL

DECDX

DECDX; адрес старшего байта делителя скорости

MOV AL, 12h

OUT DX, AL

DECDX; адрес младшего байта делителя скорости

MOVAL, 0Ch ; установка младшего байта делителя

OUTDX,AL

ADDDX, 3 ; адрес регистра управления

MOVAL, 00011011b ; DLAB=0, четность, 1 стоп-бит, 8 бит/слово

OUTDX,AL

DECDX

DECDX; адрес регистра разрешения прерываний

MOVAL, 00h ; прерывания запрещены

OUTDX,AL

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

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

Регистр статуса постоянно проверяется до тех пор, пока бит 5 не станет равным 1. После этого в регистр хранения передатчика может быть передан очередной байт данных. В процессе передачи бит 5 равен 0, и когда он опять станет равным 1, в регистр хранения передатчика может быть передан следующий символ.

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

MOVDX, COM1 ; помещаем базовый адрес порта в регистр DX

ADDDX, 5 ; адрес регистра состояния

wait: ; метка ожидания окончания приема

INAL,DX; чтение байта состояния

TESTAL, 01h ; бит 1 = «1» (принят байт)

JZwait; нет - ждем

SUBDX, 5 ; адрес регистра приемника

INAL,DX; чтение принятого байта в регистр DX

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

; передача байта из AH без контроля готовности приемника

MOVDX, COM1 ; помещаем базовый адрес порта COM1 в регистр DX

ADDDX, 5 ; адрес регистра состояния

wait: ; метка ожидания окончания передачи

INAL,DX; чтение байта состояния

TESTAL, 40h ; бит 6 = «1» (готовность к передаче очередного байта)

JZwait ; нет - ждем

SUBDX, 5 ; адрес регистра передатчика

MOVAL,AH; помещаем передаваемый байт в регистр AL

OUTDX,AL; передача данных

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

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

; установка нового вектора прерывания

MOVDX,OFFSETIOINT

MOVAX,SEGIOINT

MOVDS,AX; параDS:DXуказывает на обработчик прерываний

MOVAL, 0Ch ; номер вектора прерывания для портаCOM1

MOVAH, 25h ; функция изменения вектора

INT21h ; изменение вектора прерывания

; инициализация регистра разрешения прерывания

MOVDX, COM1 ; помещаем адрес порта COM1 в регистр DX

INCDX; адрес регистра разрешения прерываний

MOVAL, 11b ; разрешаем прерывания приема и передачи

OUTDX,AL

Второе действие состоит в реализации подпрограммы обработки прерывания. Для порта COM1 номер прерывания равен 0Bh. Алгоритм обработчика этого прерывания показан на рис. 50. При наступлении прерывания читается регистр идентификации IIR и по его разрядам IID0 и IID1 определяется тип прерывания. Если прерывание вызвано поступлением данных, происходит переход на подпрограмму принятия данных, в противном случае – на подпрограмму передачи.

Затем проверяется разряд INP на наличие отложенных прерываний. Если они существуют, вновь следует определить тип прерывания. В отсутствии новых прерываний выполняется разрешение прерываний с более низким уровнем и завершается обработка прерывания 0Bh.

Ниже представлена дословная реализация описанного алгоритма.

; процедура обработки прерывания

IOINTPROCFAR

MOVDX, COM1 ; помещаем адрес порта COM1 в регистр DX

INCDX; указываем на регистр идентификации прерывания

INCDX

INAL,DX; читаем значение регистра идентификации прерывания

nextint:

TESTAL, 10b ; тип прерывания «получены данные»

JNZsendata; переход на передачу символа, если флаг нуля установлен

getdata: ; метка начала приема данных

... ; реализация алгоритма приема данных

JMPSHORTnewio; переход на проверку наличия нового прерывания

sendata: ; метка начала передачи данных

... ; реализация алгоритма передачи данных

; перед выходом проверка на наличие нового прерывания

newio: ; метка начала проверки поступления нового прерывания

MOVDX, COM1 ; помещаем адрес порта COM1 в регистр DX

INCDX; указываем на регистр идентификации прерывания

INCDX

INAL,DX; читаем значение регистра идентификации прерывания

TESTAL, 1 ; проверка бита 1

JNZnextint ; переход по метке nextint, если флаг нуля установлен

MOVAL, 20h ; иначе передаем код завершения аппаратного прерывания

OUT20h,AL

IRET; возврат из процедуры обработки прерывания

IOINTENDP; завершение процедуры обработки прерывания

Рис. 50. Алгоритм обработки прерывания 0Bh.

Пример 4. Используя встроенный в среду Borland® Delphi ассемблер разработать подпрограмму эмуляции последовательного порта при помощи параллельного. Подпрограмма должна выполнять передачу байтовых данных. Активным уровнем считать лог. 0. Временные параметры считать задаваемыми через глобальные переменные.

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

Алгоритм последовательной передачи с использованием параллельного порта показан на рис. 51. Данные передаются по линии D0, а синхросигнал – по линии D1. Разряды байта передаются последовательно, начиная с самого старшего. Операции маскирования задают последовательное изменение разряда D1 в порядке 1-0-1 и совместно с очередным разрядом передаваемого байта данных выводятся в порт. Временные задержки определяют скорость передачи данных и задаются глобально через параметр DLY. Базовый адрес порта хранится в переменной LPT.

Рис. 51. Алгоритм последовательной передачи байта данных через параллельный порт.

Пример процедуры синхронной передачи байта приведен ниже.

procedure SendByte(b: Byte);

begin

asm

{ Передаваемый байт }

MOVBL,b

{ Инверсия разрядов байта }

NOTBL

{ В DX базовый адрес порта LPT }

MOVDX, LPT

{ Счетчик для передачи 8 бит из BL }

MOVCX, 8

{ Сдвиг влево; в флаге CF старший бит }

@@L1:SHL BL, 1

MOV AL, 1

JC@@L2

{ Если передаваемый бит = 0, то AL=0 иначе AL=1 }

MOVAL, 0

{ D0=передаваемый бит, D1=CLK=1 }

@@L2:OR AL, 2

OUT DX, AL

{ D0=передаваемый бит, D1=CLK=0 }

AND AL, 0FDh

OUT DX, AL

{ Временная задержка }

PUSHCX

MOVCX,DLY

@@L3:LOOP@@L3

POPCX

{ D0=передаваемый бит,D1=CLK=1 }

ORAL, 2

OUTDX,al

{ Временная задержка }

PUSH CX

MOV CX, DLY

@@L4:LOOP @@L4

POPCX

{ Повторять 8 раз }

LOOP@L1

end;

end;