Sunteți pe pagina 1din 7

Readme File for Code Example: CE018 - Using the Fast Fourier Transform (FFT) for Frequency Detection

---------------------------------------------------------------------This file contains the following sections: 1. Code Example Description 2. Folder Contents 3. Suggested Development Resources 4. Reconfiguring the project for a different dsPIC30F device 5. Reconfiguring the project for a different FFT Size: 6. Revision History 1. Code Example Description: ---------------------------Microchip's 16-bit dsPIC Digital Signal Controllers feature a DSP Engine in the C PU that is capable of executing a Fast Fourier Transform (FFT) with great effici ency (high speed and low RAM usage). The on-chip features enabling the FFT imple mentation include, bit-reversed addressing, Multiply-accumulate (MAC) type instr uctions and the ability to store and retrieve constants stored in Program memory . Microchip provides a DSP functions library that provides in-place FFT functions. In this code example, we demonstrate how the DSP library functions can be used t o perform an FFT on an input signal (vector). The code example is reconfigurable to perfrom an FFT of any size, including common sizes of 64, 128, 256 and 512 p oints. The code example also allows the user to place the FFT coefficients (know n as Twiddle Factors) in RAM or in Program Flash Memory. The project may be easi ly reconfigured by modifying the header file, FFT.h. By default, the example imp lements a 256-point FFT using coefficients stored in Program Flash memory. The input signal for our example will be 256 points of a Square wave signal of f requency 1KHz sampled at 10 KHz. This signal was first generated by dsPICworks a nd then exported as an assembler file from dsPICworks. After exporting it out, t he assembler file was modified to ensure the samples reside in Y-data space. The FFT operation is performed on the input signal, in-place. This means that th e output of the FFT resides in the same RAM locations where the input signal use d to reside. The FFT is performed in the following steps: 1. Initialization: Generate Twiddle Factor Coefficients and store them in X-RAM or alternately use twiddle factor coefficients stored in Program Flash. 2. Scale the input signal to lie within the range [-0.5, +0.5]. For fixed point fractional input data, this translates to input samples in the range [0xC000,0x3 FFF]. The scaling is achieved by simply right-shifting the input samples by 1 bi t, assuming the input samples lie in the fixed point range [0x8000,0x7FFF] or [1,+1). 3. Convert the real input signal vector to a complex vector by placing zeros in every other location to signify a complex input whose imaginary part is 0x0000. 4. Butterfly computation: This is achieved by performing a call to the FFTComple xIP() function. 5. Bit-Reversed Re-ordering: The output array is re-ordered to be in bit-reverse d order of the addresses. This is achieved by a function call to BitReverseCompl ex().

6. SquareMagnitude computation: We then need to compute the magnitude of each co mplex element in the output vector, so that we can estimate the energy in each s pectral component/frequency bin. This is achieved by a call to a special C-calla ble routine, SquareMagnitudeCplx(), written in assembler language. This routine will be incorporated into the DSP library in future revisions of the C30 toolsu ite. At that time, you may remove the source file, cplxsqrmag.s from the project and include the latest DSP library file, libdsp-coff.a. 7. Peak-picking: We then find the frequency component with the largest energy by using the VectorMax() routine in the DSP library. 8. Frequency Calculation: The value of the spectral component with the highest e nergy, in Hz, is calculated by multiplying the array index of the largest elemen t in the output array with the spectral (bin) resolution ( = sampling rate/FFT s ize). 2. Folder Contents: ------------------This folder contains the following sub-folders: a. gld This folder contains the linker script file for the example project. This file is used for building the project. This file was provided with the MPLAB C30 v1.33 toolsuite. b. h This folder contains C header files useful in building this project. Device register and bit definitions are provided in the *.h file that follows the device name. These files were provided with the MPLAB C30 v1.33 toolsuite. c. hex This folder contains three file types - coff, hex and map. These are files generated by the MPLAB C30 toolsuite on build operation performed within MPLAB IDE. The *.map file contains details on memory allocation for various variables, constants and dsPIC30F instructions specified in the source and library code. The *.hex file contains a binary file that may be programmed into the dsPIC30F device. The *.coff file contains a binary file that is used by MPLAB IDE for simulation. d. inc This folder contains Assembler include files useful in building this project. Device register and bit definitions are provided in the *.inc file that follows the device name. These files were provided with the MPLAB C30 v1.33 toolsuite. e. lib This folder contains library archive files, which are a collection of precompiled object files. The file named "libpic30-coff.a" contains the C run-time start-up library. These file were provided with the MPLAB C30 v1.33 toolsuite. f. src This folder contains all the C and Assembler source files (*.c, *.s) used in demonstrating the described example. This folder also contains a sub-folder named "obj" that stores compiled object files generated when the project is built.

