I wrote a simple program that has 2 ISRs, one plays a music note, the other updates time every mS.
The problem that i am having is that when i disable the interrupt that updates the time, the tones are played as expected, however when i enable the time update interrupt, the some of the tones come and go and the program does not function correctly. Can you please help, Thank you
#include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #include <MC9S12C128.h> /* derivative information */ #include <stdio.h> #include <math.h> /// FUNCTIONS /// void initializePorts(void); void Delay(); byte getKey(); byte control(); void play(); /// GLOBAL VARIABLES /// volatile int msCount;
volatile int M; ////////////////////////////////////////////////////////
void main() { volatile byte MODES; initializePorts(); TSCR1 = 0x80; //Allows the timer to function TSCR2 = 1; //prescaler = 2, clock is at Buss Speed / 2 = 2MHz/2 = 1MHz TIE_C5I = 1; TIOS = 0xE0; //Chanal 7-5 isr act as an output campare with MCU timer //////////////////////////////////////////////////////////////////////////// // initializing timers and counters.. /// /////////////////////////////////////////////////////////////////////////// EnableInterrupts; for(; { MODES = control(); if(MODES == 1) play(); }/* loop forever */ }
///////////////// Timer6 Interrupt Service Routine ///////////// void interrupt 14 ISR_Timer6(void) { TC6 = TC6 + M; //802 TFLG1_C6F = 1; }
void interrupt 13 ISR_Timer5(void) { msCount++; TC5 = TC5 + 1000; // Interrupt again in 1 second, set the next match value for TC5, // When Timer chanal 5(TC5) matches the MCU counter, an interrupt occurs. TFLG1_C5F = 1; //when TC5 matches MCU timer, a flag is set, this flag must be cleared // in order to work interrupt again. Right here, we are clearing the flag // set for TC5 by clearing the flag set by TC5 //TCTL1 regesters connects timers to pins PT
}
void initializePorts() { DDRA = 0xFF; // PTA<7:0> - outputs (LEDs) DDRB = 0xF0; // Make PTB<7:4> outputs DDRM = 0x00; //Make Portm inputs PERM_PERM5; PERM_PERM4; return; }
void Delay(int mS){ int j; int count; for(j = 0; j < mS; j++){ for(count = 0; count < 300; count++) ; } return; }
byte getKey(){ byte row[4] = {1,2,4,8}; int count = 0; DDRT = 0x0F; //port T is rows, output DDRP = 0x00; //portp is coloumns, input PPSP = 0x0F; //pull down imput P which is coloumns for(count = 0; count < 4; count++){ PTT = row[count]; Delay(0); if(PTP_PTP0 == 1) return 4*count; else if(PTP_PTP1 == 1) return 4*count+1; else if(PTP_PTP2 == 1) return 4*count+2; else if(PTP_PTP3 == 1) return 4*count+3; } return 0XFF; }
/////////////////////////////////////////////////////////////////// // PLAY FUCNION //// ////////////////////////////////////////////////////////////////// void play() { byte keybounce; byte press; volatile int notes[16] = {1804,1607,1432,1352,1204,1073,1012,0,902,804,716,637,602,536,478,451}; PORTA = 0x11; TIE_C6I = 1; while(1) { press = getKey(); if(press == 7) { TIE_C6I = 0; TCTL1_OL6 = 0; return; } else if(press == 0xFF) TCTL1_OL6 =0; else { M = notes[press]; TCTL1_OL6 = 1; keybounce = press; while(keybounce == press) press = getKey();
} } }
/////////////////////////////////////////////////////////////////// // CONTROL FUNCTION (PLAY, RECORD, PLAYBACK) //// ////////////////////////////////////////////////////////////////// byte control(){
byte options; int blinker = msCount; PORTA = 0x00; while(1) { if(msCount - blinker > 200) { PORTA = ~PORTA; blinker = msCount; } options = getKey(); if(options == 0) return 1; else if(options == 1) return 2; else if(options == 2) return 3; } }
TFLG1_C5F = 1; //when TC5 matches MCU timer, a flag is set, this flag must be cleared
TFLG1_C6F = 1;
^^ these lines is wrong. TFLG1_C5F=1 clears all timer flags, not just C5F. TFLG1_C6F=1 clears all timer flags, not just C6F. Search forums if you wonder why it is so. Correct way to clear just C5F is this
TFLG1 = TFLG1_C5F_MASK;