Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Звіт до 3 лаби саніне.doc
Скачиваний:
3
Добавлен:
21.07.2019
Размер:
423 Кб
Скачать
☆

Interrupt movwf w_copy ;Сохраняем контекст

mov ST_copy,STATUS

movlw B'10000000' ;Коррекция TMR0,

movwf TMR0 ;чтоб прерывания почаще происходили

movf ADDRESS,W ;Адрес ячейки с требуемыми на данном шаге данными

movwf FSR ;заносим в FSR (косвенная адресация)

comf INDF,W ;Переносим данные из ячейки с указанным адресом в W

;с инверсией, т.к. светодиоды подключены к "плюсу"

movwf PORTB ;И выдаем результат на выводы PORTB

movlw BYTE1F ;Заносим адрес ячейки BYTE1F в W

xorwf ADDRESS,W ;Если адреса совпадают, то пора вернутся к BYTE00

btfss STATUS,Z ;Адреса совпали, Z=1, пропускаем переход

goto Int_label ;Адреса не совпали, переход

movlw BYTE00 ;Снова заносим адрес ячейки Byte0

movwf ADDRESS ;в ячейку ADDRESS - начался следующий цикл

Int_label incf ADDRESS,F ;В следующем прерывании будем выводить следующий байт

movf LONGTIMER,W ;Заданное число циклов прошло?

jz PlaybackN ;Да - переход на воспроизведение текущей мелодии

PlaybackN clrf COUNTER ;Обнуляем счетчик номера ноты

movf NUMBER,W

sublw D'11' ;Проверка - если NUMBER не больше 11

btfss STATUS,C ;то переход к воспроизведению

goto Finish ;Иначе переход на Finish

sublw D'11' ;Восстанавливаем исходное значение

clrf PCLATH

addwf PCL,F ;Переход на исполнение мелодии под номером NUMBER

goto Melody11

Finish movf LONGTIMER,W ;Мелодия воспроизведена по причине истечения интервала?

jnz Demand_label ;Нет - переход

Incf number,f ;Подготавливаемся к воспроизведению следующей мелодии

movf NUMBER,W

sublw SONGS-1 ;(SONGS-1-W) --> W

btfss STATUS,C ;Мелодия была последняя по номеру ?

clrf NUMBER ;Да - возврат к начальной мелодии

mvi LONGTIMER,CYCLES ;Исходное значение - начинаем отсчет циклов по новой

Demand_label call Led_all_100

movlw D'200'

call Pause

End_int bcf INTCON,T0IF ;Сбрасываем флаг запроса на прерывание от таймера

mov STATUS,ST_copy ;Восстанавливаем контекст

swapf W_copy,F ;Тут приходится хитрить, чтобы сохранить бит Z в STATUS

swapf W_copy,W ;(MOVF его может изменить, а SWAPF - нет)

retfie ;Возврат из обработчика с установкой бита GIE

;--------------------------------------------------------------------------------------------------

;--------------------------------------------------------------------------------------------------

; --- ПОДПРОГРАММЫ ---

;--------------------------------------------------------------------------------------------------

;Подпрограммы табличной конвертации

;--------------------------------------------------------------------------------------------------

;Подпрограмма декодирования длительности

Dec_dur clrf PCLATH

addwf PCL,F

retlw D'8' ;"HHHHH000" = 1/8

retlw D'16' ;"HHHHH001" = 1/4

retlw D'32' ;"HHHHH010" = 1/2

retlw D'48' ;"HHHHH011" = 3/4

retlw D'64' ;"HHHHH100" = 1

retlw D'96' ;"HHHHH101" = 3/2

retlw D'128' ;"HHHHH110" = 2

retlw D'255' ;"HHHHH111" = 4

;Подпрограмма декодирования ноты

Dc_tone sublw D'24' ;Проверка - если число не больше 24

btfss STATUS,C ;то переход на дешифрацию

retlw 00h ;Иначе возвращаем 0 (тишина)

clrf PCLATH

sublw D'24' ;Восстанавливаем исходное значение

addwf PCL,F

retlw D'252' ;"00000DDD" = "си" 1-й октавы (494 Гц)

retlw D'238' ;"00001DDD" = "до" 2-й октавы (524 Гц)

retlw D'224' ;и так далее...

retlw D'212'

retlw D'202'

retlw D'190'

retlw D'178'

retlw D'168'

retlw D'158'

retlw D'150'

retlw D'142'

retlw D'134'

retlw D'126' ;"си" 2-й октавы (988 Гц)

retlw D'119' ;"до" 3-й октавы (1048 Гц)

retlw D'112'

retlw D'106'

retlw D'101'

retlw D'95'

retlw D'89'

retlw D'84'

retlw D'79'

retlw D'75'

retlw D'71'

retlw D'67'

retlw D'63' ;"си" 3-й октавы (1976 Гц)

;Подпрограмма дешифрации номера воспроизводимой ноты для отображения на светодиодах

Dcd8 andlw B'00000111' ;Нас интересуют младшие 3 бита (т.к. 8 светодиодов)

clrf PCLATH

addwf PCL,F

retlw B'11111110'

retlw B'11111100'

retlw B'11111000'

retlw B'11110000'

retlw B'11100000'

retlw B'11000000'

retlw B'10000000'

retlw B'00000000'

;--------------------------------------------------------------------------------------------------

;Сервисные подпрограммы

;--------------------------------------------------------------------------------------------------

;Подпрограмма паузы (используется ячейка TEMP1)

Pause movwf TEMP1 ;Длительность паузы задается числом в W (примерно в мс)

movf TEMP1,F ;Проверка на 0

btfsc STATUS,Z ;Если длительность не равна 0, то Z=0 и пропускаем return

return ;Если же длительность равна 0, то сразу возврат

clrw ;Очищаем W

P_label addlw 01h ;Внутренний цикл по W

btfss STATUS,Z ;

goto P_label ;

decfsz TEMP1,F ;Внешний цикл по TEMP1

goto P_label ;

return ;Конец подпрограммы паузы

;Подпрограмма вспышки всех светодиодов с паузой 100 мс

Led_all_100 clrf PORTB

movlw D'100'

call Pause

mvi PORTB,0FFh

return

;--------------------------------------------------------------------------------------------------

;Музыкальные подпрограммы

;--------------------------------------------------------------------------------------------------

;Подпрограмма выдачи звукового сигнала

Sound

movwf TONE ;Временно сохраняем исходные данные (байт был в W)

andlw B'00000111' ;Маска

call Dec_dur ;Вызов подпрограммы табличной конвертации

movwf DURATION ;Получили результат - байт, задающий длительность ноты

rrf TONE,F

rrf TONE,F

rrf TONE,W ;Сдвигаем...

andlw B'00011111' ;Маска

call Dc_tone ;Вызов подпрограммы табличной конвертации

movwf TONE ;Получили результат - байт, задающий высоту тона

movf COUNTER,W

call Dcd8 ;Вызываем дешифратор, результат в W

movwf PORTB ;И выдаем результат на выводы PORTB