Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define LED_ON PORTC|=(1<<0)
#define LED_OFF PORTC&=~(1<<0)
#define C1 15288
#define C1d 14431
#define D1 13621
#define D1d 12856
#define E1 12134
#define F1 11453
#define F1d 10811
#define G1 10204
#define G1d 9631
#define A1 9090
#define A1d 8580
#define H1 8099
#define C2 7648
#define C2d 7220
#define D2 6814
#define D2d 6430
#define E2 6069
#define F2 5730
#define G2 5102
#define G2d 4815
#define A2 4545
#define A2d 4291
#define H2 4049
#define C3 3822
#define P 0
#define End 1
#define N16 250.000
#define N8 500.000
#define N4 1000.000
#define N2 2000.000
#define N1 4000.000
int tanki[]={160.000,P,N16,C2,N16,D2,N16,D2d,N16,C2,N16,D2,N16,D2d,N16,D2d,N16,F2,N16,G2,N16,D2d,N16,F2,N16,G2,N16,
F2,N16,G2,N16,A2,N16,F2,N16,G2,N16,A2,N16,G2d,N16,A2d,N16,C3,N16,G2d,N16,A2d,N16,C3,N16,C3,N16,P,N16,C3,N16,C3,N16,C3,N16,C3,N16,End}; //мелодия танчиков
int mario[]= {100.000,P,N8,E2,N16,E2,N16,P,N16,E2,N8,P,N16,C2,N16,E2,N16,P,N16,
G2,N16,P,N16,P,N8,G1,N16,P,N8,P,N8,
C2,N16,P,N8,G1,N16,P,N8,E1,N8,P,N8,
P,N16,A1,N16,P,N16,H1,N16,P,N16,A1d,N16,A1,N16,P,N16,
G1,N16,E2,N16,G2,N16,A2,N16,P,N16,F2,N16,G2,N16,
P,N16,E2,N16,P,N16,C2,N16,D2,N16,H1,N16,End}; //мелодия марио
int miniPolka[54]={120.000,P,N8,C2,N8,E2,N8,G2,N8,E2,N8,G2,N8,F2,N8,D2,N4,G2,N8,F2,N8,D2,N4,G2,N8,E2,N8,C2,N4,
C2,N8,E2,N8,G2,N8,E2,N8,A2,N8,G2,N8,F2,N4,G2,N8,F2,N8,E2,N8,D2,N8,C2,N4,End};
int bumer[]={170.000,P,N8,E2,N8,G2,N4,P,N4,P,N4,
G2,N8,E2,N4,P,N4,P,N4,
A2,N8,G2,N8,A2,N8,G2,
N8,A2,N8,G2,N8,A2,N8,G2,N8,A2,N8,H2,N4,P,N4,End};
int nokia[30]={120.000,P,N8,E2,N8,D2,N8,
F1d,N4,G1d,N4,C2d,N8,H1,N8,
D1,N4,E1,N4,H1,N8,A1,N8,
C1d,N4,E1,N4,A1,N4,End};
int mortal[66]={140.000,A1,N8,A1,N8,C2,N8,A1,N8,D2,N8,A1,N8,E2,N8,D2,N8,
C2,N8,C2,N8,E2,N8,C2,N8,G2,N8,C2,N8,E2,N8,C2,N8,
G1,N8,G1,N8,H1,N8,G1,N8,C2,N8,G1,N8,D2,N8,C2,N8,
F1,N8,F1,N8,A1,N8,F1,N8,C2,N8,F1,N8,C2,N8,H1,N8,End};
int *playlist[]={mortal,
nokia,
miniPolka,
bumer,
mario,
tanki
};
volatile int track=0;
volatile int NoteLong = 250;
volatile int loaded=0;
volatile int i = 1;
// прерывание таймера 1
//interrupt [TIM1_COMPA] void timer1_compa_isr(void)
ISR (TIMER1_COMPA_vect)
{
// PORTD.0=!PORTD.0;
//PORTC ^= 1;
PORTC^=(1<<1);
}
volatile int Bit = 0x00;
void play()
{
OCR1AH = (char)(Bit>>8); //записываем текущую ноту в OCR1A
OCR1AL = (char)Bit;
_delay_ms(NoteLong);
// #asm("cli") //запрещаем прерывание чтобы оборвать ноту
cli();
_delay_ms(40);
// #asm("sei")
sei();
i=i+2;
}
void pause()
{
// #asm("cli") //пауза между нотами
cli();
_delay_ms(NoteLong);
// #asm("sei")
sei();
// i=i+2;
i+=2;
}
void stop()
{
// #asm("cli")
cli();
Bit=0x00;
//PORTC=0x00;
PORTC&=~(1<<1);
i=1;
_delay_ms(200);
if(track==5) //если последний, то начать заново
{
loaded=1;
track=0;
LED_ON;
_delay_ms(1000);
LED_OFF;
}
else
{
track++;
LED_ON;
_delay_ms(1000);
LED_OFF;
}
}
void Loading_melody()
{
i=1;
while(playlist[track][i]!=1)
{
playlist[track][i+1]=playlist[track][i+1]/(playlist[track][0]/60.000);
i++;
if(playlist[track][i]!=1)
{
i++;
}
}
i=1;
}
int main(void)
{
PORTC=0x00;
DDRC=0b000000011;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
//TCCR1A=0x00;
TCCR1B=0x09;
//TCNT1H=0x00;
//TCNT1L=0x00;
//ICR1H=0x00;
//ICR1L=0x00;
//OCR1AH=0x00;
OCR1AL=0xFB;
//OCR1BH=0x00;
//OCR1BL=0x00;
TIMSK=0x10;
LED_ON;
_delay_ms(1000);
LED_OFF;
while (1)
{
if(loaded==0)
{
Loading_melody(); //пересчет длительности нот
}
// #asm("sei")
sei();
while(playlist[track][i]!=1)
{
Bit= playlist[track][i]; //массив с нотами
NoteLong=playlist[track][i+1];
if(Bit==0)
{
pause();
}
else
{
play();
}
}
stop();
//LED_ON;
};
}