Лабораториялық жұмыс №14.

Тақырып: Сыртқы құрылғылармен аудиоинтерфейсы арқылы және дыбыстық картамен жұмыс.

Жұмыс мақсаты: студенттерді бағдарламалық деңгейде дыбыспен жұмыс істеуді үйрету.

Теориялық мәліметтер:

Дыбыс генерациясы интерфейс адаптері арқасында В порты бит жиілікпен 8255 сырттағымен қосуда және сөнуден тұрады, динамикапен байланысты (бит1). В порты 61H ие болады (бірақ АТ интерфейс микросхемалары 8255 сырттағы такті сияқты болмайды, ол бұл мақсат үшін сол порт адресі және сол бит қолданады). Егер бағдарлама максималды мүмкін жиілікпен бит мағынасын ауыстырса, онда жиілік өте жоғары, пайдалы болу үшін. Сондықтан екі ауыстырып қосулар аралығында екі бос цикл салу керек. Есте сақтаңыздар, В портының 0 бит таймер 2 микросхемасын канал қақпаларымен басқарады, яғни өз өз кезегінде динамикапен байланысты. Бұл сондықтан бит лақтырылған болу тиісті, таймер каналынан ажыратады.

Келесі мысалда екі айнымалы енгізілген. Бірі, "FREQUENCY" көрсетілген, қосу және өшіру әрекеттері арасында бос циклда есепші ретінде қолданылады. Мағына неғұрлым аз болса, соғұрлым бит және жиілік өзгерту жылдам болады. "NUMBER_CYCLES" айнымалысы, тон ұзақтығы орнатады. Ол қосу және өшіру процессі қанша рет қайталанғанын айтады. Неғұрлым саны көп болса, соғұрлым берілген дыбыс ұзағырақ дыбыс шығарады.

Бұл процедура үшін аппараттық үзу тиым салынған болу тиісті. Себебі, таймер үзуі сондай жиілікпен және жүйелілікпен орындалады (секундына 18.2 рет), ол жиілікке маңызды әсер етеді. Әзірше үзу тиым салынғанда, BIOS тәулік уақыттының есепшісі жұмыс істемейді. Егер содан соң мағынасын оқып шықса, онда ол нақтыдан кейбір өлшемінде ажыратылады, яғни сәйкес өзгерту істелгенше дейін.

NUMBER_CYCLES EQU 1000

FREQUENCY EQU 300

PORT_B EQU 61H

CLI ; үзулерге тиым салынған

MOV DX,NUMBER_CYCLES ;DX тон ұзақтығы

IN AL,PORT_B ;B портынан мағына аламыз

AND AL,11111110B ;динамикаті таймерден ажыратымыз

NEXT_CYCLE: OR AL,00000010B ;динамикаті қосамыз

OUT PORT_B,AL ;B портқа команданы жібереміз

MOV CX,FREQUENCY ;CX жарты циклда тоқтау

FIRST_HALF: LOOP FIRST_HALF ; тоқтауды істеймыз

AND AL,11111101B ;динамикаті өшіреміз

OUT PORT_B,AL ; B портқа команданы жібереміз

MOV CX,FREQUENCY ; жарты циклда тоқтау CX SECOND_HALF: LOOP SECOND_HALF ; тоқтауды істеймыз

DEC DX ;есепшіден бірлікті оқимыз

JNZ NEXT_CYCLE ;егер 0, онда аяқтау керек

STI ;үзулерге рұқсат етеміз

Дыбыс генерациясы басқа әрекеттермен біруақытта болады.

