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

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

Код в CodeVision.

 

#define F_CPU 4000000UL
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "util/delay.h"
//Объявление и инициализация массивов
//Таблица задержек
unsigned int tabz[]PROGMEM={16,32,64,128,256,512,1024};
//Массив коэффициентов деления
unsigned int tabkd[]PROGMEM={0,4748,4480,4228,3992,3768,3556,3356,3168,2990,2822,2664,2514,
                             2374,2240,2114,1996,1884,1778,1678,1584,1495,1411,1332,1257,
                             1187,1120,1057,998,942,889,839,792};
//Таблицы мелодий
//В траве сидел кузнечик
unsigned char mel1[]PROGMEM={109,104,109,104,109,108,108,96,108,104,
                             108,104,108,109,109,96,109,104,109,104,
                             109,108,108,96,108,104,108,104,108,141,
                             96,109,111,79,79,111,111,112,80,80,
                             112,112,112,111,109,108,109,109,96,109,
                             111,79,79,111,111,112,80,80,112,112,
                             112,111,109,108,141,128,96,255};
//Песенка крокодила Гены
unsigned char mel2[]PROGMEM={109,110,141,102,104,105,102,109,110,141,
                             104,105,107,104,109,110,141,104,105,139,
                             109,110,173,96,114,115,146,109,110,112,
                             109,114,115,146,107,109,110,114,112,110,
                             146,109,105,136,107,105,134,128,128,102,
                             105,137,136,128,104,107,139,137,128,105,
                             109,141,139,128,110,109,176,112,108,109,
                             112,144,142,128,107,110,142,141,128,105,
                             109,139,128,173,134,128,128,109,112,144,
                             142,128,107,110,142,141,128,105,109,139,
                             128,173,146,128,96,255};
//В лесу родилась ёлочка
unsigned char mel3[]PROGMEM={132,141,141,139,141,137,132,132,132,141,
                             141,142,139,176,128,144,146,146,154,154,
                             153,151,149,144,153,153,151,153,181,128,
                             96,255};
//Happy births day to you
unsigned char mel4[]PROGMEM={107,107,141,139,144,143,128,107,107,141,
                             139,146,144,128,107,107,151,148,146,112,
                             111,149,117,117,148,144,146,144,128,255};
//С чего начинается родина
unsigned char mel5[]PROGMEM={99,175,109,107,106,102,99,144,111,175,
                             96,99,107,107,107,107,102,104,170,96,
                             99,109,109,109,109,104,106,171,96,99,
                             111,109,107,106,102,99,144,111,143,104,
                             114,114,114,114,109,111,176,96,104,116,
                             112,109,107,106,64,73,143,107,131,99,
                             144,80,80,112,111,64,75,173,128,255};
//Из кинофильма "Весёлые ребята"
unsigned char mel6[]PROGMEM={105,109,112,149,116,64,80,148,114,64,
                             78,146,112,96,105,105,109,144,111,64,
                             80,145,112,64,81,178,96,117,117,117,
                             149,116,64,82,146,112,64,79,146,144,
                             96,105,105,107,141,108,109,112,110,102,
                             104,137,128,96,105,105,105,137,102,64,
                             73,142,105,107,109,64,75,137,96,105,
                             105,105,137,102,105,142,112,64,82,180,
                             96,116,116,116,148,114,112,142,109,64,
                             78,146,144,96,105,105,107,141,108,109,
                             112,110,102,104,169,96,96,255};
//Улыбка
unsigned char mel7[]PROGMEM={107,104,141,139,102,105,104,102,164,128,
                             104,107,109,109,109,111,114,112,111,109,
                             144,139,128,109,111,144,96,111,109,104,
                             107,105,173,128,111,109,112,107,111,109,
                             109,107,102,104,134,132,128,100,103,107,
                             107,107,107,139,112,100,103,102,102,102,
                             134,102,103,107,105,107,108,108,108,108,
                             107,105,107,108,144,142,128,112,107,110,
                             140,112,105,108,107,107,107,105,140,139,
                             139,112,103,102,103,105,108,107,105,103,
                             128,112,107,110,108,108,108,140,112,105,
                             108,107,107,107,139,112,103,102,103,105,
                             108,107,105,103,105,139,132,128,96,96,
                             96,255 };
//Таблица начала всех мелодий.Открываем файл pgmspace.h и изучаем.
PGM_P tabm[]PROGMEM={mel1,mel2,mel3,mel4,mel5,mel6,mel7};
//Фукция задержки,чтобы работала функция _delay_ms(double __ms)
void delay_ms(unsigned int us)
{
    for(unsigned int i=0;i<us;i++)
    {
        _delay_ms(1);
    }
}
void main(void)
{
    unsigned char count;
    unsigned char temp;
    unsigned int nota;   //Сюда будем записывать 16-ти битный адрес таблиц
                         //так как все адреса AVR=unsigned int(16-bit,или 2 байта)
    unsigned char fnota; //Код тона ноты
    unsigned char dnota; //Код длительности ноты
    PORTB=0x08;
    DDRB=0x08;
    PORTD=0x7f;
    DDRD=0x00;
    
    ACSR=0x80;
    TCCR1A=0x00;
    TCCR1B=0x09;
    while(1)
    {
    m1: temp=PIND;                             //Копируем состояние кнопок
        for (count=0;count<7;count++)          //Цикл проверки кнопок
        {
            if((temp&1)==0)goto m3;            //Проверка младшего бита в temp
            temp>>=1;                          //Сдвиг содержимого temp в лево на 1 бит
        }
    m2: TCCR1A=0x00;                           //Выключение звука
        goto m1;                               //Переход на начало
    m3: nota=pgm_read_word(&tabm[count]);      //В nota записываем адрес текущей таблицы
        
    m4: if(PIND==0x7f)goto m2;                 //Если ни одна кнопка не нажата
        if((pgm_read_byte(nota))==0xff)goto m3;//Проверка на конец мелодии
        fnota=(pgm_read_byte(nota)) & 0x1f;    //Определяем код тона
        dnota=((pgm_read_byte(nota))>>5)&0x07; //Определяем код длительности
        if(fnota==0)goto m5;                   //Если пауза не воспроизводим вук
        OCR1A=pgm_read_word(&tabkd[fnota]);    //Берём значение частоты звука
        TCCR1A=0x40;                           //Включаем звук
    m5: delay_ms(pgm_read_word(&tabz[dnota])); //Формируем задержку
        TCCR1A=0x00;                           //Выключаем звук
        delay_ms((pgm_read_word(&tabz[0])));   //Задержка между нотами
        nota++;                                //Перемещаем указатель на следующую ноту
        goto m4;                               //К началу цикла
    }
}



НАЗАД               Assembler AVR               Assembler PIC                 ДАЛЕЕ



Back to Top