Разработка программы воспроизведения мелодии

Автор: Пользователь скрыл имя, 14 Марта 2012 в 18:49, курсовая работа

Описание работы

Целью данной разработки является создание программы, которая будет являться электронной моделью музыкальной шкатулки, воспроизводящей MIDI мелодии, т.к. учебный стенд имеет плоский синтезатор. А также освоение архитектуры и методов проектирования на базе микроконтроллера ADuC812 с ядром MCS–51.
Для разработки музыкальных продуктов программист должен быть музыкантом, акустиком и радистом одновременно или нужна группа, объединяющая таких специалистов и, что очень важно, говорящих на одном языке.

Содержание

ВВЕДЕНИЕ 3
ТЕХНИЧЕСКОЕ ЗАДАНИЕ 5
ВВЕДЕНИЕ 6
1 ОСНОВАНИЕ ДЛЯ РАЗРАБОТКИ 6
2 НАЗНАЧЕНИЕ РАЗРАБОТКИ 6
3 ТРЕБОВАНИЯ К РАЗРАБОТКЕ 6
3.1 Требования к функциональным характеристикам 6
3.2 Нижний уровень 7
3.3 Верхний уровень 9
3.4 Требования к надежности 10
3.5 Требования к информационной и программной совместимости 11
3.6 Требования к условиям эксплуатации 13
3.7 Требования к составу и параметрам технических средств 13
4 РАЗРАБОТКА СТРУКТУРНОЙ СХЕМЫ 14
5 РАЗРАБОТКА ФУНКЦИОНАЛЬНОЙ СХЕМЫ 15
6 ТЕХНИКО-ЭКОНОМИЧЕСКИЕ ПОКАЗАТЕЛИ 16
7 ЭТАПЫ И СТАДИИ ПРОЕКТИРОВАНИЯ 16
8 ОПИСАНИЕ СТЕНДА SDK 1.1. 17
9 ПРИНЦИП ФОРМИРОВАНИЯ ЗВУКА 20
10 ОПИСАНИЕ ПРОГРАММЫ 21
10.1 Режим начальной инициализации 21
10.2 Основной режим работы 23
ПРИЛОЖЕНИЕ 1 28
ПРИЛОЖЕНИЕ 2 29

Работа содержит 1 файл

МУЗ.ШКАТУЛКА.docx

— 808.86 Кб (Скачать)
"text-align:center">
 Рис.15  Алгоритм опроса клавиатуры

Рис.16  Алгоритм обработки нажатия клавиши «1»

Воспроизведение мелодии сводится к генерации  последовательности импульсных сигналов определенной звуковой частоты в  течении определенных интервалов времени.  Для этого используются два счетчика Т/С1 – отвечающий за формирование сигнала  и Т/С0 – за формирование интервала  звучания ноты. Звуковой сигнал формируется  путем инвертирования R1.  Вначале  в Т/С0 необходимо загрузить число 62 500 для получения задержки 1/16с.  При переполнении Т/С0 производится уменьшение счетчика интервала периода.

При нажатии на клавишу  «1» программа должна проигрывать загруженную мелодию (см. рис. 16).  В это время любые другие прерывания игнорируются. По окончанию воспроизведения мелодии,  можно повторно ее проиграть, для этого следует нажать на клавишу «1». 

Рис.17  Алгоритм воспроизведения мелодии

 

 

Приложение 1

Принципиальная схема

Приложение 2

org 2000H         

LJMP START

ORG 200bh ;прерывание от нулевого таймера-счетчика

LJMP kl

ORG 2023h ;прерывание от порта

LJMP cin

    

DPP equ 84h   ;регистр управления портами ввода-вывода, звуком и сигналом INT0

arm5 equ 20h

 

org     2100H         

 

START: 

    mov DPP,#08h 

mov r0, #00h

mov r1, #00h

mov r2, #0ffh  ;адрес по которому будем считывать данные  

mov r4, #00h

mov r5, #00h   

mov r6, #00h

mov r7, #00h

mov 08h, #0ffh

mov 09h, #10000000b ; хранится адрес для курсора ЖКИ

mov 0ah, #00h

mov 0bh, 00h   ; после дребезга

mov 0ch, 00h

mov 0dh, #00h

mov 0eh, #00h

mov 0fh, #11111110b

mov 11h, #00h

mov 12h, #0ffh

mov 15h, #00h

mov 16h, #00h

mov 18h, #00h

mov 13h, #00h

mov 1ah, #00h

 

lcall set_JK

lcall wait

 

mov SCON, #01010000b ; для настройки порта, 4 - бит разрешения приема данных, 6 - бит управления режимом УАПП(01-8 бит, изменяемая скорость передачи)

mov TMOD, #00100001b ; ТО - 1й режим, Т1 - 2й режим  

mov TL0, #low(NOT(11111111b))

