Buenas notícias!
Ya he encontrado el fallo, o los fallos! Aquí os los pongo por si alguien le pasa lo mismo que yo:
Correción 1: guardar las muestras en parte real y parte imaginaria
Código:
Corrección 2:
La fft se realiza asi:
Saludos!
Ya he encontrado el fallo, o los fallos! Aquí os los pongo por si alguien le pasa lo mismo que yo:
Correción 1: guardar las muestras en parte real y parte imaginaria
Código:
Código:
void __attribute__ ((__interrupt__, no_auto_psv)) _ADCInterrupt(void)
{
IFS0bits.T3IF = 0; //Clear the Timer3 Interrupt Flag
IFS0bits.ADIF = 0; //Clear the A/D Interrupt flag bit or else the CPU will keep vectoring back to the ISR
if(tics%2 == 0 ){
sigCmpx[CountSamples].real = ADCBUF0;
}else{
sigCmpx[CountSamples].imag = ADCBUF0;
CountSamples++;
}
tics++;
if (CountSamples >= FFT_BLOCK_LENGTH){
doFilterFlag = 1;
CountSamples = 0;
tics = 0;
}
}
Corrección 2:
Código:
Código:
#define FFT_BLOCK_LENGTH 512 /* = Number of frequency points in the FFT */
#define LOG2_BLOCK_LENGTH 9 /* = Number of "Butterfly" Stages in FFT processing */ 2^9 = 512
#define SAMPLING_RATE 8000 /* = Rate at which input signal was sampled */
/* SAMPLING_RATE is used to calculate the frequency*/
/* of the largest element in the FFT output vector*/
La fft se realiza asi:
Código:
char FFTMotor(){
int i = 0;
double aux = 0;
fractional *p_real = &sigCmpx[0].real ; // posa al punter p_real l'@de memòria on es troba sigCmpx[0].real
fractcomplex *p_cmpx = &sigCmpx[0] ; // posa al punter p_cmpx l'@de memòria on es troba sigCmpx[0]
IEC0bits.ADIE = 0; //paro la interrupció per fer la FFT
sprintf(uTxt, "\r\n entro a la FFTMOTOR \r\n" );
putsUART1((unsigned int *)uTxt);
ThereIsARockFlag = 0;
doFilterFlag = 0;
p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real ; /* Set up pointers to convert real array */ // p_real = &sigCmpx[127].real posa a p_real l'@ de memòria de sigCmpx[127].real
p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1]; /* to a complex array. The input array initially has all */ // p_cmpx = &sigCmpx[255] posa a p_cmpx l'@ de memòria de sigCmpx[255]
/* the real input samples followed by a series of zeros */
for ( i = FFT_BLOCK_LENGTH; i > 0; i-- )
{
/* Convert the Real input sample array to a Complex input sample array */
(*p_cmpx).real = (*p_real--);
/* We will simpy zero out the imaginary part of each data sample */
(*p_cmpx--).imag = 0x0000;
}
#ifndef FFTTWIDCOEFFS_IN_PROGMEM
FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA);
#else
FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));
#endif
sigCmpx[0].real = 0; // remove signal continue
// Store output samples in bit-reversed order of their addresses
BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);
// Compute the square magnitude of the complex FFT output array so we have a Real output vetor
SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);
// Find the frequency Bin ( = index into the sigCmpx[] array) that has the largest energy
// i.e., the largest spectral component
VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);
// Compute the frequency (in Hz) of the largest spectral component
aux = 15.63; //((8000)/FFT_BLOCK_LENGTH);
peakFrequency = peakFrequencyBin*15.63; //(SAMPLING_RATE/FFT_BLOCK_LENGTH); //aux;
sprintf(uTxt, "\r\n Frequencia de Pic: %ld \r\n", peakFrequency);
putsUART1((unsigned int *)uTxt);
IEC0bits.ADIE = 0;
return 0;
}
Saludos!