Понедельник, Май 25, 2020

Музыкальная шкатулка AVR ASM

;При нажатии на одну из семи кнопок будет звучать одна из семи мелодий
.include "tn2313def.inc"
.list
.def     loop1=r0
.def     loop2=r1
.def     loop=r21
.def     temp=r16
.def     temp1=r17
.def     count=r18
.def     fnota=r19
.def     dnota=r20
         .cseg
         .org    0
start:   rjmp    init
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
         reti
init:    ldi     temp,ramend
         out     spl,temp
         ldi     temp,0x08
         out     ddrb,temp
         out     portb,temp
         ldi     temp,0x7f
         out     portd,temp
         ldi     temp,0
         out     ddrd,temp
         ldi     temp,0x80
         out     acsr,temp
         ldi     temp,0x09      ;включаем режим CTC
         out     tccr1b,temp
stop:    ldi     temp,0
         out     tccr1a,temp    ;выключаем звук
main:    clr     count
         in      temp,pind
button:  lsr     temp
         brcc    prog
         inc     count
         cpi     count,7
         brne    button
         rjmp    stop
;-------------------Выбор мелодии------------------
prog:    mov     yl,count       ;вычисляем адрес,где
         ldi     zl,low(tabm*2) ;хранится начало мелодии
         ldi     zh,high(tabm*2)
         rcall   addw           ;к подпрограмме 16-разрядного сложения
         lpm     xl,z+          ;извлекаем адреса из таблицы
         lpm     xh,z           ;и помещаем в X
;-------------------Воспроизведение мелодии-----------
play:    mov     zh,xh          ;записываем в Z начало мелодии
         mov     zl,xl
s1:      in      temp,pind      ;читаем содержимое порта D
         cpi     temp,0x7f      ;проверяем на равенство 7f
         breq    stop           ;если равно(кнопки отпущены)
         lpm     temp,z         ;изслекаем код ноты
         cpi     temp,0xff      ;проверяем,не конец ли мелодии
         breq    play           ;если конец,начинаем мелодию сначала
         andi    temp,0x1f      ;выделяем код тона из кода ноты
         mov     fnota,temp     ;записываем в регистр кода тона
         lpm     temp,z+        ;еще раз берём код ноты
         rol     temp           ;производим четырёх кратный сдвиг кода ноты
         rol     temp
         rol     temp
         rol     temp
         andi    temp,0x07      ;выделяем код длительности
         mov     dnota,temp     ;помещаем его в регистр длительности
         rcall   nota           ;вызываем подпрограмму воспроизведения ноты
         rjmp    s1             ;в начало цикла(следующая нота)
;------------------Подпрограмма 16-ти разрядного сложения--------------
addw:    push    yh
         lsl     yl             ;Умножение первого слагаемого на 2
         ldi     yh,0           ;Второй байт первого слагаемого=0
         add     zl,yl          ;складываем 2 слогаемых
         adc     zh,yh
         pop     yh             
         ret
;------------------Подпрограмма исполнения одной ноты-------------------
nota:    push    zh
         push    zl
         push    yl
         push    temp
         cpi     fnota,0x00      ;проверка не пауза ли
         breq    nt1             ;если пауза,переходим к задержке
         mov     yl,fnota        ;вычисляем адрес,где хранится
         ldi     zl,low(tabkd*2) ;коэфициент деления для текущей ноты
         ldi     zh,high(tabkd*2)
         rcall   addw
         lpm     temp,z+         ;извлекаем мл.разряд КД для текущей ноты
         lpm     temp1,z         ;ст. разряд КД
         out     ocr1ah,temp1    ;записать в ст.часть регистра совпадения
         out     ocr1al,temp     ;записать в мл.часть регистра совпадения
         ldi     temp,0x40       ;включить звук
         out     tccr1a,temp
nt1:     rcall   wait
         ldi     temp,0
         out     tccr1a,temp     ;выключить звук
         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              ;к подпрограмме 16-разрядного сложения
         lpm     yl,z+             ;читаем первый байт коэфициента задержки
         lpm     yh,z              ;читаем второй байт коэфициента задержки
         clr     zl                ;обнуляем регистровую пару
         clr     zh
w1:      ldi     loop,255          ;пустой внутренний цикл
w2:      dec     loop
         brne    w2
         adiw    r30,1             ;увеличение регистровой пары Z на единицу
         cp      yl,zl             ;проверка младшего разряда
         brne    w1
         cp      yh,zh             ;проверка старшего разряда
         brne    w1
         pop     yl
         pop     yh
         pop     zl
         pop     zh
         ret
