Методические указания к выполнению работы. к п. 1. см методические указания к п.1 лабораторной работы №1.

      Комментарии к записи Методические указания к выполнению работы. к п. 1. см методические указания к п.1 лабораторной работы №1. отключены

К п. 1. См методические указания к п.1 лабораторной работы №1.

К п.2. Работой клавиатуры в IBM PC управляет специализированный микропроцессор — контроллер клавиатуры, который воспринимает каждое нажатие и отжатие клавиш и выдает скан-код клавиши в порт контроллера клавиатуры с адресом 60Н.

рисунок

Скан-код клавиши это однобайтное число, младшие 7 бит которого являются идентификационным номером, присвоенным каждой клавише (табл. 9). Старший бит (бит 7) является признаком нажатия (бит равен 0) или освобождения (бит равен 1) клавиши. Таким образом, каждая клавиша генерирует два типа скан-кодов: “код нажатия” и “код освобождения”, когда клавиша отпускается. Код освобождения на 128 больше кода нажатия клавиши.

После поступления скан-кода в порт 60Н формируется сигнал запроса прерывания процессору для обработки нажатия клавиши. Процессор прерывает на время свою работу и переходит на п/пр обслуживания прерывания от клавиатуры (09Н), которая выполняет следующие функции:

  • считывает скан-код клавиши из порта 60Н;
  • анализирует состояние слова статуса клавиатуры (при нажатии клавиш статуса изменяет это слово) и осуществляет трансляцию скан-кода нажатой клавиши в коды ASCII, формируя 2-х байтовый код;
  • записывает полученный 2-х байтовый код в буфер клавиатуры.

<p>табл. 9

