The software running on the PIC contains 3 main portions:
-A/D Input Interrupt
-Timer Output Interrupt
-Main Switch Function
The A/D Input Interrupt is a quick and simple low priority interrupt. The timer interrupt takes high priority because we want the speaker sound to be crystal clear.
Low and High Priority Interrupts
------------« Begin Code »------------
void InterruptHandlerHigh()
{
if(INTCONbits.TMR0IF)
{
//Reset The Timer Value
WriteTimer0( timer0_val );
//If a valid 'note' is stored in timer0_val, Play It!
if( timer0_val <= 0xFB55 && timer0_val >= 0xED56){
sound_state = (sound_state ^ 0xFF) & new_volume;
PORTD = sound_state;
}
INTCONbits.TMR0IF = 0;
}
INTCONbits.GIEH = 1; //Re-enable all high priority interrupts
return;
}
void InterruptHandlerLow()
{
if(PIR1bits.ADIF == 1){
//AD Interrupt Triggered, Read The Value
ad_val = ReadADC();
//Set AD Value Ready
ad_ready = 1;
PIR1bits.ADIF = 0;
}
INTCONbits.GIEL = 1; //Re-enable all low priority interrupts
return;
}
------------« End Code »------------
The code above should be straight forward. The interrupts are not suppose to be processor hogs, they should be quick, simple and as short as possible.
Main Switch
------------« Begin Code »------------
..
...
ConvertADC(); // Start conversion
if(ad_ready == 1){
//Calculate The Distance Using The Formula
result = pow(3027.4/ad_val,1.2134);
//Convert The Distance From Float to Integer
distance = (int) result;
//Clear AD_ready because we used the ADC result
ad_ready = 0;
//Change The Timer0_val according to distance
switch(distance){
//C4
case 11 :
case 12 :
case 13 :
case 14 :
case 15 : timer0_val = 0xED56;
break;
..
...
....
..
//C5
case 46 :
case 47 :
case 48 :
case 49 :
case 50 : timer0_val = 0xF6AB;
break;
default : timer0_val = 0x0000;
}
}
Delay10KTCYx(1);
...
..
------------« End Code »------------
The main function of this project tells the A/D converters to start and then computes the distance away the object is from the sensor and passes that value to a switch statement. Depending on what value timer0_val gets updated with tells the timer0 to play a different tone on PORTD. This process happens over and over forever until the batteries die.