2 каналға есепші жіберіңіздер. В порт арқылы алдын ала микросхема рұқсат етілген болуға тиісті микросхема интерфейсі 8255 сырттағымен (адрес 61H). Жылжытуға арналған есепші қойылатын талап мағынасын есептеңіздер, 1.19 миллиондардың талап қойылатын жиілікке герцтерде бөлу. Дыбыс 2 каналдағы қақпалар жабық болғанша созылады. Сондықтан В портындағы бит 1 - бит 0 түсіру тиістісіз, әйтпесе дыбыс шексіз созылады және компьютерді қайта жүктеумен ғана тоқтатылуы мүмкін. Дыбыс ұзақтылығын дәл теңгеру үшін BIOS тіулік уақыттарының есепшісін қолдануға болады. Берілген мысалда жиілік 440 герц генерацияланады. Дыбыс пернетақтадан кез келген пернені басудан кейін тоқталады.

;---В портына 8255 микросхемасын орнатуда 2 канал рұқсаты

PORT_B EQU 61H ; В портының адрестерін орнату

IN AL,PORT_B ; оның мағынасын оқу

OR AL,3 ; екі кіші биттерді орнату

OUT PORT_B,AL ;В портына байтты жібереміз;---енгізу/шығару регистрлерін орнату

COMMAND_REG EQU 43H ; командалық регистр адресі

CHANNEL_2 EQU 42H ;2 канал адресі

MOV AL,10110110B ;2 канал үшін биттер тізбегі

OUT COMMAND_REG,AL ;командалық регистрге жіберу ;---жылжытуға есепші жіберу

MOV AX,2705 ;есепші= 1190000/440

OUT CHANNEL_2,AL ;кіші байтты жібереміз

MOV AL,AH ;AL кіші байтты жылжытамыз

OUT CHANNEL_2,AL ;үлкен байтты жібереміз;---пернені басуды күтеміз

MOV AH,1 ;21H үзулер функциясының номері

INT 21H ;үзулерді шақытамыз;---дыбыстың өшірілуі

IN AL,PORT_B ; В портынан байтты аламыз

AND AL,11111100B ; екі кіші битті түсіреміз

OUT PORT_B,AL ; байтты қайтадан жібереміз

Динамика гудогі.

Қарапайым гудок үшін жақсысы, микросхема интерфейсі сырттағымен 8255 негізін қолданатын әдіс жақын келеді. Төменде қайталайтын гудок мысалы келтірілген, сіздер оныжүйе стартында естисіздер.

;---динамика гудогі

MOV DX,800 ;циклдер санының есепшісі

IN AL,61H ;читаем порт B 8255

AND AL,0FEH ;8253 таймер битін өшіреміз

NEXTCYCLE: OR AL,2 ;динамика битін қосамыз

OUT 61H,AL ;B портына байтты жібереміз

MOV CX,150 ;бірінші жарты ұзақтығы

CYCLEUP: LOOP CYCLEUP ;әзірше тоқтау сигналы жоғары

AND AL,0FDH ;динамика битін өшіреміз

OUT 61H,AL ; B портына байтты жібереміз

CYCLEDOWN: LOOP CYCLEDOWN ; әзірше тоқтау сигналы төмен

DEC DX ;циклдар есепшісін кемітеміз

JNZ NEXTCYCLE ;әзірша циклді өайталаймыз DX емес 0

Тон жинағының генерациясы.

Дыбыс генерациясына арналған мысалда 8253 таймер микросхемасы қолданылады, мұнда 8 нота орындалады, бірақ кішкене модификация бұл процедура мүмкіншіліктері күшті кеңейти алады. Берілгендердің үш жол болады. Біріншісі, әрбір нота ұзақтығын орнатыды, өз бетімен тоқтау периоды сияқты (бұл тоқтаук периодын өзгертіп, темп өзгертуге болады). Екінші жол әрбір жиілікте 8 нотаны құрады; бұл мағыналар қалайтын тон үшін 2 канал 8253 микросхема каналда регистр жылжытуға орналастырылған болады. Үшінші жол, код нөмірлері 1-ден 8 дейін түріндегі әуендерден тұрады, яғни сегіз жиіліктің талапқа сай болады. Бұл жол 0FFH кодпен аяқталынады, әуеннің соңының белгісімен қызмет етеді. Әуеннің кезек нотасын оқитын процедура, сәйкес жиілікті тауып, оны 2 каналға орналастырады. Содан соң бүл нотаға арналған ұзақтық цикл тоқтау есепшісіне орналаса бастайды тәуліктуақыттардың есепшісі қолданады, ал қашан тоқтау бітеді, онда келесі нота өңдеуіне өтеміз.

