Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сис прогр курсовая / Metod_k_kurs_rabote.doc
Скачиваний:
8
Добавлен:
07.02.2016
Размер:
282.62 Кб
Скачать

Додаток а

КЕРУВАННЯ СИСТЕМНИМ ТАЙМЕРОМ ТА ЗВУКОМ

Крім годинника реального часу, будь-який комп’ютер (навіть простіший IBM PC) містить пристрій, що має назву системний таймер. Це пристрій, який під’єднано до лінії запиту на апаратне переривання IRQ0 та виробляє програмне переривання INT 8h приблизно 18,2 рази на секунду (точне значення – 1193180/65536 раз на секунду).

А.1 Обробник переривання таймеру

При ініціалізації BIOS встановлює свій обробник для переривання таймеру. Цей обробник кожний раз збільшує на одиницю поточне значення 4-байтової змінної, що розташовано в області даних BIOS за адресою 0000:046Ch-лічильник таймеру. Якщо цей лічильник переповниться внаслідок того, що пройшло більш ніж 24 години з моменту запуску таймеру, в комірку 0000:047h заноситься значення 1.

Друга дія, що виконується стандартним обробником переривання таймеру, – контроль за роботою двигунів НГМД. Якщо після останнього звернення до НГМД пройшло більш ніж 2 секунди, обробник переривання вимикає двигун. Комірка за адресою 0000:0440h містить час, який залишився до вимикання двигуна. Цей час постійно зменшується обробником переривання таймеру. Коли він стає рівним нулю, двигун НГМД вимикається.

Остання дія, яку виконує обробник переривання таймеру, – виклик програмного переривання INT 1Ch. Після ініціалізації системи вектор INT 1Ch вказує на команду IRET, тобто обробник переривання INT 1Ch нічого не виконує. Програма може встановити власний обробник цього переривання для того, щоб виконувати які-небудь періодичні дії.

Таймер зазвичай реалізується на мікросхемі Intel 8253 (для комп’ютерів IBM PC та IBM PC/XT) або 8254 (для комп’ютерів IBM PC/AT та IBM PS/2), а також на аналогах цих мікросхем.

А.2 Канали таймеру

В сучасних комп’ютерах задіяні всі три канали таймеру.

Канал 0

Канал 0 використовується в системному годиннику часу доби (не слід плутати з годинником реального часу, що реалізовано на іншій мікросхемі). Цей канал працює в режимі 3 й використовується як генератор імпульсів з частотою приблизно 18,2 Гц. Саме ці імпульси викликають апаратне переривання IRQ0 та програмне INT 8h.

Канал 1

Канал 1 використовується для регенерації вмісту динамічної пам’яті комп’ютера. Вихід каналу OUT використовується для запиту до каналу прямого доступу DMA, котрий виконує оновлення вмісту пам’яті.

Канал 2

Канал 2 під’єднано до гучномовця комп’ютера й може бути використано для генерації “різноманітних” звуків або музики або як генератор випадкових чисел. Канал використовує режим 3 таймерів 8253 та 8254.

А.3 Таймер та музика

Одне з найбільш розповсюджених застосувань таймеру – генерація звукових сигналів й програвання музики. Таймер дозволяє програвати музику в фоновому режимі, тобто під час роботи програми може звучати музика.

А.3.1 Налаштовування таймеру для програвання музики

Канал 2 мікросхеми 8254 зв’язаний з гучномовцем комп’ютера. Однак гучномовець не просто з’єднано з виходом OUT каналу 2. Порт виводу 61h також використовується для керування гучномовцем. Молодший біт порту 61h під’єднано до входу GATE каналу 2 таймеру. Цей біт при встановленні в одиницю дозволяє роботу каналу, тобто генерацію імпульсів для гучномовця.

Додатково для керування гучномовцем використовується біт 1 порту 61h. Якщо цей біт встановлено, імпульси від каналу 2 таймеру зможуть проходити на гучномовець.

Додаткова інформація. Порт – це схема спряження, зазвичай містить в собі один або декілька регістрів вводу-виводу й дозволяє під’єднати, наприклад, периферійний пристрій до зовнішніх шин мікропроцесора. Кожний порт в персональному комп’ютері має свій унікальний номер.

Таким чином, для включення звуку необхідно виконати наступні дії:

Запрограмувати канал 2 таймеру на необхідну частоту (завантажити регістр лічильника каналу необхідним значенням);

Встановити два молодших біти порту 61h. Так як інші 6 бітів порту 61h використовуються для інших цілей, встановлення молодших бітів має виконуватись таким чином, щоб значення інших бітів не було змінено. Для цього спочатку необхідно прочитати байт з порту 61h в робочу комірку пам’яті, встановити там необхідні біти, потім вивести нове значення байту до порту 61h. Для вимикання звуку необхідно скинути два молодших біти порту 61h, при цьому не можна змінювати значення інших бітів цього порту.