;----------------Таблица длительности задержек-----------------------
tabz:    .dw     128,256,512,1024,2048,4096,8192
;----------------Таблица коэфициента делеия-------------------------
tabkd:   .dw     4748,4480,4228,3992,3768,3556,3356,3168,2990,2822,2664,2514
         .dw     2374,2240,2114,1996,1884,1778,1678,1584,1495,1411,1332,1257
         .dw     1187,1120,1057,998,942,889,839,792
;----------------Таблица начала всех мелодий-------------------------
tabm:    .dw     mel1*2,mel2*2,mel3*2,mel4*2,mel5*2,mel6*2,mel7*2
;----------------Таблица мелодий-------------------------------------
;в траве сидел кузнечик
mel1:    .db     109,104,109,104,109,108,108,96,108,104
         .db     108,104,108,109,109,96,109,104,109,104
         .db     109,108,108,96,108,104,108,104,108,141
         .db     96,109,111,79,79,111,111,112,80,80
         .db     112,112,112,111,109,108,109,109,96,109
         .db     111,79,79,111,111,112,80,80,112,112
         .db     112,111,109,108,141,128,96,255
;песенка крокодила гены
mel2:    .db     109,110,141,102,104,105,102,109,110,141
         .db     104,105,107,104,109,110,141,104,105,139
         .db     109,110,173,96,114,115,146,109,110,112
         .db     109,114,115,146,107,109,110,114,112,110
         .db     146,109,105,136,107,105,134,128,128,102
         .db     105,137,136,128,104,107,139,137,128,105
         .db     109,141,139,128,110,109,176,112,108,109
         .db     112,144,142,128,107,110,142,141,128,105
         .db     109,139,128,173,134,128,128,109,112,144
         .db     142,128,107,110,142,141,128,105,109,139
         .db     128,173,146,128,96,255
;в лесу родилась елочка
mel3:    .db     132,141,141,139,141,137,132,132,132,141
         .db     141,142,139,176,128,144,146,146,154,154
         .db     153,151,149,144,153,153,151,153,181,128
         .db     96,255
;happy births to you
mel4:    .db     107,107,141,139,144,143,128,107,107,141
         .db     139,146,144,128,107,107,151,148,146,112
         .db     111,149,117,117,148,144,146,144,128,255
;с чего начинается родина
mel5:    .db     99,175,109,107,106,102,99,144,111,175
         .db     96,99,107,107,107,107,102,104,170,96
         .db     99,109,109,109,109,104,106,171,96,99
         .db     111,109,107,106,102,99,144,111,143,104
         .db     114,114,114,114,109,111,176,96,104,116
         .db     112,109,107,106,64,73,143,107,131,99
         .db     144,80,80,112,111,64,75,173,128,255
;песня из кинофильма "Весёлые ребята"
mel6:    .db     105,109,112,149,116,64,80,148,114,64
         .db     78,146,112,96,105,105,109,144,111,64
         .db     80,145,112,64,81,178,96,117,117,117
         .db     149,116,64,82,146,112,64,79,146,144
         .db     96,105,105,107,141,108,109,112,110,102
         .db     104,137,128,96,105,105,105,137,102,64
         .db     73,142,105,107,109,64,75,137,96,105
         .db     105,105,137,102,105,142,112,64,82,180
         .db     96,116,116,116,148,114,112,142,109,64
         .db     78,146,144,96,105,105,107,141,108,109
         .db     112,110,102,104,169,96,96,255
;улыбка
mel7:    .db     107,104,141,139,102,105,104,102,164,128
         .db     104,107,109,109,109,111,114,112,111,109
         .db     144,139,128,109,111,144,96,111,109,104
         .db     107,105,173,128,111,109,112,107,111,109
         .db     109,107,102,104,134,132,128,100,103,107
         .db     107,107,107,139,112,100,103,102,102,102
         .db     134,102,103,107,105,107,108,108,108,108
         .db     107,105,107,108,144,142,128,112,107,110
         .db     140,112,105,108,107,107,107,105,140,139
         .db     139,112,103,102,103,105,108,107,105,103
         .db     128,112,107,110,108,108,108,140,112,105
         .db     108,107,107,107,139,112,103,102,103,105
         .db     108,107,105,103,105,139,132,128,96,96
         .db     96,255 

 

 

 

НАЗАД                  Assembler PIC                  Си AVR                  ДАЛЬШЕ

Back to Top