;---берілгендер сегментінде

BEAT DB 10,9,8,7,6,5,4,3,2 ;ноталар ұзақтығы

FREQUENCY DW 2280,2031,1809,1709 ;жиіліктер кестесі

DW 1521,1353,1207,1139 ;

MELODY DB 1,2,3,4,5,6,7,8,0FFH ; ноталар жиіліктерінің номері

;---инициализация

PORT_B EQU 61H

COMMAND_REG EQU 43H

LATCH2 EQU 42H

IN AL,PORT_B ; ағымдағы статусты аламыз

OR AL,00000011B ;динамика және таймерді рұқсат етеміз

OUT PORT_B,AL ;байтты ауыстырамыз

MOV SI,0 ;көрсеткішті инициализациялаймыз

MOV AL,0B6H ;2 канал үшін орнату

OUT COMMAND_REG,AL ;командалық регистрді жібереміз ;---нотаға қараймыз, оның жиілігін аламыз және 2 каналға орналастырамыз

NEXT_NOTE: LEA BX,MELODY ;әуен үшін қызматтен алу

MOV AL,[BX][SI] ;жол нотасның n-ші кодын аламыз

CMP AL,0FFH ;жол соңын тексеру

JE NO_MORE ;егер соңы болса, онда шығуға

CBW ;сөзге аударамыз

;жиілікті алуы

MOV BX,OFFSET FREQUENCY ;кестелер жиілігін қызметтен алу

DEC AX ;0-ден есепті бастаймыз

SHL AX,1 ;2-ге көбейтемез, өйткені сөздің

MOV DI,AX ;DI арқылы адрестейміз

MOV DX,[BX][DI] ;кестеден жиілікті аламыз

;нотаны орындауды бастаймыз

MOV AL,DL ;жиіліктің кіші байтын дайындаймыз

OUT LATCH2,AL ;оны жібереміз

MOV AL,DH ; жиіліктің үлкен байтын дайындаймыз

OUT LATCH2,AL ;оны жібереміз;---цикл тоқтаудың құрылуы

MOV AH,0 ;есепшіні оқу функциясының номері

INT 1AH ;есепші мағынасын аламыз

MOV BX,OFFSET BEAT ;кестелер ұзындығын қызметтен алу

MOV CL,[BX][SI] ;кезекті нотаның ұзындығын аламыз

MOV CH,0 ;

MOV BX,DX ;есепшінің кіші сөзін аламыз

ADD BX,CX ;аяқтау кезеңін анықтаймыз

STILL_SOUND: INT 1AH ; есепші мағынасын аламыз

CMP DX,BX ; соңғысымен салыстырамыз

JNE STILL_SOUND ;тең емес – дыбысты жалғастырамыз

INC SI ;келесі нотаға өтеміз

JMP NEXT_NOTE ; ;---аяқтау

NO_MORE: IN AL,PORT_B ; В портының статусын аламыз

AND AL,0FCH ;динамикаті өшіреміз

OUT 61H,AL ;байтты ауыстырамыз

Тапсырма:

2 секунды ұзақтықпен динамика көмегімен дыбыс құратын бағдарламаны жазыңыздар.

Динамика гудогін құратын бағдарламаны жазыңыздар.

Дыбыс сиренасына еліктейтін бағдарламаны жазыңыздар.

«Бумер» типті әуен құратын бағдарламаны жазыңыздар.

Әдебиет: 10, бет.54-62; 23, бет.85-92; 8, бет.23-32.

Бақылау сұрақтар

1. Дыбыс генерациясы басқа әрекеттермен бір уақытта қалай болады ?

2. Динамика гудогін қалай орындау керек?

3. Қандай микросхема динамика үшін жауап береді?