Praktichna_robota_2


Чтобы посмотреть этот PDF файл с форматированием и разметкой, скачайте его и откройте на своем компьютере.

1

Практична робота №
2


Тема:

Програмування системного таймеру

Мета роботи:


Оволодіння практичними навичками в роботі з
системним таймером


Теоретичнi вiдомостi


Окрім годинника реального часу, будь
-
який комп'ютер (навіть простий IBM РС)
містить пристрій,
званий системним таймером. Цей пристрій підключений до лінії
запиту на переривання I
RQ
0 і виробляє переривання INT 8h приблизно 18,2 разу в
секунду (точне значення
-
1193180/65536 разів в секунду).

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

Інша дія, що виконується стандартним обробником переривання таймера,
-

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

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

Необхідно відзначити, що пе
реривання INT 1
C
h викликається обробником
переривання INT 8h до скидання контроллера переривання, тому під час виконання
переривання INT 1
C
h всі апаратні переривання заборонені. Зокрема, заборонені
переривання від клавіатури.


2

Приведений нижче рисунок 2.1 і
люструє механізм обробки переривання
таймера:



Рисунок 2.1
М
еханізм обробки переривання таймера

Таймер зазвичай реалізується на мікросхемі Intel 8253 (для комп'ютерів IBM РС
і IBM XT) або 8254 (для комп'ютерів IBM AT і IBM P
S
/2
).

Мікросхеми таймера 8253/8254

Таймери 8253 і 8254 складаються з трьох незалежних каналів, або лічильників.
Кожен канал містить регістри:



стану каналу RS (8 розрядів);



керуючого слова
RSW
(8 розрядів);



буферний регістр
OL
(16 розрядів);



р
егістр лічильника
CE
(16 розрядів);



регістр констант перерахунку
CR
(16 розрядів).

Обробник Int 8h

Збільшення
лічильника за
адресою 0000:046Ch, перевірка
його на переповнення.


Перевірка ч
асу останнього
звернення до НГМД, якщо воно
більше 2 секунд, вимкнення
двигуна НГМД.

Виклик переривання INT 1Ch

З
кидання контроллера переривань

IRET

Обробник Int
1C
h

Виконання дій
, визначених в
програмі


IRET


3

Канали

таймера

підключаються

до

зовнішніх

пристроїв

за

допомогою

трьох

ліній
:



GATE



керуючий
вхід;



CLOCK

-
вхід тактової частоти;



OUT

-
вихід таймера.

Рег
істр

лічильника

CE

працює

в

режимі

віднімання
.
Його

вміст

зменшується

по

задньому

фронту

сигналу
CLOCK
за

умови
,
що

на

вхід
GATE
встановлений

рівень

логічної
1.

Залежно від режиму роботи таймера при досягненні лічильником CE нуля тим
або іншим чином змінює
ться вихідний сигнал OUT. Буферний регістр OL
призначений для запам'ятовування поточного вмісту регістра лічильника CE без
зупинка процесу рахунку. Після запам'ятовування буферний регістр доступний
програмі для читання.

Регістр констант перерахунку CR мож
е завантажуватися в регістр лічильника,
якщо це потрібно в поточному режимі роботи таймера. Неважко

здогадатися по
назві, регістри стану каналу і
керуючого
слова,

призначені, відповідно, для
визначення поточного стану каналу і для завдання режиму роботи т
аймера.

Спрощена схема взаємодії регістрів каналу приведена на
рисунку
2.2:






Рисунок 2.2 Спрощена схема взаємодії регістрів каналу


Можливі шість режимів роботи таймера. Вони розділяються на трьо
х типів:

-

р
ежими 0, 4
-
однократне виконання функцій.

-

р
ежими 1, 5
-
робота з перезапуском.

-

р
ежими 2, 3
-
робота з автозавантаженням.

СR

С
E

OL


Керуюча
логіка каналу

GA
TE

CLOCK

OUT


4

У режимі однократного виконання функцій перед початком рахунку вміст
регістра констант перерахунку
CR
переписується в
регістр лічильника
CE
по сигналу
CLOCK
, якщо сигнал
GATE
встановлений в 1. Надалі вміст регістра
CE
зменшується
у міру приходу імпульсів
CLOCK
.
Процес рахунку можна припинити, якщо подати
на вхід GATE рівень логічного 0. Якщо потім на вхід GATE подати 1, р
ахунок буде
продовжений далі. Для повторення виконання функції необхідне нове завантаження
регістра CR, тобто
повторне програмування таймеру.

