#include <16F628.h>
#use delay(clock=4000000)
#fuses XT,PUT,BROWNOUT,MCLR,NOWDT,NOPROTECT,NOLVP
#define TONE_PIN PIN_A0
#define nSIZE 25
long ErrCor;
// NOTE FREQUENCY
// Octave0 Octave1 Octave2 Octave3
const long C_NOTE[4] ={ 262, 523, 1047, 2093};
const long Cf_NOTE[4] ={ 277, 554, 1109, 2217};
const long D_NOTE[4] ={ 294, 587, 1175, 2349};
const long Df_NOTE[4] ={ 311, 622, 1245, 2489};
const long E_NOTE[4] ={ 330, 659, 1329, 2637};
const long F_NOTE[4] ={ 349, 698, 1397, 2794};
const long Ff_NOTE[4] ={ 370, 740, 1480, 2960};
const long G_NOTE[4] ={ 392, 784, 1568, 3136};
const long Gf_NOTE[4] ={ 415, 831, 1661, 3322};
const long A_NOTE[4] ={ 440, 880, 1760, 3520};
const long Af_NOTE[4] ={ 466, 923, 1865, 3729};
const long B_NOTE[4] ={ 494, 988, 1976, 3951};
void generate_tone(long frequency, long duration);
void do_delay(int ms_delay, int num_ms, int us_delay, int num_us);
const struct note2
{
long tone;
long length;
} happy_bday[nSIZE] = {
C_NOTE[0],350, C_NOTE[0],100, D_NOTE[0],500, C_NOTE[0],500, F_NOTE[0],500, E_NOTE[0],900,
C_NOTE[0],350, C_NOTE[0],100, D_NOTE[0],500, C_NOTE[0],500, G_NOTE[0],500, F_NOTE[0],900,
C_NOTE[0],350, C_NOTE[0],100, C_NOTE[1],500, A_NOTE[0],500, F_NOTE[0],500, E_NOTE[0],500, D_NOTE[0],900,
Af_NOTE[0],350, Af_NOTE[0],100, A_NOTE[0],500, F_NOTE[0],500, G_NOTE[0],500, F_NOTE[0],1200};
void do_delay(int ms_delay, int num_ms, int us_delay, int num_us)
{
int i;
for(i=0;i<num_ms;i++)
delay_ms(250);
delay_ms(ms_delay);
for(i=0;i<num_us;i++)
delay_us(250);
delay_us(us_delay);
}
void generate_tone(long frequency, long duration)
{
int32 total_delay_time; // in microseconds
long TmsD, TusD;
int num_us_delays, num_ms_delays, ms_delay_time, us_delay_time;
long num_periods;
total_delay_time = (int32)(1000000/frequency)/2-ErrCor; // calculate total delay time (10 for error)
if(total_delay_time>10000)
return;
TmsD = total_delay_time/1000; // total delay time of ms
num_ms_delays = TmsD/250; // number of 250ms delays needed
ms_delay_time = TmsD%250; // left over ms delay time needed
TusD = total_delay_time%1000; // total delay time of us (ms already acounted for)
num_us_delays = TusD/250; // number of 250us delays needed
us_delay_time = TusD%250; // left over us delay time needed
num_periods = ((unsigned int32)duration*1000)/(1000000/frequency);
while((num_periods--) != 0)
{
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
output_high(TONE_PIN);
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
output_low(TONE_PIN);
}
return;
}
//*** MAIN ***
void main()
{
int i;
set_tris_a(0B11111110);
ErrCor=10;
for(i=0;i<nSIZE;i++)
{
generate_tone(happy_bday[i].tone,happy_bday[i].length);
}
}
|