///////////////////////////////////////////////////////// // Joseph Kasnicki (jkk38) // // Colin Barth (csb42) // // ECE 476 Final Project // // Cornell Spring 2008 // // Uses fixed point and PWM code written by Bruce Land // // // // Bogey Warnings: // // 1. Return values, unreferenced parameters in // // fixed point code // // 2. Overflow possible in OCR0 computation // ///////////////////////////////////////////////////////// #include #include //for sine #include // for delay_us #include "notes.c" // Freqs and buttons for notes #include "fixed_point.c" // for fixed point multiply with mult_opt #define begin { //readability #define end } #define t_getButtons 20; // decode buttons every 20mSec unsigned char time_getButtons; #define countMS 62 // 62 ticks of timer0 = 1 mSec unsigned char count; //counts to 62 for ms counter //Microphone stuff //NEED AREF JUMPER DETACHED for 2.56V bandgap reference!!! unsigned char Ain; char blowing; char fadeIn; // 1 if need to be fading in char fadeOut; // 1 if need to be fading out #define MIC_SIZE 30 // size of shift register for ADC values #define MIC_THRESHOLD 120 // if ADC value is below this, user is blowing #define ADC_TIME_OUT 10 // look at every ADC_TIME_OUT values #define USE_FADES 1 // use 1, otherwise sound will POP unsigned char mic[MIC_SIZE]; // shift register for ADC values int multi; // fixed point int for fading in and fading out // stores current button values unsigned char fullPresses; unsigned char halfPresses; //assign memory locations for storing sinetable lookup values unsigned int acc @0x2f0; //the HIGH byte of the accumulator variable unsigned char highbyte @0x2f1; //(0x2f1 for 8 byte inc) signed char sineTable[256] @0x300; //need loc to avoid glitch unsigned int inc; //Variable for sinewave // Function prototypes void initialize(void); //set up ports and variables void getButtons(void); //decode the buttons every 20 mSec //********************************************************** //timer 0 overflow //Changes OCR0 for PWM interrupt [TIM0_OVF] void timer0_overflow(void) begin if (--count == 0) //Decrement the software timers every 1ms begin count = countMS; time_getButtons--; if (fadeOut == 1) begin if (USE_FADES == 1) begin //multiply by value < 1 until get to 0 if (multi < 0x0002) { multi = 0x0000; fadeOut = 0; } else if (multi >= 0x0100){ multi = 0x00ff; } else { multi = mult_opt(multi,0x00f0); } end else begin //should USE_FADES instead multi = 0x0000; TCCR0 = 1; fadeOut = 0; end end if (fadeIn == 1) begin if (USE_FADES == 1) begin //multiply by value > 1 until get to 1 if (multi < 0x0002) { multi = 0x0002; } else if (multi >= 0x00ff){ multi = 0x0100; fadeIn = 0; } else { multi = mult_opt(multi,0x0180); if (multi > 0x0100) multi = 0x0100; } end else begin //should USE_FADES instead multi = 0x0100; fadeIn = 0; end end end //increment accumulators for sineTable lookup acc = acc + inc; OCR0 = 128 + fix2int(mult_opt(multi,int2fix(sineTable[highbyte]))); end //********************************************************** // Return the bad note inc to play when an invalid button // combo is pressed int getBadNote(void) begin int val = 535; if ( (fullPresses&0x01) == 0x01 ) val -= 50; if ( (fullPresses&0x02) == 0x02 ) val -= 50; if ( (fullPresses&0x04) == 0x04 ) val -= 50; if ( (fullPresses&0x08) == 0x08 ) val -= 50; if ( (fullPresses&0x10) == 0x10 ) val -= 50; if ( (fullPresses&0x20) == 0x20 ) val -= 50; if ( (fullPresses&0x40) == 0x40 ) val -= 50; if ( (fullPresses&0x80) == 0x80 ) val -= 50; if ( (halfPresses&0x01) == 0x01 ) val += 100; if ( (halfPresses&0x02) == 0x02 ) val += 100; if ( (halfPresses&0x80) == 0x80 ) val += 100; return val; end void getButtons (void) begin time_getButtons = t_getButtons; //PortC and PortD are buttons // For buttons 0,6,7, halfPress is either button (not both), fullPress is both // For buttons 1-5, halfPresses never occur, so fullPress is either or both buttons halfPresses = PINC^PIND; fullPresses = (PINC&PIND)|(halfPresses & 0b01111100); halfPresses = halfPresses & 0b10000011; // fadeOut if user isn't blowing if (blowing == 0) begin fadeOut = 1; fadeIn = 0; return; end // fadeIn because user is blowing fadeOut = 0; fadeIn = 1; // set inc to proper value if (halfPresses == Cbuth && fullPresses == Cbutf) inc = Cinc; else if (halfPresses == CSbuth && fullPresses == CSbutf) inc = CSinc; else if (halfPresses == Dbuth && fullPresses == Dbutf) inc = Dinc; else if (halfPresses == DSbuth && fullPresses == DSbutf) inc = DSinc; else if (halfPresses == Ebuth && fullPresses == Ebutf) inc = Einc; else if (halfPresses == Fbuth && fullPresses == Fbutf) inc = Finc; else if (halfPresses == FSbuth && fullPresses == FSbutf) inc = FSinc; else if (halfPresses == Gbuth && fullPresses == Gbutf) inc = Ginc; else if (halfPresses == GSbuth && fullPresses == GSbutf) inc = GSinc; else if (halfPresses == Abuth && fullPresses == Abutf) inc = Ainc; else if (halfPresses == ASbuth && fullPresses == ASbutf) inc = ASinc; else if (halfPresses == Bbuth && fullPresses == Bbutf) inc = Binc; else if (halfPresses == Cbut2h && fullPresses == Cbut2f) inc = Cinc2; else if (halfPresses == CSbut2h && fullPresses == CSbut2f)inc = CSinc2; else if (halfPresses == Dbut2h && fullPresses == Dbut2f) inc = Dinc2; else if (halfPresses == DSbut2h && fullPresses == DSbut2f)inc = DSinc2; else if (halfPresses == Ebut2h && fullPresses == Ebut2f) inc = Einc2; else if (halfPresses == Fbut2h && fullPresses == Fbut2f) inc = Finc2; else if (halfPresses == FSbut2h && fullPresses == FSbut2f)inc = FSinc2; else if (halfPresses == Gbut2h && fullPresses == Gbut2f) inc = Ginc2; else if (halfPresses == GSbut2h && fullPresses == GSbut2f)inc = GSinc2; else if (halfPresses == Abut2h && fullPresses == Abut2f) inc = Ainc2; else if (halfPresses == ASbut2h && fullPresses == ASbut2f)inc = ASinc2; else if (halfPresses == Bbut2h && fullPresses == Bbut2f) inc = Binc2; else if (halfPresses == Cbut3h && fullPresses == Cbut3f) inc = Cinc3; // invalid buttons combo else inc = getBadNote(); end void main(void) begin int i; int time; time = 0; initialize(); TCCR0 = 0b01101001; //turn on PWM now while (1) begin if (time_getButtons==0) getButtons(); //ADC stuff //get the sample when it's ready while(ADCSR.6==1) {}; Ain = ADCH; time++; // look at every ADC_TIME_OUT values if (time == ADC_TIME_OUT) { time = 0; //shift in values for (i=0; i