![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
«Изучение организации и принципов работы клавиатуры»
Цель работы: изучение организации и принципов работы клавиатуры и закрепление практических навыков управления ею, а также практических навыков создания собственных программ обработки прерываний.
Образовательные результаты, заявленные во ФГОС третьего поколения:
Студент должен
уметь:
- осуществлять разработку кода программного модуля на современных языках программирования;
- создавать программу по разработанному алгоритму как отдельный модуль;
- выполнять отладку и тестирование программы на уровне модуля
знать:
- основные этапы разработки программного обеспечения;
- основные принципы технологии структурного и объектно-ориентированного программирования;
- основные принципы отладки итестирования программных продуктов.
Краткие теоретические и учебно-методические материалы
По теме лабораторной работы
Работа клавиатуры организована на базе собственного микропроцессора. При нажатии или отпускании любой клавиши генерируется код (скан-код), который записывается в собственную память (аппаратный буфер) клавиатуры. При этом в центральный процессор выдается прерывание 9, сигнализирующее о появлении очередного скан-кода. Программа обработки этого прерывания может теперь прочитать код из клавиатуры. Если она этого не сделает, то сканкоды будут накапливаться в аппаратном буфере и могут быть прочитаны позднее. Чтение скан-кода производится из однобайтного порта 0x60. При выполнении только чтения скан-код не удаляется из аппаратного буфера, и при следующем обращении к порту 0x60 будет прочитан тот же скан-код.
Для того, чтобы удалить скан-код из аппаратного буфера, необходимо послать в клавиатуру сигнал подтверждения: на короткое время выставить единицу в старшем разряде однобайтного порта 0 x61 (не разрушая при этом остальных разрядов этого порта). Каждая клавиша имеет собственный уникальный скан-код, в том числе и на 101-клавишной клавиатуре AT, где некоторые клавиши дублируются - например, левая и правая клавиши Shift имеют разные скан-коды. Распределение значений скан-кодов примерно соответствует расположению клавиш на панели клавиатуры. Скан-коды не совпадают с кодировкой внутримашинного представления символов, для которой применяется код ASCII. Преобразование скан-кодов в коды ASCII происходит программными путем.
Пример.
Разработать программу обработки прерывания от клавиатуры, которая должна:
распознавать нажатие "горячей" комбинации клавиш и реагировать на него звуковым сигналом; при первом нажатии "горячей" комбинации переходить в режим блокировки ввода заданной клавиши, при втором - отменять этот режим; системная обработка всех других клавиш нарушаться не должна. Комбинация клавиш LeftCtrl+RightShift+F3; блокирование ввода клавиши 3.
Программа состоит из основной программы и трех функций.
void *readvect(int in) - функция читает вектор прерывания с номером in и возвращает его значение.
void writevect (int in, void *h) - функция устанавливает новый вектор прерывания in на новый обработчик этого прерывания по адресу h.
void interrupt new9() - процедура нового обработчика прерывания 9h.
Глобальные переменные программы: old9 - адрес старого обработчика прерывания 9h; F3_code - скан-код клавиши "F3", которая входит в комбинацию "горячих" клавиш; key3_code - скан-код клавиши "3", которая будет блокироваться/разблокироваться при каждом нажатии "горячей" комбинации клавиш; f - флаг, который при каждом нажатии "горячей" комбинации клавиш переключается из состояния 0 в 1 или из 1 в 0 (состояние 1 означает, что клавиша "3" заблокирована); rr и sr - переменные, которые используются для задания значений регистров общего назначения и сегментных регистров соответственно при вызове прерывания.
В главной программе использует символьный массив string для проверки работы программы. Переменные процедуры обработки прерывания 9h:
c - переменная, которая используется для подтверждения приема из клавиатуры, в случае, если была нажата клавиша "3", а флаг f показывал, что эта клавиша заблокирована;
x, y - переменные, которые используются для сохранения координат курсора на экране в момент вызова процедуры обработки прерывания;
byte17 - байт флага состояния клавиатуры в области данных BIOS по адресу 0040:0017;
byte18 - байт флага состояния клавиатуры в области данных BIOS по адресу 0040:0018;
mask - маска, которая используется для определения нажатия клавиши левый Shift (в этом случае бит 1 в byte17 установлен в 1);
mask17 - маска, которая используется для определения нажатия клавиши Сtrl (в этом случае бит 2 в byte17 установлен в 1);
mask18 - маска, которая используется для определения нажатия клавиши левый Сtrl (в этом случае бит 0 в byte18 установлен в 1);
Главная программа выполняет такие действия:
Запоминает адрес старого обработчика прерывания 9h, вызывая функцию readvect(in) с параметром in=9. Записывает в таблицу векторов прерываний адрес нового обработчика прерывания с помощью функции writevect(). Вводом строки символов дает возможность проверить работу программы и ее реакцию на нажатие "горячей" комбинации клавиш и блокирование/разблокирование ввода клавиши "3". В конце работы восстанавливает в таблице векторов прерываний адрес старого обработчика.
Для решения задачи процедура обработки прерывания от клавиатуры new9() должна действовать по такому алгоритму:
Прочитать флаги состояния клавиатуры (статус клавиш-переключателей), которые находятся в области данных BIOS (два байта по адресам 0040:0017 и 0040:0018).
Выделить бит 1 в флаге по адресу 0040:0017 (если он равен 1, то нажата клавиша левый Shift).
Выделить бит 2 в этом же флаге (если он равен 1, то нажата левый или правый Ctrl).
Выделить бит 0 в флаге состояния клавиатуры по адресу 0040:0018 (если он равен 1, то нажата клавиша левый Ctrl).
Из порта 60h прочитать скан-код нажатой клавиши.
Если нажата комбинация клавиш левый Shift, правый Ctrl (нажата клавиша Ctrl, но это не правый Ctrl)и клавиша F3, то выполнить п.7. Иначе - перейти к п.8.
Сигнализировать о нажатии "горячей" комбинации клавиш звуковым сигналом, переключить значение флага блокирования ввода клавиши "3" на обратное и вызвать старый обработчик прерывания от клавиатуры.
Прочитав байт из порта 60h, определить, нажата ли клавиша 3" и если, кроме этого, еще и флаг блокирования указывает на то, что она заблокирована (f=1), то выполнить п.п. 9 и 10, иначе - вызвать старый обработчик прерывания.
Послать подтверждение приема в клавиатуру. Для этого в порт 61h на короткое время выставить "1" по шине старшего разряда.
Сбросить контроллер прерываний, посылая код 20h в порт 20h.
Функция readvect() читает вектор заданного прерывания. Для чтения вектора используется функция 35h DOS (прерывания 21h):
Вход: AH = 35h;
AL = номер вектора прерывания.
Выход: ES:BX = адрес программы обработки прерывания
Функция writevect() устанавливает новый вектор прерывания на заданный адрес. Для записи вектора используется функция 25h DOS:
Вход: AL = номер вектора прерывания;
DS:BX = 4-байтный адрес нового обработчика прерывания.
/* Подключение стандартных заголовков */
#include <dos.h>
void interrupt (*old9)(); /* Старый обработчик прерывания 9h */
void interrupt new9(); /* Новый обработчик прерывания 9h */
void *readvect (int in); /* Чтение вектора */
void writevect (int in,void *h); /* Запись вектора */
unsigned char F3_code=61; /* scan-code "F3" */
unsigned char key3_code=4;/* scan-code "3" */
char f=0; /* Флаг */
union REGS rr;
struct SREGS sr;
/*--------------------------------------------------------*/
void main()
{
char string[80]; /* Буфер для ввода текста */
textbackground(0);
clrscr();
textattr(0x0a);
cprintf("---------------");
cprintf(" Лабораторная работа ");
cprintf("---------------");
cprintf("---------------");
cprintf(" Управление клавиатурой ");
cprintf("---------------");
old9=readvect(9);
writevect(9,new9);
textattr(0x0c);
cprintf("\n\n\r\"горячая\" комбинация: ");
textattr(0x0a);
cprintf("Left Shift, Right Ctrl, F3\n\r");
textattr(0x0b);
cprintf("Клавиша, которая блокируется: ");
textattr(0x0f);
cprintf("3");
textattr(0x07);
cprintf("\r\nВводите строку символов>");
scanf("%s",string);
writevect(9,old9);
}
/*--------------------------------------------------------*/
/* Чтение вектора */
void *readvect(int in)
{
rr.h.ah=0x35;
rr.h.al=in;
intdosx(&rr,&rr,&sr);
return(MK_FP(sr.es,rr.x.bx));
}
/*--------------------------------------------------------*/
/* Запись вектора */
void writevect(int in,void *h)
{
rr.h.ah=0x25;
rr.h.al=in;
sr.ds=FP_SEG(h);
rr.x.dx=FP_OFF(h);
intdosx(&rr,&rr,&sr);
}
/*--------------------------------------------------------*/
/* Новый обработчик 9-го прерыванмя */
void interrupt new9()
{
unsigned char c,x,y;
unsigned char byte17,byte18;
unsigned char mask=0x02;
unsigned char mask17=0x04;
unsigned char mask18=0x01;
byte17=peekb(0x40,0x17);
byte18=peekb(0x40,0x18);
if((inportb(0x60)==F3_code)&&(byte17&mask)&&
(byte17&mask17)&&(!(byte18&mask18)))
{
cputs("\7");
x=wherex();
y=wherey();
gotoxy(55,3);
textattr(0x1e);
if(f==0)
{
f=1;
cprintf("Клавиша \"3\" заблокирована ");
}
else
{
f=0;
cprintf("Клавиша \"3\" разблокирована");
}
gotoxy(x,y);
textattr(0x07);
(*old9)();
}
if((f==1) && (inportb(0x60)==key3_code))
{
c=inportb(0x61);
outportb(0x61,c|0x80);
outportb(0x61,c);
outportb(0x20,0x20);
}
else
(*old9)();
}
Во время программы при первом нажатии комбинации клавиш LeftCtrl+RightShift+F3 программа переходит в режим блокирования вводу клавиши 3, при втором - отменяет этот режим.
Задания для лабораторной работы:
Разработать программу обработки прерывания от клавиатуры, которая должна:
распознавать нажатие "горячей" комбинации клавиш и реагировать на него звуковым сигналом;
при первом нажатии "горячей" комбинации переходить в режим блокировки ввода заданной клавиши, при втором - отменять этот режим;
системная обработка всех других клавиш нарушаться не должна.
1. комбинация клавиш LeftCtrl+RightShift+F3; блокирование ввода клавиши 3.
2. комбинация клавиш LeftAlt+RightShift+F1; блокирование ввода клавиши 2.
3. комбинация клавиш LeftCtrl+RightShift+F7; блокирование ввода клавиши 4.
4. комбинация клавиш LeftShift+RightAlt+F9; блокирование ввода клавиши 1.
5. комбинация клавиш LeftAlt+RightShift+F2; блокирование ввода клавиши 5.
6. комбинация клавиш LeftAlt+RightCtrl+F4; блокирование ввода клавиши 7.
7. комбинация клавиш LeftCtrl+RightShift+F7; блокирование ввода клавиши 8.
8. комбинация клавиш LeftAlt+RightShift+F9; блокирование ввода клавиши 9.
9. комбинация клавиш LeftAlt+RightShift+F8; блокирование ввода клавиши 6.
10. комбинация клавиш LeftCtrl+RightAlt+F6; блокирование ввода клавиши 0.
11. комбинация клавиш LeftAlt+RightShift+F1; блокирование ввода клавиши q.
12. комбинация клавиш LeftCtrl+RightShift+F12; блокирование ввода клавиши g
13. комбинация клавиш LeftAlt+Rightv+F11; блокирование ввода клавиши wh
14. комбинация клавиш LeftCtrl+RightShift+F10; блокирование ввода клавиши e
15. комбинация клавиш LeftAlt+RightShift+F12; блокирование ввода клавиши r
16. комбинация клавиш LeftCtrl+RightShift+F2; блокирование ввода клавиши g
17. комбинация клавиш LeftAlt+RightShift+F1; блокирование ввода клавиши t
18. комбинация клавиш LeftAlt+RightCtrl+F3; блокирование ввода клавиши y
19. комбинация клавиш LeftCtrl+RightAlt+F4; блокирование ввода клавиши u
20. комбинация клавиш LeftAlt+RightShift+F5; блокирование ввода клавиши i
21. комбинация клавиш LeftCtrl+RightAlt+F8; блокирование ввода клавиши o
22. комбинация клавиш LeftAlt+RightCtrl+F6; блокирование ввода клавиши p
23. комбинация клавиш LeftAlt+RightShift+F5; блокирование ввода клавиши l
24. комбинация клавиш LeftShift+RightAlt+F9; блокирование ввода клавиши k
25. комбинация клавиш LeftAlt+RightShift+F1; блокирование ввода клавиши j
26. комбинация клавиш LeftAlt+RightCtrl+F3; блокирование ввода клавиши h
27. комбинация клавиш LeftAlt+RightShift+F2; блокирование ввода клавиши d
28. комбинация клавиш LeftCtrl+RightAlt+F12; блокирование ввода клавиши s
29. комбинация клавиш LeftCtrl+RightShift+F11; блокирование ввода клавиши z
30. комбинация клавиш LeftAlt+RightCtrl+F9; блокирование ввода клавиши x
31. комбинация клавиш LeftAlt+RightShift+F10; блокирование ввода клавиши c
32. комбинация клавиш LeftAlt+RightCtrl+F8; блокирование ввода клавиши v
33. комбинация клавиш LeftAlt+RightShift+F5; блокирование ввода клавиши b
34. комбинация клавиш LeftShift+RightAlt+F4; блокирование ввода клавиши n
35. комбинация клавиш LeftAlt+RightShift+F1; блокирование ввода клавиши m.
Контрольные вопросы:
1.Опишите функции стандартного ввода DOS связанные с клавиатурой.
2.Что такое скан-коды?
3.Каким образом происходит чтение скан-кодов?
4.Для чего служат однобайтные ASCII-коды?
5.Для чего служат расширенные ASCII-коды?
Дата публикования: 2015-11-01; Прочитано: 1134 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!