Студопедия

Главная страница Случайная лекция


Мы поможем в написании ваших работ!

Порталы:

БиологияВойнаГеографияИнформатикаИскусствоИсторияКультураЛингвистикаМатематикаМедицинаОхрана трудаПолитикаПравоПсихологияРелигияТехникаФизикаФилософияЭкономика



Мы поможем в написании ваших работ!




Управление динамиком

В связи с повсеместным распространением звуковых плат обычный динамик PC теперь практически не используется или используется для выдачи сообщений об ошибках. Поэтому программирование канала 2 системного таймера - относительно безопасная операция. Изменения же частот канала 0 может привести к сбою системных часов, а канала 1 – и вовсе к потере содержимого ОЗУ. Поэтому be careful, студент!

 

Канал 2 системного таймера управляет динамиком компьютера — он генерирует прямоугольные импульсы с частотой, равной 1 193 180/начальное_значение_счетчика. При программировании динамика начальное значение счетчика таймера принято называть делителем частоты — считается, что динамик работает с частотой, равной 1 193 180/делитель Гц. Диапазон слышимости человеческого уха составляет примерно от 20 Гц до 20 кГц. Следовательно, делитель должен быть в диапазоне примерно 60…60000 (3Ch…EA60h). Например, частота ноты «до» первой октавы составляет 261,6 Гц, следовательно, делитель для нее должен быть 1 193 180 / 261,6 = 4561 (11D1h).

 

Чтобы включить динамик, необходимо установить 2 младших бита порта 61h. Соответственно, чтобы выключить – нужно эти 2 бита сбросить. Например, следующий код будет играть ноту «до» пока не будет нажата какая-нибудь клавиша:

 

in al, 61h ; прочитать байт из порта 61h

or al, 03h ; установить два младших бита: XXXXXXXX or 00000011 = XXXXXX11

out 61h, al ; записать обратно в порт 61h (speaker on)

 

mov al, 0B6h ; команда установки режима канала 2 системного таймера

out 43h, al ; записать команду в порт 43h

mov al, 0D1h ; младший байт делителя

out 42h, al ; записать в порт 42h значение D1h

mov al, 11h ; старший байт делителя

out 42h, al ; записать в порт 42h значение 11h (значение счетчика = 11D1h)

 

mov ah, 0 ; функция 0 прерывания BIOS 16h ожидает нажатия любой клавиши

int 16h ; после выполнения AH=scan-код, AL=ASCII-код (или 0 для функциональных клавиш)

 

in al, 61h ; прочитать байт из порта 61h

and al, 0FCh ; сбросить 2 младших бита: XXXXXXXX and 11111100 = XXXXXX00

out 61h, al ; записать обратно в порт 61h (speaker off)

Задание:

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

 

1.Включает динамик.

2.Ожидает нажатия клавиши (например, с помощью функции 0 прерывания int 16h).

3.Если это клавиша ESC (scan-код 01h, ASCII-код 1Bh), то динамик выключается, программа завершает работу.

4.Значение ASCII-кода умножается на коэффициент, чтобы результат попал в диапазон слышимости (коэффициент подобрать самостоятельно).

5.Полученный результат (2 байта) записывается в канал 2 системного таймера в качестве делителя.

6.Программа возвращается к п. 2.

Дополнительно (для умниц на хорошую оценку)

 

7.Оформить код записи делителя в виде процедуры, которой значение делителя передается в качестве параметра.

8.Оформить коды включения и выключения динамика в виде макросов.

9.Снабдить программу адекватными комментариями.

 

Например, программа может выглядеть так:

 

.model tiny ; Программа типа COM

 

... ; Тут макросы SpeakerOn и SpeakerOff

 

SetFreq PROTO near pascal N:word ; прототип процедуры SetFreq (для директивы INVOKE)

 

.code

 

org 100h

 

Start: SpeakerOn ; Вызов макро включения динамика

 

WaitKey:

mov ah, 0 ; Вызов функции 0 (ждать нажатия клавиши)

int 16h ; прерывания BIOS int 16h

cmp ax, 011Bh ; Сравнить AX c кодом клавиши ESC

je Exit ; Если совпало - на выход

mul Coeff ; Иначе умножаем AL на коэффициент

INVOKE SetFreq, ax ; и вызываем функцию установки делителя, равного значению в AX

jmp WaitKey ; Повторяем процедуру

 

Exit: SpeakerOff ; Вызов макро выключения динамика

ret ; Всем пока!

 

Coeff db xx ; Коэффициент для делителя

 

... ; А тут сама процедура SetFreq

 

end Start


<== предыдущая страница | следующая страница ==>
Управление таймером через порты ввода-вывода | Визуальные фильтры

Дата добавления: 2015-07-26; просмотров: 227; Нарушение авторских прав




Мы поможем в написании ваших работ!
lektsiopedia.org - Лекциопедия - 2013 год. | Страница сгенерирована за: 0.003 сек.