Листинг 19.1

/==== программа вывода цифрового звука ====

;процессор mеgа8515 в режиме 8515, частота 16 МГц

.include "853 5def.inc"

.equ T_Sample = 193  ;предварительное значение для Timer 0 при 4 кГц

.equ bSample = 0  ;бит готовности к чтению

;регистры temp и DATA определены в "I2С.рrg" (Приложение 5)

.def FLAGS = r19

; прерывания

rjmp RESET  ;начальный загрузчик

reti

reti

reti

reti

reti

reti

rjmp TIMO  ;обработчик прерывания переполнения Timer 0

reti

reti

reti

reti

.include "I2C.prg"

RESET:

            ldi temp,0b00100000

            out DDRD,temp  ;ОС1А — на выход

            ldi temp,(1<  ;инициализация PWM

            out TCCR1A,temp

            ldi temp,1<  ;включаем Timer1, 1/1

            out TCCR1B,temp

            ldi temp,(1<  ;включаем Timer0, 1/64

            out TCCR0,temp

            out TCNT0,T_Sample  ;T_Sample=6, заряжаем таймер 0 на 4 кГц

            ldi temp,(1<  ;разрешаем прерывание Timer0

            out TIMSK,temp

            clr temp  ;очищаем все регистры

            out OCR1AH,temp

            out OCR1AL,temp

            out OCR1BH,temp

            out OCR1BL,temp

            ldi XH,high(Nbytes)

            ldi XL,low(Nbytes)  ;зарядка счетчика выводимых байт

            ;вместо Nbytes подставить объем записи в байтах, не более 64К

            ldi YH,high(ADrWord)

            ldi YL,low(ADrWord)

            ;вместо ADrWord можно подставить начальный адрес

            ;во flash-памяти, он может быть отличен от 0:0

            sei  ;разрешаем прерывания

loop_voice:  ;читаем байт для последующего вывода

            rcall read_i2c  ;чтение памяти, YL,YH — адрес, в DATA — полученных байтов

            sleep  ;Idle-mode, проснется по прерыванию Timer0

            sbrs FLAGS,bSample  ;бит встает в 1 в обработчике прер. TIM0

            rjmp loop_voice  ;если еще не установлен, то на начало цикла

            adiw YL,1 ;иначе увеличиваем адрес на 1

            cbr FLAGS,1<  ;сбрасываем бит готовности к чтению

            sleep  ;Idle-mode, проснется по прерыванию Timer0

            in temp,TCCR0  ;проверяем, не остановлен ли таймер

            tst temp

            brne loop_voice  ;если не остановлен, то следующий цикл

            ;иначе вывод звука закончен — делаем что-то еще

;===== обработчик прерывания от Timer 0 =====

TIM0:

           out TCNT0,T_Sample  ;перезаряжаем Timer0

           clr temp

           out OCR1AH,temp

           out ОСR1AL,DATA  ;занесение байта в PWM

           sbr FLAGS,1<  ;бит готовности к чтению — в 1

           sbiw XL,1  ; уменьшаем счетчик прочитанных байтов

           brne rt_pwm_  ;если он равен 0

           out TCCR0,XL  ;то выключаем таймер 0

           out TCCR1B,XL  ;и Timer 1 также

rt_pwm_:

           reti  ;возврат из обработчика Timer0

Перейти на страницу:

Поиск

Похожие книги