check for the Goertzel algorithm, it's easy to implement.
I have implement it for TMS320LF2401A from texas, using a 8000Hz sample rate, you must put the rutine det_DTMF inside a periodic interrupt that reaches at 8000 samples per second, use "y" like the sample at it moment. After 320 samples, in the arm array have the results:
#include "LF2401A.H"
// ***************************************************************************************************
/*
Coeficientes de Goertzel
kgt[n]=256*cos(6.2832*frec/8000 )
*/
const int t_kgt[]=
{
219, // 697Hz
211, // 770Hz
201, // 852Hz
189, // 941Hz
149, // 1209Hz
128, // 1336Hz
102, // 1477Hz
73 // 1633Hz
};
int arm[8]={0,0,0,0,0,0,0,0};
void inline det_DTMF(int y)
{
static int N_DTMF=0,arm_DTMF=0;
static int qn[8],qn1[8],qn2[8];
int * p_tb;
int j,c,d;
long mp;
int kgt;
// Lee el coeficiente de Goertzel de la armónica que estoy tratando
p_tb=(int *)t_kgt;
p_tb+=arm_DTMF;
kgt=WordReadFlash(p_tb);
// Hago la función de Goertzel
// mp=kgt*qn1[j]/128;
// Pero: Como qn1 puede ser > 256, entonces la multiplicación
// se sobrepasa de un int. Hay que tener cuidado con el
// manejo de longs, ya que ocupan mucho tiempo de proceso
mp=qn1[arm_DTMF];
mp*=kgt;
mp>>=7;
qn[arm_DTMF]=mp-qn2[arm_DTMF]+y;
qn2[arm_DTMF]=qn1[arm_DTMF];
qn1[arm_DTMF]=qn[arm_DTMF];
arm_DTMF++;
if (arm_DTMF== 8 )
{
N_DTMF++;
arm_DTMF=0;
}
// Cuando pasan las 320 muestras, proceso el resultado
// para filtrar las armónicas.
if (N_DTMF==320 )
{
for (j=0; j<8; j++)
{
p_tb=(int *)t_kgt;
p_tb+=arm_DTMF;
kgt=WordReadFlash(p_tb);
qn1[j]=abs(qn1[j])>>8;
qn2[j]=abs(qn2[j])>>8;
arm[j]=qn1[j]*qn1[j]+qn2[j]*qn2[j]+(((qn1[j]*qn2[j])>> 8 )*kgt)>>8;
arm[j]=abs(arm[j]);
if (arm[j]>0x0001) arm[j]=0xEEEE; else arm[j]=0x0000;
qn2[j]=0;
qn1[j]=0;
}
N_DTMF=0;
}
}