Одноголоса мелодія складається з нот, розділених або не розділених паузами. При програванні мелодії необхідно для кожної ноти програмувати відповідним чином канал 2 таймеру й вмикати гучномовець (за допомогою порту 61h) на відповідний час, рівний довжині ноти. Потім програма повинна вимкнути динамік та витримати паузу перед програванням наступної ноти, якщо така пауза необхідна.

Програма може генерувати звуки й іншим чином, не використовуючи таймер. Для цього необхідно скинути молодший біт порту 61h та, керуючи бітом 1 цього порту, формувати імпульси для гучномовця. Інакше кажучи, програма повинна періодично встановлювати та скидати цей біт. Висота генерації звуку буде відповідати періоду зміни стану вказаного біту.

Можна також комбінувати описані способи, отримуючи різноманітні звукові ефекти.

А.3.2 Програвання музики в фоновому режимі

Для програвання мелодії в фоні використовується переривання INT 1Ch, котре виробляється таймером з частотою приблизно 18,2 Гц. Обробник цього переривання здійснює контроль за відпрацюванням нот з масиву, що містить мелодію, і програмування мікросхеми 8254. Наприклад, один раз на півсекунди обробник перевіряє, чи не час припинити звучання однієї ноти й почати програвання наступної. Якщо настав час, він вимикає гучномовець й перепрограмовує канал 8254 на нову частоту, що відповідає наступній ноті.

Основна перевага використання таймеру для програвання мелодії – незалежність констант, що використовуються для програмування каналу таймеру від швидкодії системи. Мелодія буде звучати однаково й на повільній IBM PC/XT, й на сучасному комп’ютері з процесором Pentium, але при умові, що буде використовуватись таймер і для організації затримок при виконанні мелодії.

Для з’ясування значення, яке треба записати до регістру лічильника каналу 2 таймеру, необхідно розділити число 1193180 на частоту ноти в герцах.

Для підготовки таблиць частот за нотами Вам допоможе Таблиця А.3.1.

Таблиця А.1 – Перелік частот для нот другої октави

Нота

Частота, Гц

До

261,7

До-діез

277,2

Ре

293,7

Ре-діез

311,1

Мі

329,6

Нота

Частота, Гц

Фа

349,2

Фа-діез

370,0

Соль

392,0

Соль-діез

415,3

Ля

440,0

Ля-діез

466,2

Сі

493,9

Для інших октав для пониження або підвищення тону значення частот треба помножити (при підвищенні тону) або розділити (при пониженні тону) на два.

А.4 Функції BIOS для роботи з таймером

BIOS комп’ютерів IBM AT містить ще дві цікаві функції для роботи з таймером. Це функції 83h та 86h переривання INT 15h.

Функція 83h дозволяє запустити таймер на відлік, вказавши адресу деякого байту в оперативній пам’яті. Програма, що запустила таймер, відразу після запуску отримує керування. При вичерпані часу, що задано під час запуску таймеру, функція встановлює старший біт вказаного байту в одиницю, сигналізуючи, таким чином, програмі про завершення вказаного часового інтервалу. Програма може також відмінити роботу таймеру в цьому режимі.

Цю функцію зручно використовувати для організації виконання яких-небудь дій паралельно з відліком часу, наприклад, можна обмежити час для введення паролю.

Формат виклику функції 83h переривання INT 15h:

На вході:

AH = 83h;

AL = код підфункції:

0 – встановити інтервал, запустити таймер;

1 – відмінити роботу таймеру;

CX = старший байт часу роботи лічильника, задається в мікросекундах;

DX = молодший байт лічильника;

ES:BX = адреса байту, в якому при вичерпанні інтервалу часу старший біт буде встановлено в 1.

На виході:

Не використовується.

Функція 86h спеціально призначена для формування затримок. Вона дозволяє з’ясовувати час затримки в мікросекундах, що досить зручно для багатьох задач. Під час виконання затримки дозволені переривання. Формат виклику функції:

На вході:

AH = 86h;

CX = старший байт часу затримки, задається в мікросекундах;

DX = молодший байт часу затримки.

На виході:

Не використовується.

А.5 Засоби MS-DOS для роботи з таймером

MS-DOS використовує чотири функції переривання INT 21h для роботи з системним таймером. Ці функції дозволяють дізнатись та встановити поточну дату й час. MS-DOS версії 3.30 й більш пізніх версій при встановленні часу й дати змінює також показники годиннику реального часу.

Для отримання поточної дати використовується функція 2Ah:

На вході:

AH = 2Ah.

На виході:

DL = день (0...31);

DH = місяць (1...12);

CX = рік (1980...2099);

