Разработка программы воспроизведения мелодии
Курсовая работа, 14 Марта 2012, автор: пользователь скрыл имя
Описание работы
Целью данной разработки является создание программы, которая будет являться электронной моделью музыкальной шкатулки, воспроизводящей 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 Кб (Скачать)Рис.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