g. dsPICworks This folder contains files created by dsPIC Filter Design and dsPICworks Data Analysis and Design Software. Input signal files, output signal files and filter specifications have been provided here. 3. Suggested Development Resources: ----------------------------------a. MPLAB IDE v7.21 or later b. MPLAB C30 v1.33 or later c. MPLAB ICD 2 R23 or later d. dsPICDEM 1.1 Development Board (See below) e. dsPIC30F6014A Digital Signal Controller Plug-In Module (See below) 4. Reconfiguring the project for a different dsPIC30F device: ------------------------------------------------------------The Project/Workspace can be easily reconfigured for any dsPIC30F device. Please use the following general guidelines: a. Change device selection within MPLAB IDE to a dsPIC30F device of your choice by using the following menu option: MPLAB IDE>>Configure>>Select Device b. Provide the correct device linker script and header file for your device. Device linker scripts and header files are available in your MPLAB C30 installation folder under: Device Linker ScriptYourDrive:>Program Files\Microchip\MPLAB C30\support\gld Device C Header fileYourDrive:>Program Files\Microchip\MPLAB C30\support\h Device ASM Include fileYourDrive:>Program Files\Microchip\MPLAB C30\support\inc c. Provide the appropriate path to your MPLAB C30 support file locations using the menu option: MPLAB IDE>>Project>>Build Options>>Project d. Chose the development board applicable to your device. Some options are provided below: - dsPICDEM 2 Development Board supports: 30F2010, 30F2011, 30F2012, 30F3010, 30F3011, 30F3012, 30F3013, 30F3014, 30F4011, 30F4012, 30F4013 - dsPICDEM 1.1 Development Board supports: 30F5013, 30F6010, 30F6011, 30F6012, 30F6013, 30F6014, 30F6011A, 30F6012A, 30F6013A, 30F6014A - dsPICDEM MC1 Development Board supports: 30F6010, 30F6010A, 30F5016 e. Re-build the MPLAB project using the menu option: MPLAB IDE>>Project>>Build All f. Download the hex file into the device and run. 5. Reconfiguring the project for a different FFT Size: ------------------------------------------------------------The project has been configured for a 256-pt FFT to be performed on a 30F6014A d evice. Perform the following steps in sequence to change the device and FFT size.

