Написал программку для проигрывания одноголосной мелодии. В принципе, адаптировал кусок с книги Белова. Контроллер - Tiny2313. Работает от внутреннего генератора 4МГц. Но почему-то глотает некоторые ноты. Причем, чаще одни и те же. Как будто запаздывает начало ноты, а воспроизводится с середины. Остальные играют хорошо.
Может кто сталкивался. Прошу прощения что на Ассемблере.
;======М У З Ы К А========
m3:
mov YL, count ; счетчик мелодий -> YL
ldi ZL, low(tabm*2) ;в Z -> начальный адрес "tabm"
ldi ZH, high(tabm*2) ;
rcall addw ; сложение смещения по счетчику и
; начального адреса "tabm"
lpm XL, Z+ ; извлечение из "tabm"
lpm XH, Z
;---------------------воспроизведение----------------------------
m4: mov ZH, XH ; пересылка в рабочий регистр
mov ZL, XL ;
m5: ldi b,255
ldi d,255
ldi e, 0 ; установка таймера1
out tccr1a, e
lpm temp, Z ; пересылка данных, находящихся
; по адресу в Z -> temp
cpi temp, 0xFF ; последняя нота????
breq m6 ; выход
andi temp, 0x1F ; выделяем код тона (И=И)
mov fnota, temp ; кидаем его в fnota
lpm temp, Z+ ; первую ноту в temp
rol temp ; 4-кратный круговой сдвиг кода ноты
rol temp ;
rol temp ;
rol temp ;
andi temp, 0x07 ;выделение кода длительности
mov dnota, temp ; помещаем его в "dnota"
rcall nota
rjmp m5
m6: cbi portB,3; заглушка 2 для порта (пищалка не такая как нужно)
ret
; Программа 16-тиразрядного сложения
addw: push YH
lsl YL
ldi YH,0
add ZL, YL
add ZH, YH
pop YH
ret
; Подпрограмма исполнения одной ноты
nota: push ZH
push ZL
push YL
push temp
cpi fnota, 0x00
breq nt1
mov YL, fnota ; fnota ->YL
ldi ZL, low(tabkd*2) ; адрес "tabkd" -> Z
ldi ZH, high(tabkd*2) ;
rcall addw ; переход на нужный адрес
lpm temp, Z+ ;извлечение в temp и temp1 нужного
lpm temp1, Z ;коэффициента деления
out OCR1AH, temp1
out OCR1AL, temp
ldi e, 0x40 ;установка таймера1
out tccr1a, e ;
nt1: rcall wait
ldi e, 0
out tccr1a, e
ldi dnota, 0
rcall wait
pop temp
pop YL
pop ZL
pop ZH
ret
; Подпрограмма формирования задержки
wait: push ZH
push ZL
push YH
push YL
mov YL, dnota
ldi ZL, low(tabz*2)
ldi ZH, high(tabz*2)
rcall addw
lpm YL, Z+
lpm YH, Z
clr ZL
clr ZH
; Цикл задержки
w1: ldi loop, 255
w2: dec loop
cpi loop, 0
brne w2
adiw r30, 1
cp YL, ZL
brne W1
cp YH, ZH
brne W1
pop YL
pop YH
pop ZL
pop ZH
ret
; **********************************
; Таблица длительности задержек
tabz: .dw 4,8,16,32,64,128,256
; **********************************
; Таблица коэффициентов деления
tabkd: .dw 0
.dw 152,143,135,128,121,114,107,101,97,90,85,80
.dw 76,72,68,64,60,57,54,51,48,45,43,40
.dw 38,36,34,30,29,27,25
; Таблица начал всех мелодий
tabm: .dw mel1*2,mel2*2,mel3*2,mel4*2,mel5*2,mel6*2,mel7*2,mel8*2,mel9*2
; **********************************
; Таблицы мелодий
mel1:
.db 146,141,146,141,146,145,177,145,141,145,141,145,146,178,255
и т. д.