mov TH0, #high(NOT(00011110b))

mov TH1, #0FDh

mov TL1, TH1

mov IP, #00010010b ; ставим приоритеты для Т0 и для порта  

mov IE, #10010000b ; разрешение прерывания от порта 

      mov TCON, #01000000b ; запуск Т1

     

ljmp $

                  

sound:

 

mov TMOD, #00010001b ; оба счетчика в 1м режиме

mov IE,   #00000000b                           

s_:      

 

 

_s: inc r2   ;длительность

mov DPP, #07h

mov DPH, #00h

mov DPL, r2  ; в r2 хранится адрес по которому будем считывать данные

movx a, @dptr

mov DPP, #08h

subb a, #2fh 

 

cjne a, #022h, __s

mov r2, #0ffh

lcall stop

 

mov SCON, #01010000b

mov TMOD, #00100001b

mov TH1, #0FDh

mov TL1, TH1

mov IE,   #10010010b

mov TCON, #01000000b

ljmp kl

 

__s: rl a

mov 12h, a  ; сохраняем длительность

 

inc r2   ;мелодия

mov DPP, #07h

mov DPH, #00h

mov DPL, r2

movx a, @dptr

mov DPP, #08h

subb a, #2fh

mov r0, a  ; сохраняем мелодию

 

s__:

clr TCON.4

mov TL0, #LOW(NOT(62500)+1) 

mov TH0, #HIGH(NOT(62500)+1) 

setb TCON.4

s:

mov DPTR, #04h

mov a, r1

movx @DPTR, a

cpl a

mov r1, a

 

jbc TCON.5, s1

clr TCON.6

 

mov a, r0

mov dptr, #table2

movc a, @a+dptr

mov TL1, a

 

mov a, r0

mov dptr, #table1

movc a, @a+dptr

mov TH1, a

 

setb TCON.6

s0:

jbc TCON.7, s

ljmp s0

s1:

djnz 12h, s__ 

 

ljmp s_

 

set_JK:

mov a, #00111000b ;натсраиваем дисплей

mov dptr, #01h

movx @dptr, a

lcall com

lcall flag_E

      lcall proverka_BF

     

mov 0dh, #00000001b

 

sd: mov a, 09h   ;сдвиг курсора

mov dptr, #01h

movx @dptr, a

lcall com

lcall flag_E

      lcall proverka_BF

      ret

 

date: mov dptr, #06h

mov a, #00000101b

movx @dptr, a

mov a, #00000100b

movx @dptr, a

RET 

 

 

com: mov dptr, #06h  ;Для ЖК фиксировать команды

mov a, #00000001b

movx @dptr, a

mov a, #00000000b

movx @dptr, a

ret

 

proverka_BF:

mov dptr, #06h

mov a, #00000011b ;чтение

movx @dptr, a

 

mov dptr, #01h

movx a, @dptr ;ч0 то считывает

mov 14h, a

mov dptr, #06h

mov a, #00000010b

movx @dptr, a

 

mov a, 14h

anl a, #10000000b

jnz proverka_BF

ret

 

flag_E: 

mov dptr, #06h

mov a, #00000101b

movx @dptr, a

mov a, #00000100b

movx @dptr, a

      ret

 

clear:

mov a, #01h

mov dptr, #01h

movx @dptr, a

lcall com

lcall flag_E

      lcall proverka_BF

      ret

 

simvol:

mov dptr, #01h

movx @dptr, a

lcall date

lcall flag_E

      lcall proverka_BF

      ret

    

cin:   ; проверка на наличие данных

jnb RI, f     ;флаг ri    

      mov A, SBUF   ;берем с буфера данные

      clr ri

mov 17h, a   ;сохраняем то что приняли

 

mov a, 01h   ;еще один флаг, который говрит что данные щас идут или нет

      cjne a, #00h, da_ 

     

      mov a , 17h

      cjne a, #0ach, f  ;это если начало пакета

mov 01h, #01h  ;ставим флаг, что потом пойдут данные

ljmp f

 

da_:

mov a, 17h   ;если конец пакета

cjne a, #0f0h, da1_  ;если нет, то это норм данные и записываем их

ljmp end_pac

 

da1_: 

XRL a, 18h   ;провряем контрольную сумму (считаем сложением по модулю 2)

mov 18h, a

mov a, 17h

inc 08h  ; двигаемся по адресному пространству

      mov DPP, #07h ; записываем данные во внешнюю память

      mov DPH, #00h

      mov DPL, 08h

      movx @DPTR, A

      movx A, @dptr

      mov DPP, #08h

      clr ri

      reti

 

f: clr ri

reti

 

e: inc 08h

 

clr ri

reti     

 

end_pac:

mov 09h, #10000000b

lcall sd

clr ri

dec 08h  ; затираем контрольную сумму