При роботі з перезапуском не вимагається повторного програмування таймера
для виконання тієї ж функції. По фронту
сигналу GATE значення константи з
регістра CR знов переписується в регістр CE, навіть якщо поточна операція не була
завершена.

В
режимі автозавантаження регістр CR автоматично переписується в регістр CE
після завершення рахунку. Сигнал на виході OUT з'явля
ється лише за наявності на
вході GATE рівня логічної 1. Цей режим використовується для створення
програмованих імпульсних генераторів і генераторів прямокутних імпульсів
(меандра).

В
комп'ютері
IBM

P
С
/
XT
/
AT
/
PS
2 задіяно всі три канали таймера.

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

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

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



5

Програмування таймера на рівні портів

Таймеру відповідають чотири порти введення/вив
едення
з наступними адресами:



40h
-
канал 0;



41h
-
канал 1;



42h
-
канал 2;



43h
-

керуючий регістр
.


Формат керуючого регістра
:

7 6 5 4 3 2 1 0

Біти

BCD: 0
-
двійковий код

1
-

двійково
-
десятковий

М (
режим роботи каналу):

000
-
режим 0

001
-
режим 1

X10
-
режим 2

X11
-
режим 3

100
-
режим 4

101
-
режим 5

RW
(вигляд завантаження лiчильника
)
:

00
-

код команд
и
CLC (зап
ам'ятати
CE);

01
-

ч
итання
/запис старш
ого
байта;

10
-

ч
итання
/запис м
олодшого
байта;

11
-
читання/запис молодшого, потім старшого
.



SC (
номер каналу
)
:

00
-
канал 0

01
-
канал 1

10
-
канал 2

11
-

код команд
и
RBC (читання стану каналу)


Поле
BCD визначає формат константи, що використовується для рахунку,
-

двійковий або двійково
-
десятковий. У двійково
-
десятковому режимі константа
задається в діапазоні 1
-
9999. Поле M визначає режими роботи мікросхеми 8254:

• 0
-
переривання від таймера;


1
-
програмований чекаючий мультивібратор;

• 2
-
програмований генератор імпульсів;


6



3
-
генератор меандра;



4


програмно
-
запускаємий
одновібратор;



5


апаратно

запускаємий
одновібратор.

Ми
будемо р
озглядати лише режим 3, оскільки саме він викорис
товується в
каналах 0 і 2. Поле RW визначає спосіб завантаження констант через однобайтовий
порт. Якщо в цьому полі задано значення 00, це
керуюче
слово, що
буде
використовуватися
для фіксації поточного вмісту регістрів лічильника CE в
буферному регістрі
OL з метою читання програмою. Це код команди CLC
-
фіксація
регістрів. Код каналу, для якого виконуватиметься фіксація, має бути вказаний в
полі SC. Поля M і BCD при цьому не
використовуються.

Поле SC визначає номер каналу, для якого призначено
керуюче
сло
во. Якщо в
цьому полі задано значення 11,
то буде виконуватися
читання стану каналу.

Наведемо формат команди
RBC ч
итання слова стану каналу
:


Біти

0

1

вибір каналу 0

1

вибір каналу 1

1

вибір каналу 2

STAT
:

0

читання стану каналів
;

1
-
не
ч
итати стан каналів
;

11
-

код команд
и
RBC

7 6 5 4 3 2 1 0


CNT
:

0

запам’
ятати поточний вміст
CE;

1


не запам’
ятовувати вміст CE
.






7

За допомогою цієї команди
можна
виконувати операції читання стану каналів
або запам
'ятовування регістра лічильника CE каналів. Можна виконувати ці операції
як для окремих каналів, так і для всіх каналів одночасно, якщо встановити відповідні
біти (1, 2, 3) в 1. Формат слова стану каналу нагадує формат регістра
керуючого

слова, за винятко
м двох старших розрядів 7 і 6:


7 6 5 4 3 2 1 0

Біти

BCD: 0
-
двійковий код

1
-

двійково
-
десятковий

М (
режим роботи каналу):

000
-
режим 0

001
-
режим 1

X10
-
режим 2

X11
-
режим 3

100
-
режим 4

101
-
режим 5

RW (вигляд з
авантаження лiчильника
)
:

00
-

код команд
и
CLC (зап
ам'ятати
CE);

01
-

ч
итання
/запис старш
ого
байта;