AL = номер дня тижня:

0 - неділя;

1 - понеділок;

2 - вівторок;

.........

6 - субота.

Зверніть увагу на те, що функція повертає номер дня тижня, котрий вона обчислює на основі дати.

Для встановлення дати використовується функція 2Bh:

На вході:

AH = 2Bh;

DL = день (0...31);

DH = місяць (1...12);

CX = рік (1980...2099).

На виході:

AL = 0, якщо встановлення виконано правильно;

AL = FFh, якщо при встановленні були допущені неправильні параметри.

Для того, щоб з’ясувати поточний час, можна скористатися функцією 2Ch:

На вході:

AH = 2Ch.

На виході:

CH = години (0...24);

CL = хвилини (0...59);

DH = секунди (0...59);

DL = соті долі секунди (0...99).

Точність часу, отриманого за допомогою цієї функції, задається таймером (час оновлюється 18,2 рази на секунду).

Для встановлення часу можна використовувати функцію 2Dh:

На вході:

AH = 2Dh;

CH = години (0...24);

CL = хвилини (0...59);

DH = секунди(0...59);

DL = соті долі секунди (0...99).

На виході:

AL = 0, якщо встановлення виконано правильно;

AL = FFh, якщо при встановленні були допущені неправильні параметри.

Програма sys_t.cpp демонструє використання системного таймеру для формування проміжків часу, незалежних від тактової частоти IBM-сумісної ЕОМ.

#include <dos.h>

#include <stdio.h>

#include <conio.h>

#include <math.h>

void main (void);

void tm_sound (int, int, int);//функція генерації звуку;

void tm_delay (int); //функція для створення затримки;

//Масив частот (еквівалент нот в герцах) другої октави

int iMel[ ] = { 220,293,329,349,293,329,349,392,

329,349,392,440,349,392,440,466,

392,440,349,392,329,349,293,329,

277,293,220,233,196,220,174,196,

164,174,146,164,138,146,146,174,

220,293,130,164,196,261,110,116,

174,233,220,146,174,220,293,130,

164,196,261,110,116,174,233,220,0

};

//Масив довжин звуків в тіках

int iDel[ ] = {

4,4,4,4,4,4,4,4,

4,4,4,4,4,4,4,4,

4,4,4,4,4,4,4,4,

4,4,4,4,4,4,4,4,

4,4,4,4,4,8,4,4,

4,4,4,4,4,4,4,4,

4,4,8,4,4,4,4,4,

4,4,4,4,4,4,4,8,4,

};

int iOct; // коефіцієнт октави

void main (void)

{

int i;

for(iOct=2;iOct<3;iOct++)

{

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

tm_sound ( iMel[i], iDel[i], iOct-1);

}

}

/*Функція tm_sound генерує звук з висотою тону й довжиною, незалежною від тактової частоти ЕОМ. Це досягнуто за рахунок того, що за замовчуванням кількість тіків в секунду однакова для всіх IBM-сумісних ЕОМ. Частота тіків - приблизно 18,2 Гц. */

void tm_sound(int iFreq, int iTime, int Oct)

{

int iPer, //Коефіцієнт ділення;

iOct = Oct, //Коефіцієнт октави;

i; //Додатковий лічильник;

/*Звернутися до керуючого порту 43h. Надіслати до цього порту послідовність бітів (байт) для вибору каналу таймеру, статусу читання/запису, режиму операції та форми представлення чисел і т.і. */

outp(0x43, 0xb6);

// З’ясувати коефіцієнт ділення,

iPer = 1193180L / (pow(2,iOct)*iFreq);//1193180 Гц - частота кварцового генератору;

/*Завантажити коефіцієнт ділення до регістру лічильника таймеру (задати висоту звуку). Завантажити спочатку молодший, а потім старший байт: */

outp(0x42, iPer & 0x00ff);

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

//Ввімкнути динамік:

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

//Виконати затримку:

tm_delay(iTime);

//Вимкнути динамік:

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

}

//Функція tm_delay для отримання затримки.

void tm_delay ( int iTicks)

{

_asm {

push si //; завантажити до стеку вміст регістру SI;

mov si,iTicks //;занести до регістру необхідну затримку в тіках;

mov ah,0 //; функція 00h – для зчитування вмісту лічильника таймеру;

int 1ah //; переривання для роботи з таймером; в регістрі DX зчитане молодше слово лічильника таймеру

mov bx,dx //; це слово занести до регістру BX

add bx,si //; й до нього додано число тіків, рівне затримці;

}

delay_loop:

/* З кожним тіком таймеру вміст лічильника за допомогою переривання BIOS INT 8h збільшується на одиницю */

_asm {

int 1ah //;- переривання для роботи з таймером; в регістрі DX зчитане молодше слово лічильника таймеру

cmp dx, bx //; порівняти з вмістом регістру BX;

jne delay_loop //;якщо не рівні – затримка продовжується;

pop si //; - інакше поновлення регістру SI значенням зі стеку

}

}

