1 #include <avr/io.h>
2 #include <avr/pgmspace.h>
3 #include <avr/interrupt.h>
4 #include <inttypes.h>
5 #include "sound.h"
6
7 #define FALSE 0
8 #define TRUE (!FALSE)
9
10 #define F_CPU 1000000UL
11 #define DURATION_SEED 32
12
13 #define sbiBF(port,bit) (port |= (1<<bit))
14 #define cbiBF(port,bit) (port &= ~(1<<bit))
15
16 const int FurElise[] PROGMEM={
17
18 8,e2, 8,xd2, 8,e2, 8,xd2, 8,e2, 8,b1, 8,d2, 8,c2, 4,a1, 8,p,
19 8,c1, 8,e1, 8,a1, 4,b1, 8,p, 8,e1, 8,xg1, 8,b1, 4,c2, 8,p, 8,e1,
20 8,e2, 8,xd2, 8,e2, 8,xd2, 8,e2, 8,b1, 8,d2, 8,c2, 4,a1, 8,p, 8,c1,
21 8,e1, 8,a1, 4,b1, 8,p, 8,e1, 8,c2, 8,b1, 4,a1,
22 0, 1
23 };
24
25 const int *Song;
26 static char Volume = 80;
27 static char Duration = 0;
28 static char Tone = 0;
29 static char Tempo;
30 void Play_Tune( void );
31
32
33
34
35 ISR( TIMER0_COMPA_vect ) {
36 PORTA ^= 0xff;
37 Play_Tune();
38 }
39
40
41
42
43 void Play_Tune(void) {
44 unsigned int temp_tone;
45 char loop;
46
47 if(!Tone) {
48 PORTD ^= ( 1<<PIN4 );
49 Duration = 0;
50 Tone = 1;
51 }
52
53 if(Duration) {
54 Duration--;
55 } else if(pgm_read_word(Song + Tone)) {
56 PORTD ^= ( 1<<PIN5 );
57 Duration = ( DURATION_SEED / pgm_read_word(Song + Tone) );
58 Tone++;
59 temp_tone=pgm_read_word(Song + Tone);
60 if( (temp_tone == p) | (temp_tone == P) )
61 cbiBF(TCCR1B, CS10);
62 else
63 sbiBF(TCCR1B, CS10);
64
65 cli();
66 TCNT1H = 0;
67 TCNT1L = 0;
68 ICR1 = temp_tone;
69 sei();
70 Tone++;
71 } else {
72 Tone++;
73 loop = (uint8_t)pgm_read_word(Song + Tone);
74
75 if( loop ) {
76 Tone = 1;
77 } else {
78 Tone = 0;
79 cbiBF(TCCR1B, 0);
80 TCCR1A = 0;
81 TCCR1B = 0;
82 sbiBF(PORTB, 5);
83 }
84 }
85 }
86
87
88
89
90 int main(void) {
91 DDRD = 0xff;
92 DDRB = 0xff;
93
94 Song = (int*) pgm_read_word(FurElise);
95 Duration = 0;
96 Tone = 1;
97
98 TCCR0A = 0;
99 TCCR0B = 0;
100 TCCR1A = 0;
101 TCCR1B = 0;
102
103
104
105
106
107
108 TIMSK = (1<<OCIE0A);
109 OCR0A = 0xB0;
110 TCCR0A = (1<<WGM01);
111 TCCR0B = (4<<CS00);
112
113
114
115
116
117
118 TCCR1A = ( 1<<COM1A1 ) |( 1<<COM1A0 );
119 TCCR1B = ( 1<<WGM13 ) |
120 ( 1<<CS00 );
121
122 ICR1 = C0;
123 OCR1AH = 0;
124 OCR1AL = 0x09;
125
126 Duration = 0;
127 Tone = 1;
128
129 sei();
130 while( 1 );
131 return 0;
132 }