/==== программа вывода цифрового звука ====
;процессор 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<
out TCCR1A,temp
ldi temp,1<
out TCCR1B,temp
ldi temp,(1<
out TCCR0,temp
out TCNT0,T_Sample ;T_Sample=6, заряжаем таймер 0 на 4 кГц
ldi temp,(1<
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<
sbiw XL,1 ; уменьшаем счетчик прочитанных байтов
brne rt_pwm_ ;если он равен 0
out TCCR0,XL ;то выключаем таймер 0
out TCCR1B,XL ;и Timer 1 также
rt_pwm_:
reti ;возврат из обработчика Timer0