Таблиця. Варіанти завдань.

Фа(1/4) Ми(1/4) Ре(1/4) До(1/4) Соль(1/2) Соль(1/2) Фа(1/4) Ми(1/4) Ре(1/4) До(1/4) Соль(1/2) Соль(1/2)

Фа(1/4) Ля(1/4) Ля(1/4) Фа(1/4) Ми(1/4) Соль(1/4) Соль(1/4) Ми(1/4)

Ре(1/4) Ми(1/4) Фа(1/4) Ре(1/4) До(1/2) До(1/2) Ре(1/4) Ми(1/4) Фа(1/4) Ре(1/4) До(1/2) До(1/2)

Ми(1/4) Ми(1/4) Ре(1/4) До(1/4) Ре(1/4) Ми(1/2)

Ми(1/4) Ми(1/4) Ми(1/4) Фа(1/2) Ми(1/4) Ре(1/4) Син(1/4) До(1/4) Ре(1/2)

До(1/4) До(1/4) Фа(1/4) Фа(1/4) Фа(1/4) Фа(1/4) Ми(1/4) До(1/4)

Ля(1/4) Ля(1/4) Соль(1/2) Фа(1/4) Ми(1/4) Ре(1/2) Ля(1/4) Ля(1/4) Соль(1/2) Фа(1/4) Ми(1/4) Ре(1/2)

До(1/4) Ре(1/4) Ми(1/2) Фа(1/4) Ми(1/4) Соль(1/2)

Си(1/4) Дов(1/2) Си(1/4) Соль(1/2) Си(1/4) Дов(1/2) Си(1/4)

Лян(1/4) До(1/4) Фа(1/4) Соль(1/4) Ля(1/2) Соль(1/4) Фа(1/4) Соль(1/4) Ре(1/4) Ре(1/4) Ля(1/4) Соль(1/2)

Продовження Таблиці

Си(1/4) Дов(1/2 .) Си(1/8) Ля(1/8) Фа#(1/8) Ля(1/2) Дов(1/4) Си(1/4) Ля(1/8) Ля(1/8) Соль(1/8) Соль(1/2)

Ми((1/4) Соль(1/4) Ми(1/4) Си(1/2) Фа#(1/4) Cоль(1/4) Ре#(1/4) Ми(1/2) я

Фа#(1/4) Соль(1/4) Ля(1/4) Си(1/4) ДоВ(1/2) Фа#(1/4) РеВ(1/4) Дов#(1/2) Фа#(1/4)

Фа#(1/4) Си(1/4) До#В(1/4) РеВ(1/4) МиВ(1/4) До#В(1/2) Си(1/4) Ля(1/2)

Ля(1/4) Соль(1/4) Фа#(1/4) Ми(1/4) Си(1/2) Ре(1/4) Ре(1/4) Си(1/2) До#(1/4)

Ми(1/4) Дов(1/4) Си(1/4) Ля(1/2) Ля(1/4) Ля(1/2) Соль#(1/2) Ми(1/2)

Ми(1/2) Ля(1/2) Ля(1/4) Соль#(1/4) Соль#(1/4) Ля(1/4) Ля(1/4) Си(1)

Ми(1/4) Дов(1/4) Си(1/4) Ля(1/2) Ми(1/2) Фа(1/2) Ми(1/2) Ми(1/2) Ре(1/2)

Ре(1/4) Ми(1/4) Фа(1/4) Ми(1/2) Ми(1/4) Фа#(1/2) Соль#(1/4) Ля(1/4)

Ля(1/2) Соль(1/2) Соль(1/4) Ля(1/4) Ля(1/4) Ля(1/4) Ля(1/4) Соль(1) До#в(1/2)

Дов(1/4) До(1/2) Си(1/4) Сив(1/4) Си(1/4) Соль(1/4) Соль#(1/4) Ля(1)

Дов(1/4) Дов(1/2) Дов(1/4) Си(1/4) Дов(1/4) Рев(1/4) Ре#в(1/4) Мив(1/2)

Мив(1/2) Мив(1/4) Рев(1/4) Дов(1/4) Си(1/4) Ля(1/2) Дов(1/4) Си(1/4) Си(1/2) Ля(1/2)

До(1/4) Ре(1/4) Ми(1/4) Фа(1/4) Соль(1/4) Ля(1/4) Си(1/4) До в(1/4)

  1. 25

Си(1/4) Ля(1/4) Соль(1/4) Фа(1/4) Ми(1/4) Ре(1/4) До(1/4)

Соседние файлы в папке Сис прогр курсовая