#include #include #include // number of timer0 overflows/sec #define INT_PER_SEC F_CPU/1/256 // Frequencies (in Hz) of notes #define F_FSH_4 370 #define F_A_4 440 #define F_B_4 494 #define F_E_4 330 #define F_CSH_5 554 #define F_D_5 587 #define F_FSH_5 740 #define F_CSH_4 277 #define F_GSH_4 415 // number of timer0 overflows for notes #define REST -1 // special case #define FSH_4 INT_PER_SEC/F_FSH_4 #define A_4 INT_PER_SEC/F_A_4 #define B_4 INT_PER_SEC/F_B_4 #define E_4 INT_PER_SEC/F_E_4 #define CSH_5 INT_PER_SEC/F_CSH_5 #define D_5 INT_PER_SEC/F_D_5 #define FSH_5 INT_PER_SEC/F_FSH_5 #define CSH_4 INT_PER_SEC/F_CSH_4 #define GSH_4 INT_PER_SEC/F_GSH_4 #define SEMIQUAVER_TIME 60 // ms #define BREATH_TIME 20 // ms volatile uint32_t intrs = 0; volatile int32_t curNote = REST; // TIMER0 overflow ISR(TIMER0_OVF_vect) { if (curNote == REST) intrs = 0; else { intrs++; if (intrs >= curNote) { PORTD ^= _BV(PD4); intrs = 0; } } } void play(int32_t note, uint32_t len) { int i; curNote = note; for (i = 0; i< len; i++) _delay_ms(SEMIQUAVER_TIME); curNote = REST; _delay_ms(BREATH_TIME); } int main(void) { /* setup clock divider. Timer0 overflows on counting to 256. * 16Mhz / 1 (CS0=1) = 16000000 increments/sec. Overflows every 256. */ TCCR0B |= _BV(CS00); // enable overflow interrupts TIMSK0 |= _BV(TOIE0); // PD4 as output DDRD = _BV(PD4); TCNT0 = 0; intrs = 0; curNote = REST; // enable interrupts sei(); while (1) { // Axel F play(FSH_4, 2); play(REST, 2); play(A_4, 3); play(FSH_4, 2); play(FSH_4, 1); play(B_4, 2); play(FSH_4, 2); play(E_4, 2); play(FSH_4, 2); play(REST, 2); play(CSH_5, 3); play(FSH_4, 2); play(FSH_4, 1); play(D_5, 2); play(CSH_5, 2); play(A_4, 2); play(FSH_4, 2); play(CSH_5, 2); play(FSH_5, 2); play(FSH_4, 1); play(E_4, 2); play(E_4, 1); play(CSH_4, 2); play(GSH_4, 2); play(FSH_4, 6); play(REST, 12); } delay(3000); }