/* Device configuration register macros for building the hex file */
_FOSC(CSW_FSCM_OFF & XT_PLL8); /* XT with 8xPLL oscillator,
Failsafe clock off */
_FWDT(WDT_OFF); /* Watchdog timer disabled */
_FBORPOR(PBOR_OFF & MCLR_EN); /* Brown-out reset disabled,
MCLR reset enabled */
_FGS(CODE_PROT_OFF); /* Code protect disabled */
/* Extern definitions */
extern fractcomplex sigCmpx[FFT_BLOCK_LENGTH] /* Typically, the
input signal to an FFT */
__attribute__ ((section (".ydata, data, ymemory"), /* routine is a
complex array containing samples */
aligned (FFT_BLOCK_LENGTH * 2 *2))); /* of an input signal.
For this example, */
/* we will provide the input signal in an */
/* array declared in Y-data space. */
/* Global Definitions */
#ifndef FFTTWIDCOEFFS_IN_PROGMEM
fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] /* Declare Twiddle
Factor array in X-space*/
__attribute__ ((section (".xbss, bss, xmemory"), aligned
(FFT_BLOCK_LENGTH*2)));
#else
extern const fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] /*
Twiddle Factor array in Program memory */
__attribute__ ((space(auto_psv), aligned (FFT_BLOCK_LENGTH*2)));
#endif
int peakFrequencyBin = 0; /* Declare post-FFT
variables to compute the */
unsigned long peakFrequency = 0; /* frequency of the largest
spectral component */
int main(void)
{
int i = 0;
fractional *p_real = &sigCmpx[0].real ;
fractcomplex *p_cmpx = &sigCmpx[0] ;
#ifndef FFTTWIDCOEFFS_IN_PROGMEM /* Generate
TwiddleFactor Coefficients */
TwidFactorInit (LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0); /* We
need to do this only once at start-up */
#endif
for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )/* The FFT function
requires input data */
{ /* to be in the fractional fixed-point range
[-0.5, +0.5]*/
*p_real = *p_real >>1 ; /* So, we shift all data samples
by 1 bit to the right. */
*p_real++; /* Should you desire to optimize this
process, perform */
} /* data scaling when first obtaining the time
samples */
/* Or within the BitReverseComplex function
source code */
p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real ; /* Set up
pointers to convert real array */
p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ; /* to a complex array. The
input array initially has all */
/* 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 */
(*p_cmpx--).imag = 0x0000; /* part of each data sample */
}
/* Perform FFT operation */
#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
/* 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 */
peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LENGTH);
while (1); /* Place a breakpoint here and observe the watch
window variables */
}
--
James M. Atkinson
President and Sr. Engineer
"Leonardo da Vinci of Bug Sweeps and Spy Hunting"
Granite Island Group
jm..._at_tscm.com
http://www.tscm.com/
(978) 546-3803
Received on Sat Mar 02 2024 - 00:57:23 CST