10
-

ч
итання
/запис м
олодшого
байта;

11
-
читання/запис молодшого, потім старшого
.




FN: прапор перезавантаження констант


OUT: стан виходу OUT



Розряд FN використовується, в основному, в режимах 1 і 5 для визначення, чи
сталося завантаження константи з регістра CR в регістр лічильника CE. Розряд OUT
дозволяє визначити стан вихідної лінії
каналу OUT у момент виконання команди
RBC. Для програмування каналу таймера необхідно виконати наступну
послідовність дій:



вивести в порт
керуючого
регістра з адресою 43h
керуюче
слово;



необхідне значення лічильника посилається в порт каналу (адреси
40h...42h),
причому спочатку виводиться молодший, а потім старший байти значення
лічильника.


8

Відразу після цього канал таймера почне виконувати необхідну функцію. Для
читання поточного вмісту лічильника CE необхідно виконати наступне:



вивести в порт
керуючого
регістра, код команди CLC (команда
запам'ятовування вмісту регістра CE);



вивести в порт
керуючого
регістра код команди запиту на читання/запис в
регістри каналу (поле RW повинне містити 11);



двома послідовними командами введення з порту
потрібного каналу ввести
молодший і старший байти поточного с
тану

Для чого вам може знадобитися перепрограмування каналів таймера?

Якщо треба підвищити точність виміру часу, що виконується за допомогою
каналу 0 таймера, мож
на
збільшити частоту що генерую
ться цим каналом імпульсів
(стандартне 18,2 Гц). Після закінчення вимірів режим роботи каналу необхідно
відновити для правильного функціонування системи.

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

Приклад 2.1
Відображення слова стану і вмісту лічильника для всіх трьох каналів таймеру.


#include

#include


main() {


unsigned i;


prin
tf("
\
n
\
n
Kanal
0"


"
\
n
-------
"

"
\
n");


// Чита
є
м
о
слово с
тану
канала,

// команда 0xe2 = 11100010B


outp(0x43, 0xe2);


printf("
\
n
Slovo stanu kanalu
: %02.2X",


inp(0x40));


// Чита
ємо по
точний стан регістру лічильника

// канала. Для
цього спочатку видаємо
команду CLC

// для канал
у
0. Код
цієї команди

-
0x00


outp(0x43, 0x00);


// Вводим
о молодший і старший байти лічильника

//
і відображаємо його
.


i = inp(0x40);


i
= (inp(0x40) << 8) + i;



9

printf("
\
n
Registr lichilnika
: %04.4X",i);


// Повтор
юємо ті ж дії для
1
і
2 канал
і
в.



printf("
\
n
\
n
Kanal
1"

"
\
n
-------
"

"
\
n");


outp(0x43, 0xe4);

prin
tf("
\
n
Slovo stanu kanala
: %02.2X",inp(0x41));

outp(0x43, 0x40);

i = inp(0x41);

i = (inp(0x41) << 8) + i;

printf("
\
n
Registr lichilnika
: %04.4X",i);

printf("
\
n
\
n
Kanal
2"

"
\
n
-------
");


outp(0x43, 0xe8);

printf("
\
n
Slovo stanu kanala
: %02.2X",inp(0x42));

outp(0x43, 0x80);

i = inp(0x42);

i = (inp(0x42) << 8) + i;

printf("
\
n
Registr lichilnika
: %04.4X",i);


getch();


exit(0);


}



Засоби BIOS для роботи з таймером

Для роботи з таймером (точніше кажучи, для роботи з каналом 0 таймера) BIOS
містить дві функції переривання INT 1
А
h. Вони дозволяють прочитати поточний
вміст лічильника і змінити його. Функція 00h призначена для читання в
місту
лічильника таймера:

На вход
і
: AH = 00h.


На в
и
ход
і
: CX = старший байт
лічильника
;


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


AL = 0,
якщо з моменту перезапуску т
аймера

прошло б
ільше
24
-
х
годин
.


Змінити вміст лічильника
таймер
у можна за допомогою наступної функції
:

На вход
і
: AH = 01h;


CX =
старший байт лічильника
;


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


На в
иході
: не
використовується
.



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


10

Проте слід враховувати, що точність формування затримки визначається
ча
стотою оновлення лічильника таймера (18.2 Гц), і може виявитися недостатньою
для деяких
додатків
.



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

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

На вход
і
: AH = 2Ah.

На в
и
ход
і
: DL = день (0...31);


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


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


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


0
-

неділя
;

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

2
-
в
івторок
;

.........

6
-
субота.


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

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

На вход
і
: 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).



11

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

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

На вход
і
: AH = 2Dh;


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


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


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


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


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

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

неправильн
і
параметр
и
.



Таймер і музика

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

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

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

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



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



для включення звуку встановити в 1 два молодших біта порту 61h.

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


12

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

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

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

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

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

Наприклад, один раз в півсекунди обробник перевіряє, чи не пора припинити
звучання однієї ноти і почати програвання наступної ноти. Якщо пора, він вимикає
гучномовець і перепрограмує канал 82
54 на нову частоту, відповідну наступній ноті.

Основна перевага використання таймера для програвання мелодії
-
незалежність
констант,
що використовуються
для програмування каналу таймера від
продуктивності системи.

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

Приклад 2.2
Функція
,
яка призначена для генерації
на гучномовці тону заданої
частоти і тривалості:

/*
формування тону заданої тривалості


13



int freq
-
частот
а в герцах;



int time


тривалість в тіках
таймера (за одну секунду
таймер

т
і
ка
є
18.2 раза).
*
/


#include

#include


void tm_sound(int freq, int time) {


int cnt, i;


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


outp(0x43
, 0xb6);


//
Обчислюємо затримку для завантаження
в

// рег
істр лічильника таймера



cnt = 1193180L / freq;


// За
вантажуємо регістр лічильника т
аймера
-
с
початку

// м
олодший
,
потім старший байти



outp(0x42, cnt & 0x00ff);

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


// В
микаємо гучномовець
. Сигнал
від
канал
у
2 таймера тепер буде
//
проходит
и

на вх
і
д г
учномовця


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


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


tm_delay(time);


// В
имикаємо гучномовець



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

}



Приклад 2.
3
Програма, яка за допомогою таблиці частот і
тривалостей
про
грає

прост
у
мелод
ію
.


#include

#include

#include


void tm_sound(int, int);

// Масив частот для мелод
ії


void main(void) {

int mary[] = {



330, 294, 262, 294, 330, 330, 330,

294, 294, 294, 330, 392, 392,

330, 294, 262, 294, 330, 330, 330, 330,

294, 294, 330, 294, 262, 0

};


// Масив
тривалостей



14

int del[] = {

5, 5, 5, 5, 5, 5, 10,

5, 5,
10, 5, 5, 10,

5, 5, 5, 5, 5, 5, 5, 5,

5, 5, 5, 5, 20

};



int i;



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

tm_sound(mary[i], del[i]);


}

void tm_sound(int freq, int time) {



int cnt;


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


outp(0x43, 0xb6);


// Обчислюємо затримку для завантаження в

// регістр лічильника таймера



cnt = 1193180L / freq;


// Завантажуємо регістр лічильника таймера
-
спочатку

// молодший, потім старший байти



outp
(0x42, cnt & 0x00ff);

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


// Вмикаємо гучномовець. Сигнал від каналу 2 таймера тепер буде

//проходити на вхід гучномовця


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


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



d
elay(
100);


// Вимикаємо гуч
номовець


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

}

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

Нота Частота, Гц


До 261,7

До
-
д
іє
з 277,2

Ре 293,7


15

Ре
-
д
іє
з 311,1


М
і
329,6

Фа 349,2

Фа
-
д
іє
з 370,0

Соль 392,0

Соль
-
д
іє
з 415,3

Ля 440,0

Ля
-
д
іє
з 466,2

С
і

493,9



Завдання:

Користуючись навичками роботи з C
/С++
,
написати та відлагодити програми
:

-

в
ідображення слова стану і вмісту лічильника для всіх трьох каналів таймеру
;

-

виведення простої мелодії, використовуючи системний таймер.





Контpольнi питання


1.
Пpизначення таймеpа.

2. Які регістри має кожен канал таймера?

3
.
Охарактеризуйте канали таймеру.

4.Які порти введення/виведення використовують
для програмування таймеру?

5. Яку послідовність дій потрібно виконати для програмування каналу таймера?

6. Які іс
нують засоби BIOS для роботи з таймером?

7. Які
є
засоби MS
-
DOS для роботи з таймером?

8
.
Охарактеризуйте існуючи способи генерації з
вука в IBM PC
?



Приложенные файлы

  • pdf 18010656
    Размер файла: 257 kB Загрузок: 0

Добавить комментарий