(i) Change device selection within MPLAB IDE to a dsPIC30F device of your choice by using the following menu option: MPLAB IDE>>Configure>>Select Device (ii) Provide the correct device linker script and header file for your device. Device linker scripts and header files are available in your MPLAB C30 installation folder under: Device Linker ScriptYourDrive:>Program Files\Microchip\MPLAB C30\support\gld Device C Header fileYourDrive:>Program Files\Microchip\MPLAB C30\support\h Device ASM Include fileYourDrive:>Program Files\Microchip\MPLAB C30\support\inc (iii) In the file FFT.h, perform the following changes: - Change FFT_BLOCK_LENGTH to either 64, 128, 256 or 512 - Correspondingly, change LOG2_BLOCK_LENGTH to either 6, 7, 8 or 9 respectively - If you would like to store Twiddle Factors coefficients in RAM instead of Program Memory comment out the line of code as shown: "//#define FFTTWIDCOEFFS_IN_PROGMEM " (iv) This project uses an input squarewave signal provided as PCM samples in the file, "inputsignal_square1khz.c" in the array named "sigCmpx[]". This array should be of length, FFT_BLOCK_LENGTH and type "fractcomplex". So, for a 64-pt FFT, it should contain only 64 data samples and padded initially with 64 zeroes. This array stores the output of the complex FFT operation and eventually stores the magnitudes of the frequency bins. Modify this array to suit the FFT size you are using. In a real application, your data will likely be input from a real-world signal. (v) Re-build the MPLAB project using the menu option: MPLAB IDE>>Project>>Build All (vi) Download the hex file into the device and run. 6. Revision History : --------------------09/30/2005 - Initial Release of the Code Example 01/05/2006 - Corrected cplxsqrmag.s 01/17/2006 - Added "5. Reconfiguring the project for a different FFT Size:" in this readme file and corrected an extern definition in the main_FFTExample.c file /********************************************************************** * 2005 Microchip Technology Inc. * * FileName: main_FFTExample.c * Dependencies: Header (.h) files if applicable, see below * Processor: dsPIC30Fxxxx * Compiler: MPLAB C30 v1.33.00 or higher * IDE: MPLAB IDE v7.20.01 or later * Dev. Board Used: dsPICDEM 1.1 Development Board * Hardware Dependencies: None * * SOFTWARE LICENSE AGREEMENT:

* Microchip Technology Inc. ( Microchip ) licenses this software to you * solely for use with Microchip dsPIC digital signal controller * products. The software is owned by Microchip and is protected under * applicable copyright laws. All rights reserved. * * SOFTWARE IS PROVIDED AS IS. MICROCHIP EXPRESSLY DISCLAIMS ANY * WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP * BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL * DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), * ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. * * REVISION HISTORY: *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Author Date Comments on this revision *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * HV 09/30/05 First release of source file * *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * ADDITIONAL NOTES: * * **********************************************************************/ #include <p30Fxxxx.h> #include <dsp.h> #include "fft.h" /* Device configuration register macros for building the hex file */ _FOSC(CSW_FSCM_OFF & XT_PLL8); /* XT with 8xPLL oscillator, Failsafe cl ock 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 sign al to an FFT */ __attribute__ ((section (".ydata, data, ymemory"), /* routine is a complex ar ray 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 arr ay 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; the */ unsigned long peakFrequency = 0; mponent */

/* Declare post-FFT variables to compute /* frequency of the largest spectral co

int main(void) { int i = 0; fractional *p_real = &sigCmpx[0].real ; fractcomplex *p_cmpx = &sigCmpx[0] ; #ifndef FFTTWIDCOEFFS_IN_PROGMEM /* Generate TwiddleFactor Coeffic ients */ 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 da ta */ { /* 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 conv ert real array */ p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ; /* to a complex array. The input arra y 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 arr ay */ { /* 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_D ATA); #else FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvo ffset(&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 la

rgest 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); iables */ } /* Place a breakpoint here and observe the watch window var

--------------------------------------------------------------------------------------/* Constant Definitions */ #define FFT_BLOCK_LENGTH 256 /* = Number of frequency points in the FFT */ #define LOG2_BLOCK_LENGTH 8 /* = Number of "Butterfly" Stages in FFT proces sing */ #define SAMPLING_RATE 10000 /* = Rate at which input signal was sampled * / /* SAMPLING_RATE is used to calculate th e frequency*/ /* of the largest element in the FFT out put vector*/ #define FFTTWIDCOEFFS_IN_PROGMEM widdle factors (coefficients) */ rogram Memory */ /*Then remove the call to "TwidFactorInit()" and add the twiddle factor*/ /*coefficient file into your Project. An exam ple file for a 256-pt FFT*/ /*is provided in this Code example */ --------------------------------------------------------------------------------------------/*<---Comment out this line of the code if t /*reside in data memory (RAM) as opposed to P

S-ar putea să vă placă și