|
 |
|
MENU |
|
|
|
|
|
 |
|
OBSŁUGA GŁOŚNIKA |
|
|
|
|
|
|
|
|
|
|
|
W tej części kursu poznamy metody generowania dźwięku z głośniczka(PC SPEAKER)
Za generowanie dźwięku odpowiada układ programowalnych portów równoległych 8255. Składa się on z trzech portów :
Nas interesuje tylko generator częstotliwości czyli port B. Port ten ma następującą strukturę:
Bity 0 i 1 uruchamiają lub zatrzymują generowanie dźwięku. Bit 0 zatrzymuje lub uruchamia licznik, natomiast bit 1 blokuje bądź odblokowuje bramkę AND głośnika. Aby głośnik działał w porcie B obydwa najmłodsze bity powinny mieć wartość 1. Nie wolno naruszać pozostałych bitów portu B. Do załączenia i wyłączenia głośnika użyjemy masek OR i AND.
Np. załączenie głośnika można wykonać następującym fragmentem kodu:
MOV DX,61H
IN AL,DX
OR AL,00000011B;Maska OR
OUT DX,AL
Aby wyłączyć głośnik wystarczy w trzeciej linijce zamiast maski OR użyć maskę AND: AND AL,11111100B
Drugi układ który przyda się do wygenerowania dźwięku to układ 8253/4 czyli zegar-licznik. Składa się on z trzech niezależnych liczników do których doprowadzany jest sygnał prostokątny CLK o częstotliwości 1.19MHz. Każdy z liczników uaktywniany jest bramką. Licznik generatora 0 - o adresie 40H(48H) służy do odmierzania impulsów zegarowych co 1/18 sekundy. Licznik generatora 1 - o adresie 41H(49H) wywołuje przerwanie do odświeżania pamięci RAM. Licznik generatora 2 - o adresie 42H(50H) odpowiada za głośnik. Uaktywniany jest bramką G2 która jest podłączona do zerowego bitu portu B. Licznik 2 dzieli częstotliwość 1.19MHz przez podany podzielnik co w efekcie daje nam żądaną częstotliwość wyjściową na głośniku. Maksymalny podzielnik to 65536 który daje nam 18Hz a minimalny to jeden który nie zmienia częstotliwości. Żeby obliczyć podzielnik np. 33Hz trzeba:
podzielnik:=1140000 / 33
podzielnik:=34546
załóżmy że chcemy wygenerować dźwięk o częstotliwości 33Hz.
MOV AX,34546
MOV DX,42H
OUT DX,AL
MOV AL,AH
OUT DX,AL
Każdy dźwięk musi mieć swój czas trwania. Czas odmierzamy za pomocą funkcji 86H przerwania 15H. Czas ten jest podawany w mikrosekundach(1/1000000) na słowie 32-bitowym czyli na dwóch rejestrach 16 bitowych. Czas można wyrazić wzorem czas := DX + (65536*CX).
Np. jeśli chcemy by coś trwało przez 0.5 sekundy powinniśmy wykonać następujący fragment kodu: MOV CX,7
MOV DX,41248
MOV AH,86H
INT 15H
Aby zapisać melodię potrzebne są nuty, mają one określone częstotliwości w różnych oktawach. Te same nuty w wyższej o 1 oktawie mają dwukrotnie większą częstotliwość.
|
C
|
D
|
E
|
F
|
G
|
A
|
H
|
1 |
33
|
37
|
41
|
44
|
49
|
55
|
62
|
2 |
65
|
73
|
82
|
87
|
98
|
110
|
123
|
3 |
131
|
147
|
165
|
175
|
196
|
220
|
247
|
4 |
262
|
294
|
330
|
349
|
392
|
440
|
494
|
5 |
523
|
587
|
659
|
698
|
784
|
880
|
988
|
6 |
1047 |
1175 |
1319 |
1397 |
1568 |
1760 |
1976 |
7 |
2093 |
2349 |
2637 |
2794 |
3138 |
3520 |
3951 |
Teraz przedstawię przykładowy program który wygrywa (nieco fałszuje) melodię. Każda nuta zapisana jest w trzech tablicach : wysokości,oktawy i czasu trwania.
;podzielniki czestotliwosci
TC equ 34546; 1.19MHz/33Hz
TD equ 30811; 1.19MHz/37Hz
TE equ 27805; 1.19MHz/41Hz
TF equ 25909; 1.19MHz/44Hz
TG equ 23265; 1.19MHz/49Hz
TA equ 20727; 1.19MHz/55Hz
TH equ 18387; 1.19MHz/62Hz
TP equ 1;pauza
;Q koniec melodii
kod segment
assume cs:kod,ss:stosik,ds:dane;
; ******************************************************
; * PROCEDURY *
; ******************************************************
initgraph proc
mov al,013H
mov ah,00h
int 10h
ret
endp
closegraph proc
mov al,03H
mov ah,00h
int 10h
ret
endp
Putpixel proc
mov ah,0Ch
mov al,kolor
mov bx,0;
mov cx,x
mov dx,y
int 10h
ret
endp
linia proc
mov x,0
l1: call putpixel
inc x;
cmp x,30;
jne l1;
ret
endp
flaga proc
mov kolor,7;
mov y,1
call linia;
mov kolor,15;
mov y,2
call linia;
mov y,3
call linia;
mov y,4
call linia;
mov y,5
call linia;
mov kolor,12;
mov y,6
call linia;
mov y,7
call linia;
mov y,8
call linia;
mov y,9
call linia;
mov kolor,4;
mov y,10
call linia;
ret
endp
nuta proc
push dx;
push cx;
mov cx,7;
mov dx,65535;
mov ah,86h;
int 15h
pop cx
pop dx
ret
nuta endp;
polnuta proc
push dx;
push cx;
mov cx,3;
mov dx,65535;
mov ah,86h;
int 15h
pop cx
pop dx
ret
polnuta endp;
cwiercnuta proc
push dx;
push cx;
mov cx,1;
mov dx,65535;
mov ah,86h;
int 15h
pop cx
pop dx
ret
cwiercnuta endp;
osemka proc
push dx;
push cx;
mov cx,0;
mov dx,32000;
mov ah,86h;
int 15h
pop cx
pop dx
ret
osemka endp;
sound proc
mov ax,ton
mov dx,42h
out dx,al
mov al,ah
out dx,al
;zalaczenie glosnika
mov dx,61h
in al,dx;
or al,00000011B;
out dx,al;
ret
endp
nosound proc
mov dx,61h
in al,dx;
and al,11111100B;
out dx,al;
ret
endp;
play proc
call sound
cmp czas,1
je cala
cmp czas,2
je pol
cmp czas,4
je cwierc
cmp czas,8
je acht
jmp endplay
cala: call nuta
jmp endplay
pol: call polnuta
jmp endplay
cwierc: call cwiercnuta
jmp endplay
acht: call osemka
jmp endplay
endplay:
call nosound
ret
endp
;--------------------------------------------------------------------
start: mov ax,dane
mov ds,ax
mov ax,stosik
mov ss,ax
mov sp,offset szczyt
mov si,0;
call initgraph;
call flaga;
melodia: lea bx,nuty
mov dl,ds:[bx+si]
cmp dl,'Q'
je exit
cmp dl,'C'
je do
cmp dl,'D'
je re
cmp dl,'E'
je mi
cmp dl,'F'
je fa
cmp dl,'G'
je so
cmp dl,'A'
je la
cmp dl,'H'
je Zi
mov ton,1
;wprowadzenie oktawy
graj:
lea bx,oktawy
mov cl,ds:[bx+si]
sub cl,30h
shr ton,cl;
lea bx,czasy
mov cl,ds:[bx+si]
sub cl,30h
mov czas,cl
call play;
inc si;
jmp melodia;
do: mov ton,TC
jmp graj
re: mov ton,TD
jmp graj
mi: mov ton,TE
jmp graj
fa: mov ton,TF
jmp graj
so: mov ton,TG
jmp graj
la: mov ton,TA
jmp graj
zi: mov ton,TH
jmp graj
exit:
call closegraph;
mov ah,4ch
mov al,00h
int 21h;
kod ends;
dane segment
nuty db 'HCDDDEDCHAADCCHPHCDDDEDCHAADGAFPAACCHCCCEEDHDGFFECDCFAGPQ'
oktawy db '344444443334443034444444333433303344344444434333444433300'
czasy db '442444444442422244244444444242212242222442224242244242210'
ton dw 0
czas db 0
x dw 0
y dw 0
kolor db 0
dane ends
stosik segment
dw 100h dup(0)
szczyt label word
stosik ends
end start
Oprócz odgrywania muzyki , możemy także grać własne kompozycje na klawiaturze. Na poprzedniej lekcji poznaliśmy jak obsługiwać klawiaturę teraz połączymy tą umiejętność z obsługą głośnika.
Dane SEGMENT
Ton DB 0
CRLF DB 13,10,'$' ; kody sterujace przejscia do nastepnej lini i powrotu karetki
LRXY DW 184fh ; 18h=24d; 4f=79d; wspolrzedne prawego dolnego rogu ekranu 80x25
Komunikat DB 'Nacisnij klawisz ESC zeby zakonczyc program ...','$'
Dane ENDS
Kod SEGMENT
assume CS:kod, DS:Dane
Main PROC
Start :
mov AX,Dane
mov DS,AX
call ClrScr
mov DX, 0200h
call GotoXY
lea DX, Komunikat
call Write
Play : mov AH,10H ; czytaj znak z klawiatury
int 16H ; w AL - kod ASCII, w AH - kod klawisza
mov Ton,AL ; sprawdzam klawisz ESC
sbb Ton,27
jz Koniec
call Sound
jmp Play
Koniec : ; zakonczenie programu
mov AH,4ch ; wybor uslugi zakonczenia programu
mov AL,0
int 21h ; wywolanie przerwania DOS
GotoXY PROC
mov AH,02H ; usluga VIDEO nr2: ustawianie kursora
mov BH,0 ; podstawowa strona wyswietlania (nr0)
int 10h ret ; powrot do miejsca wywolania
GotoXY ENDP
ClrScr PROC
mov CX,0 ; wspolrzedne gornego lewego rogu ekranu
mov DX,LRXY ; wspolrzedne dolnego prawego rogu ekranu
mov AL,0 ; czyszczenie okna (0)
mov BH,07h ; mormalny atrybut dla pustego wiersza
mov AH,06h ; usluga VIDEO nr 6: czyszczenie/przesuwanie
int 10h
mov DX,0
call GotoXY
ret ; powrot do miejsca wywolania
ClrScr ENDP
Write PROC
mov AH,09h
int 21h
ret
Write ENDP
WriteLn PROC
call Write
mov DX,offset CRLF
call Write
ret
WriteLn ENDP
ReadKey PROC
mov AH,08h
mov AL,0
int 21h
ret
ReadKey ENDP
Sound PROC
mov AL, 10110110B ; generator w trybie '3'
out 43H, AL
mov AL, 169
out 42H, AL
mov AL, Ton
out 42H, AL
in AL,61H ; wczytaj zawartos portu B8255
or AL,00000011B ; ustaw bity 0 i 1
out 61H,AL ; wyslij do 61h
mov CX,0FFFFH
p1: nop
push CX
mov CX,0FFH
p2: nop
dec CX
jnz p2
pop CX
dec CX
jnz p1
in AL,61H ; wylacz dzwiek
and AL,11111110B
out 61H,AL
ret
Sound ENDP
Main ENDP
Kod ENDS
END Start ; rozpoczecie programu od etykiety Start
Teraz masz do dyspozycji potężne narzędzia programistyczne : wyświetlanie na ekranie,obsługa klawiatury oraz wydawanie dźwięków z komputera. Jak je wykorzystasz zależy od Twojej inwencji. W kolejnych częściach tego kursu poznamy możliwości trwałego zapisu danych , modyfikacji daty, czasu a także bardziej zaawansowany dostęp do zawartości ekranu .
|
Teraz 11190 odwiedzający (26010 wejścia) |
|
|
|
|
|
 |
|
Logowanie |
|
|
|
|
|
|
|
|
|
|