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

Аппаратное обеспечение IBM PC

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

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

2.2. Порты для работы с клавиатурой

Для работы с клавиатурой типа PC/XT используются порты с адресами 60h и 61h.

Порт 60h при чтении содержит скан-код последней нажатой клавиши.

Порт 61h управляет не только клавиатурой, но и другими устройствами компьютера, например, работой встроенного динамика. Этот порт доступен как для чтения, так и для записи. Для нас важен самый старший бит этого порта. Если в старший бит порта 61h записать значение 1, клавиатура будет заблокирована, если 0 - разблокирована.

Так как порт 61h управляет не только клавиатурой, при изменении содержимого старшего бита необходимо сохранить состояние остальных битов этого порта. Для этого можно сначала выполнить чтение содержимого порта в регистр, изменить состояние старшего бита, затем выполнить запись нового значения в порт:

          .........

        in      al, 61h
        or      al, 80h
        out     61h, al

          .........


Компьютер типа IBM AT позволяет управлять скоростными характеристиками клавиатуры, а также зажигать или гасить светодиоды на лицевой панели клавиатуры - Scroll Lock, Num Lock, Caps Lock.

Для расширенного управления клавиатурой используется порт 60h в режиме записи. Этот порт используются для управления подчиненным процессором Intel 8042, ответственным за обмен данными с клавиатурным компьютером.

При использовании порта 60h на запись программа дополнительно получает следующие возможности:

  •  установка времени ожидания перед переходом клавиатуры в режим автоповтора;
  •  установка периода генерации скан-кода в режиме автоповтора;
  •  управление светодиодами, расположенными на лицевой панели клавиатуры - Scroll Lock, Num Lock, Caps Lock.

Процессор 8042 обслуживает не только клавиатуру, но и другие системы компьютера. Через порт 64h, например, выполняется сброс (отключение) процессора 80286 для возврата из защищенного режима работы в реальный.

Для посылки команды процессору 8042 вначале необходимо убедиться в том, что его внутренняя очередь команд пуста. Это можно сделать, прочитав слово состояния 8042 из порта с адресом 64h. Бит с номером 1 должен быть равен нулю.

Приведем фрагмент программы, составленной на языке ассемблера, проверяющий состояние очереди команд процессора 8042:

                ..........

        mov     cx,0               ; счетчик для ограничения времени
                                                ; ожидания готовности 8042

wait_loop:

; читаем порт состояния процессора 8042

        in      al,64h 
        and     al,00000010b  ; флаг готовности

; ожидаем готовность процессора 8042

        loopnz  wait_loop
                                                ; к приему команды
                ..........



После того, как программа дождется готовности процессора 8042, она может послать ему команду, записав ее в порт с адресом 60h:

                ..........

        mov     al,cmd             ; команда для 8042
        out     60h ,al            ; вывод команды в 8042

                ..........


Некоторые команды состоят более чем из одного байта. Остальные байты команды необходимо записать в порт 60h, предварительно убедившись в готовности процессора 8042 с помощью последовательности команд, приведенной выше. В большинстве случаев можно также использовать простую временную задержку:

                ..........

        mov     al, cmd_byte1
        out     60h, al

        mov     cx, 2000h

wait_loop: loop wait_loop

        mov     al, cmd_byte2
        out     60h, al
                ..........


Мы приведем формат двух команд процессора 8042, имеющих отношение к работе с клавиатурой - команду установки задержки и периода автоповтора и команду управления светодиодами, расположенными на клавиатуре.

Для установки характеристик режима автоповтора в порт 60h необходимо записать код команды 0F3h, затем байт, определяющий характеристики режима:

Биты    Значение


0-4     Период автоповтора:

           0 - 30.0;       0Ah - 10.0;
           1 - 26.7;       0Dh -  9.2;
           2 - 24.0;       10h -  7.5;
           4 - 20.0; 14h -  5.0;
           8 - 15.0;       1Fh -  2.0.
                        
        Период автоповтора определяет количество
        посылок скан-кода, генерируемых процессором
        клавиатуры в одну секунду. Можно использовать не
        только те значения, которые приведены выше,
        но и промежуточные, например, 9 или 15h.

5-6     Задержка включения режима автоповтора:

            00 - 250 мс;
            01 - 500 мс;
            10 - 750 мс;
            11 - 1000 мс.

7       Зарезервировано, должно быть равно 0.


Первоначально при инициализации системы период задержки для включения режима автоповтора устанавливается модулями BIOS равным 500 мс при периоде автоповтора, равном 10 повторам в секунду. Если это слишком медленно для вас, вы можете установить другие значения. Некоторые прикладные программы, например, текстовый процессор Microsoft Word, содержат средства для управления временными характеристиками клавиатуры.

Для управления светодиодами, расположенными на лицевой панели клавиатуры, используйте команду 0EDh. Вслед за этой командой в порт 60h необходимо записать байт, имеющий следующий формат:

Биты    Значение


0       1 - включить светодиод Scroll Lock;

1       1 - включить светодиод Num Lock;

2       1 - включить светодиод Caps Lock;

3-7     не используются.


Приведем пример простейшей программы, управляющей светодиодами на лицевой панели компьютера. Такое управление может выполняться только при использовании порта 60h управления клавиатурой, так как BIOS не содержит соответствующей поддержки. Наша программа после запуска включит все светодиоды и будет ожидать нажатия на любую клавишу. После нажатия программа выключит светодиоды.

#include <stdio.h>

void main(void);

void main(void) {

        int i;

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

        outp(0x60,0xed);

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

        for(i=0; i<4000; i++);

// Выводим второй байт команды,
// младшие три бита которого определяют
// состояние светодиодов на лицевой панели
// клавиатуры.

        outp(0x60,7);

// Ожидаем нажатия на любую клавишу.

        getch();

// Выключаем все светодиоды.

        outp(0x60,0xed);
        for(i=0; i<4000; i++);
        outp(0x60,0);

        exit(0);
}


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