- •Лабораторна робота №3
- •Текст програми
- •Interrupt movwf w_copy ;Сохраняем контекст
- •Incf number,f ;Подготавливаемся к воспроизведению следующей мелодии
- •Incf counter,f ;Инкрементируем счетчик номера ноты
- •Incf number,f ;Подготавливаемся к воспроизведению следующей мелодии
- •Xorwf temp3,w ;Последний светодиод был?
- •Приводимо текст нех файла:
- •Використані команди:
- •Висновки:
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'