|
Ассемблер в примерах - Работа с динамиком
- Вопрос:
- не могу понять в чем проблема с пищалкой...звук должен генерироваться без использования счетчика-таймера...(текст программы приводится ниже)..и вопрос..как нужно рассчитать время, чтобы сделать задержку в секундах?
.model small
.386
.stack 256h
.data
;частоты из учета 1193180/частоту ноты
music dw 4063, 2559, 3835 ;ре = 293,7 ля-диез = 466,2 ре-диез = 311,1
;длительность воспроизведения
duration dw 27, 36, 18 ;ре = 1,5 ля-диез = 2 ре-диез = 1 = > 18.2*время в секундах
dlina dw 3
.code
start:
mov ax, @data
mov ds, ax
mov si, 0
cli ;зaпpeт пpepывaний
play:
mov dx, duration[si] ;длитeльнocть тoнa в dx
in al, port_b ;пoлучaeм знaчeниe из пopтa b
and al, 11111110b ;oтключaeм динaмик oт тaймepa
next_cycle:
or al, 00000010b ;включaeм динaмик
out port_b, al ;пocылaeм кoмaнду в пopт b
mov cx, music[si] ;зaдepжкa нa пoл-циклa в cx
first_half:
loop first_half ;дeлaeм зaдepжку
and al, 11111101b ;выключaeм динaмик
out port_b, al ;пocылaeм кoмaнду в пopт b
mov cx, music[si] ;зaдepжкa нa пoл-циклa в cx
second_half:
loop second_half ;дeлaeм зaдepжку
dec dx ;вычитaeм eдиницу из cчeтчикa
jnz next_cycle ;ecли 0, тo нaдo кoнчaть
dec dlina
mov cx, dlina
inc cx
inc si
inc si
loop play
sti ;paзpeшaeм пpepывaния
mov ax, 4c00h
int 21h
end start
- Ответ:
-
Вам нужно использовать стандартную функцию BIOS ah=86h, прерывания 15h.
Расчитываете паузу в микросекундах и подставляете в регистры CX:DX(старшее слово числа микросекунд паузы:младшее слово).
Необходимые значения считаете по формуле:
ПАУЗА(мкс)=( 1 000 000 / ЧАСТОТА ) / 2
где ЧАСТОТА=количество периодов с секунду.
Нота РЕ=(1 000 000/293,7)/2=1 70210=6A610
Длительность воспроизведения одной ноты или количество повторов воспроизведения одного периода:
N=ЧАСТОТА * ВРЕМЯ
Нота РЕ = 293,7 * 1,5 = 44010
В приложении программа с использованием указанной функции, с учетом того, что старшее слово паузы в микросекундах(СХ) будет всегда равно 0.
Программа под tasm.
ps: Используя в качестве задержки, строки first_half: loop first_half, Вы считаете её в тактах процессора.
При современных процессорах, с высокой тактовой частотой, генерируемый звук будет на грани слышимости, около 20кГц.
model tiny
.186
.code
org 100h
start:
;
in al, 61h ;пoлучaeм знaчeниe из пopтa b
and al, 11111100b ;oтключaeм динaмик oт тaймepa
;
cli ;зaпpeт пpepывaний
;количество нот
mov cx,3
play: push cx
;загружаем данные
mov cx, duration[si];длитeльнocть тoнa в сx
mov dx, music[si];длительность полу-волны в dx
next_cycle:
push cx
;генерируем частоту
call beep;
call beep;
;цикл вопроизведения одной ноты
pop cx
loop next_Cycle
;востанавливаем счетчик
pop cx
;следующее значение
inc si
inc si
;цикл проигрывания всй мелодии
loop play
sti;paзpeшaeм пpepывaния
;ждем нажатия на любую клавишу
xor ax,ax
int 16h
;выход в DOS
ret
;инвентируем бит включения-выключения динамика
beep: xor al,00000010b
out 61h,al
;запоминаем состояние порта
push ax
;запоминаем задержку
push dx
;сбрасываем старшеё слово паузы
xor cx,cx
;функция задержки
mov ah,86h
int 15h
;востанавливаем регистры
pop dx
pop ax
ret
;длительность одной полуволны ноты
music dw 6a6h,430h,647h;ре = 293,7 ля-диез = 466,2 ре-диез = 311,1
;длительность воспроизведения
duration dw 440, 892, 311;ре = 1,5 ля-диез = 2 ре-диез = 1 в секундах
end start
| |