Скан-код Клавиша Скан-код Клавиша Скан-код Клавиша Скан-код Клавиша
Esc Enter RightShift ScrollLock
2-11 ‘1’¸‘9’,’0’ Ctrl PrtScr 71¸73 ‘7’¸’9’
‘–‘ 30¸40 ‘A’¸’’’ Alt ‘–‘
‘=’ ‘`’ ‘ ‘ 75¸77 ‘4’¸’6’
Backspace LeftShift CapsLock ‘+’
Tab ‘\’ 59¸68 F1¸F10 79¸82 ‘1’¸’3’,’0’
16¸27 ‘Q’¸‘]’ 44¸53 ‘Z’¸’/’ NumLock ‘.’

Поскольку скан-коды клавиш считываются из порта 60Н п/пр обслуживания прерываний от клавиатуры, то для выполнения задания к лабораторной работе можно рекомендовать следующую последовательность действий:

  • запретить прерывания от клавиатуры;
  • считать содержимое порта 60H после нажатия клавиши;
  • считать содержимое порта 60H после отпускания клавиши;
  • разрешить прерывания от клавиатуры;
  • вывести полученные скан-коды на экран.

В языке Pascal для прямого обращения к содержимому портов ввода/вывода предварительно объявлены массивы Port и PortW. Элементами массива Port являются значения типа Byte, а массива PotrW – типа Word. Индексами этих массивов должны быть выражения типа Byte, которые указывают абсолютный адрес порта, например:

State := Port [$80]; { считать из порта 80Н в переменную State}

Port [$90] := State+1; { записать в порт 90Н новое значение }

Фрагмент программы чтения скан-кодов клавиш:

Uses crt, dos;

Var ScanCodeDown, ScanCodeUp,Scan :byte;

Begin

……..

Delay(1000); { задержка времени для отработки отжатия клавиши }

{ при выборе пункта меню }

Port [$21]:=2; { запретить ПКП прерывания от клавиатуры }

Scan:=Port [$60]; { считать текущее содержимого порта клавиатуры }

Writeln(‘Нажмите заданную клавишу’);

Repeat

ScanCodeDown:=Port [$60]; { считать содержимое клавиатуры }

Until ScanCodeDownScan; { ждать нажатия клавиши }

Scan:=ScanCodeDown; { сохранить скан-код нажатия }

Repeat

ScanCodeUp:=Port [$60]; { считать содержимое клавиатуры }

Until ScanCodeUpScan; { ждать отжатия клавиши }

Port [$21]:=0; { разрешить ПКП прерывания от клавиатуры }

Writeln (‘Скан-код нажатия клавиши’, ScanCodeDown);

Writeln (‘Скан-код отжатия клавиши’, ScanCodeUp);

Writeln (‘Нажмите любую клавишу’);

Readkey;

………

End.

К п. 3. Буфер клавиатуры устроен как циклическая очередь (типа FIFO) и занимает непрерывную область памяти. Имеется два указателя на начало и конец строки символов, которая находится в буфере в данный момент. Новые нажатия клавиш сохраняются в позициях, следующих за концом буфера, и соответственно обновляется указатель на конец буфера. В то время как указатель на начало буфера установлен на первый введенный символ, указатель на конец буфера установлен на позицию за последним введенным символом. Когда оба указателя равны, считается, что буфер пуст.

Сам буфер занимает 32 байта с адреса 0040Н:001EH по 0040Н:003СН. Указатели на начало и конец буфера расположены по адресам 0040Н:001AH и 0040Н:001CH соответственно. Значения указателей меняются от 1EH до 3CH, что соответствует области данных BIOS.

Новое нажатие на клавишу сохраняется в позициях следующих за хвостом буфера, т.е. в более старших адресах памяти и поэтому при вводе данных используются значения только хвоста очереди. Буфер может накапливать до 15 нажатий на клавишу. Для разрешения ввода 15 символов требуется 16 позиция, которая располагается перед головой буфера, и в этой позиции записывается значение кода возврата каретки (ASCII13) и скан-код клавиши ‘Enter’. Когда буфер заполнен, новые вводимые символы игнорируются, и выдается сигнал на динамик.

Рисунок

Как отмечалось выше, после трансляции скан-кодов клавиш в коды ASCII в буфере отводится по два байта для каждого нажатия на клавишу. Для трансляции скан-кодов в коды ASCII используются 3 таблицы:

  • скан-кодов клавиш (табл. 9);
  • кодов символов ASCII (табл. 11);
  • расширенных кодов ASCII (табл. 12).

Символам ASCII соответствуют клавиши, которые отображаются на экране – символы алфавита, цифры и т.д. Скан-код таких клавиш преобразуется в 2-х байтовый код, младший байт которого содержит код ASCII, а старший – скан-код клавиши.

Расширенные коды присвоены клавишам или комбинациям клавиш, которые не отображаются на экране – функциональные клавиши F1-F10, Home, PageUp и т.д, комбинации ‘Alt-A’, ‘Ctrl-B’ и т.д. Скан-код таких клавиш преобразуется в 2-х байтовый код, младший байт которого равен 0, а старший содержит номер расширенного кода, который обычно совпадает со скан-кодом клавиши, но не всегда, поскольку некоторые клавиши можно комбинировать с клавишами сдвига для генерации различных кодов.

В прикладных программах ввод данных осуществляется из буфера клавиатуры. При этом прикладная программа должна решить две задачи:

  • определить наличие символа в буфере клавиатуры;
  • выполнить ввод символа и очистить позицию буфера , соответствующую введенному символу.

Для решения первой задачи достаточно проверить значения указателей головы и хвоста буфера клавиатуры: если они равны — буфер пуст; в противном случае – в буфере находится новый символ. В Turbo Pascal наличие символа в буфере проверяется с помощью функции Keypressed.

При вводе данных в прикладную программу код символа читается из буфера клавиатуры, после чего значения указателя головы буфера увеличивается на единицу или приравнивается значению хвоста (буфер пуст). В Turbo Pascal ввод символа из буфера выполняется с помощью функции Readkey, которая вместе с тем ожидает и ввод символа, т.е. определяет наличие символа в буфере.

Фрагмент программы ввода данных в прикладных программах:

Begin

………

{ вывод содержимого указателей на экран}

writeln(‘Начало буфера до нажатия: ’,MemW[$0040:$001A);

writeln(‘Конец буфера до нажатия: ’,MemW[$0040:$001C);

repeat until keypressed; { ждать нажатия клавиши }

{ вывод содержимого указателей на экран}

writeln(‘Начало буфера после нажатия: ’,MemW[$0040:$001A);

writeln(‘Конец буфера после нажатия: ’,MemW[$0040:$001C);

ch:=readkey; { считать символ из буфера клавиатуры }

writeln(‘Символ: ‘,ch);

writeln (‘ASCII код символа: ’,ord(ch));

{ вывод содержимого указателей на экран}

writeln(‘Начало буфера после чтения из буфера: ’,MemW[$0040:$001A);

writeln(‘Конец буфера после чтения из буфера: ’,MemW[$0040:$001C);

Writeln (‘Нажмите любую клавишу’);

Readkey;

………

End.

К п. 4. Хотя скан-код и указывает однозначно на нажатую клавишу, по нему нельзя судить, включен ли на клавиатуре верхний или нижний регистр или пользователь вводит латинские или русские буквы. Кроме того, на клавиатуре компьютера клавиши статуса ‘Alt’, ‘Ctrl’, ‘Shift’,’CapsLock’ и др. Таким образом, прерывание от клавиатуры должно анализировать не только скан-коды, но и факты нажатия перечисленных клавиш. Информация о текущем состоянии клавиш статуса клавиатуры хранится в двух ячейках памяти с адресами 0040Н:0017Н и 0040Н:0018Н и называется словом состояния клавиатуры (табл. 10).

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

табл. 10

Адрес ячейки Номер бита Клавиша Значение, когда бит установлен
0040Н:0017Н InsertCaps LockNum LockScroll LockAltCtrlЛевый ShiftПравый Shift режим вставки включенрежим Caps Lock включенрежим Num Lock включенрежим Scroll Lock включенклавиша нажатаклавиша нажатаклавиша нажатаклавиша нажата
0040Н:0018Н 2 — 0 InsertCaps LockNum LockScroll LockCtrl – Num Lockне используются клавиша нажатаклавиша нажатаклавиша нажатаклавиша нажатарежим Ctrl – Num Lock включен

Для проверки состояния битов статуса клавиш необходимо обратиться к соответствующему элементу массива Mem, а затем сравнить его содержимое с словом-маской соответствующего бита. Например:

Status17:= Mem [$0040:$0017]; { считываем слово статуса }

If Status17 and 40 { 4H = 00000100B }

then ……. { клавиша Ctrl нажата }

else …… { клавиша Ctrl отжата }

  • К п.5. Для модификации существующего прерывания BIOS 09Н необходимо выполнить следующую последовательность действий:
  • создать новую процедуру, вызывающую какое-либо неиспользуемое прерывание (табл. 3).
  • перенести вектор прерывания для 09Н в С8Н.
  • изменить вектор 09Н, чтобы он указывал на новую процедуру;
  • при завершении программы восстановить исходные значения векторов.

Модуль KeyBoard предоставляет возможность наглядного отображения на экране текущего значения слова состояния и буфера клавиатуры при нажатии на клавиши. Для пользователя доступны следующие переменные и процедуры модуля:

  • процедура ClearBuf – заполняет содержимое буфера нулями;
  • переменная count_press – подсчитывает количество нажатий на клавиши клавиатуры в текущем сеансе работы. Вы можете использовать значение этой переменной в основной программе для ограничения числа нажатий на клавиши, например:

…………..

ClearBuf; { заполнить буфер нулями }

Count_press := 0; { очистить счетчик нажатий клавиш }

repeat

until count_press = 7; { ждать пока будут нажаты 7 клавиш }

…….

  • процедура Status_Print – выводит на экран в наглядной форме значение слова состояния клавиатуры (только ячейки 0417Н);
  • процедура Status_Print – выводит на экран в наглядной форме значение слова состояния клавиатуры (только ячейки 0417Н);
  • процедура Buffer_Print– выводит на экран в наглядной форме значения указателей буфера клавиатуры (ячейки 041АН-041DН и содержимое самого буфера (ячейки 041ЕН-043СН).

К п.6. При анализе содержимого буфера вы можете воспользоваться следующими таблицами: скан-кодов клавиш (табл. 9), ASCII кодов символов (табл. 11.), или расширенных кодов (табл. 12.).

табл. 11

Код Символ Код Символ Код Символ Код Символ Код Символ Код Символ Код Символ Код Символ
! A a А а р
B b Б б с
# C c В в т
$ D d Г г у
% E e Д д ф
F f Е е х
BEL G g Ж ж ц
BK ( H h З з ч
Tab ) I i И и ш
LF * J j Й й щ
+ K k К к ъ
¢ L i Л л ы
CR M m М м ь
. N n Н н э
/ O o О о ю
P p П п я
Q q Р Е
R r С е
S s Т ³
T t У ?
U u Ф o
V v Х o
W w Ц ?
X x Ч »
Y y Ш °
: Z z Щ .
; [ { Ъ .
\ | Ы O
= ] } Ь h
^ ~ Э z
? _ Del Ю g
@ Я

табл. 12

Значение 2-го байта Соответствующие клавиши
16-2530-3844-5059-6884-9394-103104-113120-131 Shift + Tab (‘back-tab”)Alt+Q –Alt+P (верхний ряд букв)Alt+A – Alt+L (средний ряд букв)Alt+Z – Alt+M (нижний ряд букв)Функциональные клавиши F1-F10HomeCursor-up (стрелка вверх)PgUpCursor-left (стрелка влево)Cursor-right (стрелка вправо)EndCursor-down (стрелка вниз)PgDnInsDelF1-F10 +ShiftF1-F10 +CtrlF1-F10 +AltCtrl + PrtScCtrl + Cursor-leftCtrl + Cursor- rightCtrl + EndCtrl + PgDnCtrl + HomeAlt+l – Alt+= (верхний ряд)Ctrl + PgUp

Контрольные вопросы

1. Что такое скан-код ?

2. Какие типы кодов символов вы знаете ?

3. Что хранится в буфере клавиатуры ?

4. Каким образом организован буфер клавиатуры ?

5. Как очистить буфер клавиатуры ?

6. Как проверить пуст или нет буфер клавиатуры ?

7. Из каких групп клавиш состоит клавиатура ?

8. Что такое слово состояния клавиатуры и от чего зависит его значение ?

9. Перечислите последовательность действий, которые необходимо выполнить для расширения стандартного прерывания клавиатуры ?

10. В каких случаях происходит переполнение буфера клавиатуры и что при этом происходит ?

Лабораторная работа № 3

Статьи к прочтению:

НАЛИВНОЙ ПОЛ, СТЯЖКА И ТЁПЛЫЙ ПОЛ. ВЫРАВНИВАНИЕ.


Похожие статьи: