#include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE "mc9s12c32" #define SONGSIZE 10 //There are 10 notes in this song void music_isr(void); void music_init(void); char getnoteflag, noteptr, note_number; long int dur_nr_half_cycles; long int SIXTEENTHNOTE = 300000; // SIXTEENTHNOTE = nr of timer ticks for 0.2 sec sixteenth note int tone_val, dur_counter; const char duration[SONGSIZE]={2,2,3,1, 1, 1, 2, 2, 3, 4}; //This is the RHIT fight song, const char tone[SONGSIZE]={6,7,8,10,11,13,15,13,11,25}; //"Dear Old Rose!" const int tone_table[25]={6818,6435,6074,5733, 5412, 5108, 4821, 4550, 4295, 4054, 3827, 3612, 3409, 3218, 3037, 2867, 2706, 2554, 2411, 2148, 2027, 2027, 1806, 1705, 1609}; void main(void) { music_init(); for(;;); } void music_init() { getnoteflag = 1; // Set getnoteflag = 1, so first interrupt will fetch a note // from tone[] and duration[] arrays. noteptr = 0; // Make noteptr point to first note in tone[ ] and duration[ ]. dur_counter = 0; // Clear Duration Counter, which counts nr.of half cycles a note is played. DDRM_DDRM0 = 1; // Make PTM0 an output (this is the output pin that will play music) PTM_PTM0 = 0; // Set PTM0 low. TSCR2 = 3; // Assuming 24 MHz bus clock, Tick time = 8/24E6 = 333.3333 ns TSCR1 = 0x80; // Turn on timer TIOS = 1; // Make TC0 an Output Compare TC0 = TCNT + 25; // Schedule first TC0 interrupt in 25 timer ticks TFLG1 = 1; // Clear TC0 interrupt flag TIE = 1; // Locally Enable TC0 interrupts EnableInterrupts; // Globally Enable TC0 interrupts } // This interrupt routine is entered every time an output compare on TC0 occurs // This should be every half of a note cycle. void interrupt music_isr( ) { TFLG1 = 1; //Relax TC0 interrupt if(getnoteflag == 1) { getnoteflag = 0; note_number = tone[noteptr]; //Look up the number of the next note if(note_number > 24) note_number = 25; // If an invalid note number (> 24) is entered, // make it a rest = 25. tone_val = tone_table[note_number]; // tone_val = nr of ticks in half cycle of note dur_nr_half_cycles = duration[noteptr]*(SIXTEENTHNOTE / tone_val); // SIXTEENTHNOTE sets the speed at which //the musical composition is played. Note 'dur_nr_cycles" // is the number of cycles in the note. dur_counter = 0; // Reset duration counter noteptr++; // Increment noteptr. if(noteptr > SONGSIZE) noteptr = 0; // If song complete, wrap back to beginning. } else { if (note_number < 25) PTM_PTM0 = ~PTM_PTM0; // Toggle PTM0 output pin dur_counter++; // increment duration counter if(dur_counter > dur_nr_half_cycles) getnoteflag = 1; // Set getnoteflag = 1 if at the end of the not } TC0 = TC0 + tone_val; // Schedule next TC0 interrupt }