Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2392_Смирнова_ЛР5_ЭВМ

.docx
Скачиваний:
2
Добавлен:
05.12.2024
Размер:
333.11 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра ВТ

отчет

по лабораторной работе №5

по дисциплине «Организация ЭВМ и систем»

Тема: Использование аппаратных прерываний, прерывание таймера

Студент гр. 2392

Смирнова М. В.

Преподаватель

Ельчанинов М. Н.

Санкт-Петербург

2023

Цель работы.

Цель работы – знакомство с различного вида аппаратными прерываниями и создание собственных подпрограмм обработки прерываний.

Задание на лабораторную работу.

Целью лабораторной работы является разработка алгоритма и реализация программы подключения собственной подпрограммы обработки прерывания и использование её в цепочке со стандартной подпрограммой обработки прерывания от одного из следующих устройств компьютера:

  1. системный таймер;

  2. клавиатура;

  3. контроллер накопителя на гибких магнитных дисках;

  4. таймер реального времени;

  5. контроллер накопителя на жёстком магнитном диске.

Б лок-схема

Текст программы

#include <stdio.h>

#include <conio.h>

#include <dos.h>

int getkey();

void sound(int, int);

void tm_sound(int freq, int time);

// Массив частот

int PartA_1[] =

{

330, 494, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587,

330, 494, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587, 0

};

int PartA_2[] =

{

131, 262, 740, 587, 659, 494, 392, 494,

124, 247, 740, 784, 880, 784, 740, 587,

165, 330, 740, 587, 659, 494, 392, 494,

165, 330, 740, 784, 880, 784, 740, 587, 0

};

// Массив длительностей

int delPartA_1[] =

{

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428, 0

};

int delPartA_2[] =

{

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428, 0

};

//--------------//

int PartB_1[] =

{

165, 494, 659, 587, 659, 494,

220, 494, 370, 392, 156, 370,

165, 494, 659, 587, 659, 330, 294,

131, 494, 220, 247, 124, 370, 0

};

int PartB_2[] =

{

165, 494, 587, 740, 659, 494,

131, 494, 294, 494, 262, 494,

185, 220, 294, 330, 370, 294,

131, 494, 440, 740, 784, 740, 0

};

int delPartB_1[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 214, 214,

428, 428, 428, 428, 428, 428, 0

};

int delPartB_2[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

//--------------//

int PartC_1[] =

{

880, 494, 880, 494, 196, 880,

740, 494, 294, 784, 740, 784,

740, 494, 440, 880, 392, 494,

659, 494, 440, 740, 784, 740, 0

};

int delPartC_1[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

int PartC_2[] =

{

880, 494, 880, 494, 392, 880,

740, 494, 294, 784, 740, 784,

740, 494, 440, 880, 392, 494,

659, 494, 440, 494, 698, 784, 0

};

int delPartC_2[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

//--------------//

int delPartD[] =

{

107, 107, 1700, 858,

428, 428, 858, 858, 858,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 1700, 0

};

int PartD[] =

{

440, 523, 880, 349,

523, 587, 659, 587, 523,

494, 659, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587, 0

};

int main(void)

{

int i;

int ch, x = 1, y = 1;

textbackground(8);

clrscr();

window(25, 5, 55, 15);

textbackground(13);

textcolor(15);

_setcursortype (_NOCURSOR);

do

{

clrscr();

gotoxy(x, y);

cprintf("@");

ch = getkey();

switch(ch)

{

case 32:

do{

for (i = 0; PartA_1[i] != 0; i++)

tm_sound(PartA_1[i], delPartA_1[i]);

if (kbhit())

break;

for (i = 0; PartA_2[i] != 0; i++)

tm_sound(PartA_2[i], delPartA_2[i]);

if (kbhit())

break;

for (i = 0; PartB_1[i] != 0; i++)

tm_sound(PartB_1[i], delPartB_1[i]);

if (kbhit())

break;

for (i = 0; PartB_2[i] != 0; i++)

tm_sound(PartB_2[i], delPartB_2[i]);

if (kbhit())

break;

for (i = 0; PartC_1[i] != 0; i++)

tm_sound(PartC_1[i], delPartC_1[i]);

if (kbhit())

break;

for (i = 0; PartC_2[i] != 0; i++)

tm_sound(PartC_2[i], delPartC_2[i]);

if (kbhit())

break;

for (i = 0; PartD[i] != 0; i++)

tm_sound(PartD[i], delPartD[i]);

} while (ch!=27);

break;

case 72: //up

if (y > 1)

y--;

else if (y == 1)

{

sound(100);

delay(100);

nosound();

y = 11;

}

break;

case 80: //down

if (y <= 10)

y++;

else if (y > 10)

{

sound(100);

delay(100);

nosound();

y = 1;

}

break;

case 77: //right

if (x <= 30)

x++;

else if (x > 30)

{

sound(100);

delay(100);

nosound();

x = 1;

}

break;

case 75: //left

if (x > 1)

x--;

else if (x == 1)

{

sound(100);

delay(100);

nosound();

x = 31;

}

break;

default: break;

}

} while (ch != 27);

return 0;

}

int getkey()

{

union REGS regs;

regs.h.ah = 0x07;

int86(0x21, &regs, &regs);

return regs.h.al;

}

void tm_sound(int freq, int time)

{

int cnt;

// Задаем режим канала 2 таймера

outp(0x43, 0xb6);

// Вычисляем задержку для загрузки в

// регистр счетчика таймера

cnt = (int)(1193180L / freq);

// Загружаем регистр счетчика таймера - сначала

// младший, затем старший байты

outp(0x42, cnt & 0x00ff);

outp(0x42, (cnt & 0xff00) >> 8);

// Включаем громкоговоритель. Сигнал от

// канала 2 таймера теперь будет проходить

// на вход громкоговорителя

outp(0x61, inp(0x61) | 3);

// Выполняем задержку.

delay(time);

// Выключаем громкоговоритель.

outp(0x61, inp(0x61) & 0xfc);

}

Примеры запуска программы

Структурная схема аппаратных средств, используемых при выполнении программы с необходимой степенью детализации содержимого блоков.

Вектор

прерывания

системного таймера

ОЗУ

(RAM)

………..

Таблица

векторов

прерываний

(1024 байт)

0000:0000

0000:0008 IRQ0

………..

0000:03FF

………..

………..

ПЗУ

(RОM)

Контроллер

ИП

Монитор

Контроллер

ЦП

(CPU)

СИСТЕМНАЯ ШИНА

Клавиатура

Контроллер

Таблица векторов прерываний занимает первый килобайт оперативной памяти — адреса от 0000:0000 до 0000:03FF. Таблица состоит из 256 элементов — FAR-адресов обработчиков прерываний. Эти элементы называются векторами прерываний. В первом слове элемента таблицы записано смещение, а во втором — адрес сегмента обработчика прерывания. Векторами являются просто полные адреса памяти программы (в сегментированной форме), которая должна быть активизирована в случае возникновения прерывания.

Прерывание с номером 8 — IRQ0 — прерывание интервального таймера, возникает 18,2 раза в секунду.

Соседние файлы в предмете Организация ЭВМ