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

Incf counter,f ;Инкрементируем счетчик номера ноты

bsf STATUS,RP0 ;Обращение к банку 1 для доступа к OPTION_REG

mvi OPTION_REG,05h ;Изменяем коэффициент деления предделителя TMR0

bcf STATUS,RP0 ;Обращение к банку 0

movf TONE,F

btfss STATUS,Z ;Если TONE=0, то молчим

bsf OUT,2 ;Динамик подключен к RA2 и RA3

Loop_label mov TMR0,SPEED ;Чем больше SPEED - тем быстрее мелодия

bcf INTCON,T0IF ;Флаг установился в предыдущем проходе цикла - сбросим

Pulse_label movf OUT,W

movf TONE,F

btfss STATUS,Z ;Если TONE=0, то молчим

movwf PORTA ;Иначе OUT --> W --> PORTA

movf TONE,W

addlw D'253' ;Коррекция: (W-3) --> W

S_label1 addlw 0FFh ;(W-1) --> W

btfss STATUS,Z

goto S_label1

bcf OUT,2

bsf OUT,3 ;Меняем полярность на динамике

movf OUT,W

movf TONE,F

btfss STATUS,Z ;Если TONE=0, то молчим

movwf PORTA ;Иначе OUT --> W --> PORTA

decf TONE,W ;Коррекция

S_label2 addlw 0FFh ;(W-1) --> W

btfss STATUS,Z

goto S_label2

bcf OUT,3

bsf OUT,2 ;Меняем полярность

btfss INTCON,T0IF

goto Pulse_label

Breakpoint1 decfsz DURATION,F ;

goto Loop_label

bcf OUT,2 ;Снимаем напряжение с динамика

mov PORTA,OUT ;Здесь можно без проверки TONE на ноль

movlw D'4' ;Пауза между нотами

call Pause

bsf STATUS,RP0 ;Обращение к банку 1 для доступа к OPTION_REG

mvi OPTION_REG,0 ;Восстанавливаем коэффициент деления предделителя

bcf STATUS,RP0 ;Обращение к банку 0

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

movf NUMBER,W

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

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

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

End_snd return

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

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

;Подпрограммы для работы со светодиодами

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

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

;Прерывания должны быть запрещены

Decode5_32 movf BYTE01,W ;Растягиваем первый бит в два раза

movwf BYTE02 ;(нулевой бит растягивать не требуется)

movf BYTE03,W ;Третий - в четыре

movwf BYTE04

movwf BYTE05

movwf BYTE06

movf BYTE07,W ;Седьмой - в восемь

movwf BYTE08

movwf BYTE09

movwf BYTE0A

movwf BYTE0B

movwf BYTE0C

movwf BYTE0D

movwf BYTE0E

movf BYTE0F,W ;И пятнадцатый - в шестнадцать раз

movwf BYTE10

movwf BYTE11

movwf BYTE12 ;Получается 1+2+4+8+16 = 31 бит из 32 максимум

movwf BYTE13

movwf BYTE14

movwf BYTE15

movwf BYTE16

movwf BYTE17

movwf BYTE18

movwf BYTE19

movwf BYTE1A

movwf BYTE1B

movwf BYTE1C

movwf BYTE1D

movwf BYTE1E

clrf BYTE1F ;Let it be

return ;Конец подпрограммы дешифрации

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

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

Roll bcf INTCON,GIE ;Запрещаем прерывания (иначе возможно переполнение стека)

movf TEMP3,W ;Проверка на ноль

jz Bypassroll_lbl ;Если 0, то сдвиг не требуется

Roll_label bcf STATUS,C ;Сброс признака переноса

rlf BYTE00,F ;Сдвиг влево на 1

btfsc STATUS,C ;Сдвинутый в С старший бит = 1 ?

bsf BYTE00,0 ;Да - устанавливаем младший бит

bcf STATUS,C

rlf BYTE01,F

btfsc STATUS,C

bsf BYTE01,0

bcf STATUS,C

rlf BYTE03,F

btfsc STATUS,C

bsf BYTE03,0

bcf STATUS,C

rlf BYTE07,F

btfsc STATUS,C

bsf BYTE07,0

bcf STATUS,C

rlf BYTE0F,F

btfsc STATUS,C

bsf BYTE0F,0

addlw D'255' ;Декремент W

jnz Roll_label

Bypassroll_lbl call Decode5_32 ;Дешифрация

bsf INTCON,GIE ;Разрешаем прерывания

movf TIME,W

call Pause

return

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

;Подпрограмма дешифрации и паузы (для экономии памяти программ)

Send bcf INTCON,GIE ;Запрещаем прерывания

call Decode5_32 ;Дешифрация

bsf INTCON,GIE ;Разрешаем прерывания

movf TIME,W

call Pause

return

;Подпрограммa "змейка"

SNAKE mvi BYTE00,B'10000101'

mvi BYTE01,B'10010110'

mvi BYTE03,B'10011000'

mvi BYTE07,B'10100000'

mvi BYTE0F,B'11000000'

call Roll

return

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

;Подпрограмма "змейка" влево

LEFT_SNAKE clrf TEMP3 ;Обнуляем счетчик проходов

Snake1label call SNAKE

movf CHANGE,W ;После каждого захода корректируем скорость

addwf TIME,F

incf TEMP3,F ;Следующий проход - следующий светодиод

movlw D'8'

xorwf TEMP3,W ;Последний светодиод был?

jnz Snake1label ;Нет - следующий светодиод

decfsz TEMP2,F ;Последний круг был?

goto LEFT_SNAKE ;Нет - еще круг

return

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

;Подпрограмма "змейка" вправо

RIGHT_SNAKE mvi TEMP3,07h ;Начальное значение счетчика проходов

Snake2label call SNAKE

movf CHANGE,W ;После каждого захода корректируем скорость

addwf TIME,F

decf TEMP3,F ;Следующий проход - следующий светодиод

movlw D'255'