mov a, 18h   ; сравнивается ту сумма которая пришла и которая образовалась у нас

cjne a, #00h, er ;переход если не равно 0

 

mov 01h, #00h

mov 18h, #00h

 

dec 08h       ; проверяем, конец ли данных

mov DPP, #07h

mov DPH, #00h

mov DPL, 08h

movx a, @dptr

mov DPP, #08h

 

cjne a, #51h,e     ;приходит 51 которое говорит что это конец текста

lcall read

clr TCON.6    ; останавливаем Т1

mov TMOD, #00000001b ; выставляем 1й режим Т0

mov IE,   #10000010b 

 

inc 08h

ljmp kl

 

er:

clr ri

mov DPTR, #07h

mov a, #1000000b

movx @DPTR, a

mov 01h, #00h

reti

 

kl:     ;в этой прцедуре мы опрашиваем клавиатуру

mov a, 0ch  ;когда 0 - значит клавиша нажата первый раз

cjne a, #00000000b, key 

 

mov a, 0fh

mov DPTR, #00000h

movx @DPTR,A ; заносим данные

      movx A, @DPTR ; считываем данные

mov R3,A  ; сохраняем

      ANL a, #11110000b

      CJNE A, #11110000b, zad_dr   ;есть ли нажатая клавиша?

      LJMP zad_30       ;сюда если нет

     

zad_dr:      ;задержка дребезга

    mov TL0, #LOW(65280)

mov TH0, #HIGH(65280)

mov 0ch, #00000001b

mov TCON, #01010000b

      reti

 

key:      ;снова опрашиваем клавиатуру

 

mov 0ch,#00000000b

mov a, 0fh

mov DPTR, #00000h

movx @DPTR,A

      movx A, @DPTR

mov 0bh, a

cjne a, 03h, scan  ;сравниваем до и после, если нет то снова на скан

mov 0eh, #01h   ;флаг! вообще нажатая клавиша срабатывает когда ее отпускают

ljmp scan

 

inc1:         ;цикл прогоняем с клавиатурой, когда нолик прогоняем для опроса

mov a, 0fh

RL a

mov 0fh, a

inc 11h

LJMP kl

 

scan:      ;кажые 30 секунд опрос

mov 11h, #0h

mov 0fh, #11111110b

mov TL0, #LOW(35280)

mov TH0, #HIGH(35280)

mov TCON, #01010000b

reti

 

zad_30:

mov a, 11h     

CJNE a, #03h, inc1  ;проверяем чтобы цикл опроса был сделал 4 раза

 

mov a, 0eh    ;была ли нажата какая-либо клавиша

cjne a, #01h, scan 

 

mov a, 0bh    ;проверка на нажатие именно "1"

cjne a, #11101110b, scan

mov 0ch, #00000000b

lcall play

mov 0bh, #00h

mov r3, #00h

mov 08h, #0ffh

mov 18h, #00h

mov 01h, #00h

mov TCON, #00000000b ;остановили все счетчики

ljmp sound 

 

 

wait:

mov 09h, #10000000b

lcall sd

mov a, #57h

lcall simvol

mov a, #41h

lcall simvol

mov a, #49h

lcall simvol

mov a, #54h

lcall simvol

ret

play:

mov 09h, #10000000b

lcall sd

mov a, #50h

lcall simvol

mov a, #4ch

lcall simvol

mov a, #41h

lcall simvol

mov a, #59h

lcall simvol

 

mov a, #11100000b

mov dptr, #07h   ; светим номер нажатой клавиши

movx @DPTR, A  

ret

 

read:

mov 09h, #10000000b

lcall sd

mov a, #52h

lcall simvol

mov a, #45h

lcall simvol

mov a, #41h

lcall simvol

mov a, #44h

lcall simvol

 

mov a, #10101010b

mov dptr, #07h 

movx @DPTR, A

ret

stop:

mov 09h, #10000000b

lcall sd

mov a, #53h

lcall simvol

mov a, #54h

lcall simvol

mov a, #4fh

lcall simvol

mov a, #50h

lcall simvol

 

mov a, #00000111b

mov dptr, #07h 

movx @DPTR, A

ret

table1:

DB 0feh ;ля

DB 0feh ;ля#

DB 0feh ;си

DB 0fdh ;до

DB 0fdh ;до#

DB 0fdh ;ре

DB 0fdh ;ре#

DB 0fdh ;ми

DB 0fdh ;фа

DB 0fdh ;фа#

DB 0fch ;соль

DB 0fch ;соль#

 

table2:

    DB 47h

    DB 2dh

DB 11h

DB 0f4h

DB 0d5h

DB 0b3h

DB 91h

DB 6bh

DB 4ah

DB 1bh

DB 0efh

DB 0c1h

end 


Информация о работе Разработка программы воспроизведения мелодии