Программирование игр для Windows. Советы профессионала

       

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


Вот шаги, которым мы должны следовать:

§

Сначала нужно установить номера передаваемых битов, количество стоп битов и тип четности. Это делается с помощью регистра управления линии (LCR);                                             

§          Затем устанавливается скорость передачи загрузкой старшего и младшего байта делителя;

§          Далее нужно инициализировать UART для управления прерываниями;

§          Мы должны сообщить программируемому контроллеру прерываний ПК (PIC), какие прерывания по последовательному порту он должен допускать;

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

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

Работа с делителем немного запутана. Вы знаете, что регистры 0 и 1 выполняют дополнительные функции загрузки двухбайтного делителя, деление на который числа 115200 дает результат, используемый UART как окончательная скорость передачи. Однако, как мы знаем, регистры 0 и 1 являются соответственно регистром поддержки передачи (THR) и регистром прерывания (IER). Когда бит 7 регистра управления линией установлен в 1, они получают номера 8 и 9, но продолжают адресоваться как 0 и 1. Ясно?

В качестве примера, давайте установим скорость передачи в 9600 бод. Мы могли бы найти число, которое при делении на него значения 115200 давало бы 9600. Это число 12. Далее мы должны запихнуть его в младший и старший байты. В этом случае младший байт будет равен 12, а старший - 0.


Далее нужно установить бит 7 (DLAB) регистра управления линией в 1 и записать младший байт в регистр 0, а старший - в регистр 1, через которые переданные байты и попадут в регистры 8 и 9. После этого необходимо очистить бит 7 (DLAB) регистра управления линии. Это было бы не так уж и плохо, а?

Затем мы инициализируем UART для приема прерываний. Немного поговорим об этом. Когда UART принимает данные, символ будет оставаться в буфере приема только до тех пор, пока не прибудет следующий, после чего вновь пришедший символ заместит старый, независимо от того, был ли он считан. Мы не можем этого допустить, иначе потеряем информацию. Существует два решения этой проблемы:

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

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



Если вы помните, в двенадцатой главе, "Мнимое время, прерывания и мультизадачность", говорилось, что в Си несложно установить новое прерывание, используя ключевое слово _interrupt. Мы напишем процедуру, которая будет активизироваться всякий раз с приходом прерывания. Но как нам сообщить UART, что прерывание обнаружено? Если вы пристально посмотрите на описание регистров, то поймете, что вам необходимо установить бит здесь бит там, и UART будет делать свою работу. Чтобы назначить прерывания, мы должны установить следующие биты в UART:

• Бит 0 (RxRDY) регистра прерывания (IER) должен быть установлен в 1;

• Бит 3 (GP02) регистра управления модемом (MCR) должен быть установлен в 1.

После этого мы уже готовы принимать прерывания, правильно? Ошибаетесь! Нужно сделать еще одну вещь. Мы должны сообщить программируемому контроллеру прерываний (PIC), какие именно прерывания по последовательному порту он должен задействовать. Чтобы выполнить это, необходимо изменить установки в регистре маски прерывания (IMP) PIC'a, который доступен через порт 21h.Таблица 14.3 показывает обозначение битов IMR.

Таблица 14.3. Регистр маски прерывания (IMR) PIC'a.

Бит 0: IRQ0 - используется для таймера

Бит 1: IRQ1 - используется для клавиатуры

Бит 2: IRQ2 – зарезервирован

Бит 3: IRQ3 - COM2 или COM4

Бит 4: IRQ4 - СОМ1 или COM3

Бит 5: IRQ5 - жесткий диск

Бит 6: IRQ6 - гибкий диск

Бит 7: IRQ7 - принтер

Таким образом, последняя вещь, которую нам необходимо сделать для обработки прерываний и запуска - активировать нужное прерывание по биту 3 или 4. Но будьте осторожны! Регистр инвертирован, так что 0 означает включен, а 1 — выключен.

Осторожно

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


Содержание раздела