/* TMS320F2812 FFT 源 码(包 括 详 细 的 注释 语句)
Fast Fourier Transform (FFT).
Using 8 points, takes about 1.2 ms to execute one FFT.
Sets up General Purpose Timer 1 to generate events at 10 kHz.
Will produce 10 kHz output on T1PWM and T1PWM pins. */
#include "system.h"
#include "eva.h"
#include "io2407.h"
#include "adc.h"
#include "interrup.h"
/* Complex structure definition*/
#include "fftcmplx.h"
extern void FFT(COMPLEX*Y,int N);
/* FFT Function */
/* The following define gives the number of samples. */
/* It should divide exactly into 512 */
/* Should N be increased, to say to 32, then the execution */
/* time of the FFT would increase */
#define N 8
unsigned int perform_fft=0 ;
/* Flag driven by interrupt */
/*************************************************************/
/*
Initialise General Purpose Timers GPT1 and GPT2
*/
/*************************************************************/
/* Initialise General Purpose Timer 1. */
void init_GPT1(void)
{
MCRA|=T1PWM ; /* Turn on T1PWM */
T1CON=0x8142 ; /* Turn off GPT1 */
GPTCONA=0x0041 ; /* Active low. */
T1PR=1475 ; /* Sample at 10 kHz */
T1CMPR=0 ; /* Duty = 0% */
T1CNT=0xFFFE ; /* Set to -2 */
T1CON=0x9142 ; /* Start timer 1 */
EVAIFRA=0xFFFF ; /* Clear any pending interrupts */
EVAIMRA|=T1PINT_FLAG ; /* Enable T1 period interrupt */
}
/* Initialise General Purpose Timer 2 */
void init_GPT2(void)
{
MCRA|=T2PWM ; /* Turn on T2PWM */
T2CON=0x8142 ; /* Turn off GPT2 */
GPTCONA|=0x0008 ; /* Controlled from GPT1 */
T2PR=1475 ; /* Sample at 10 kHz */
T2CMPR=0 ; /* Duty cycle 0% decimal */
T2CNT=0xFFFE ; /* Set to -2 */
T2CON=0x9142 ; /* Start timer 2 */
}
/**************************************************************/
void init_ADC()
{
/* Non Cascade for 8 measurements. */
/* Will affect RESULT0 to RESULT7 only */
/*| ADC_ACQ_PS3 | ADC_ACQ_PS2*/
ADCCTRL1=(ADC_SOFT|ADC_CPS);
CHSELSEQ1=0x3210 ; /* 8 measurements 0 */
CHSELSEQ2=0x0000 ;
CHSELSEQ3=0xFFFF ;
CHSELSEQ4=0xFFFF ;
MAX_CONV=0x0007 ; /* 8 measurements, not 0 */
/* Reset sequence at zero and software start of conversion */
ADCCTRL2=(RST_SEQ1|SOC_SEQ1);
}
/* No semicolon here */
/***********************************************************/
int input_buffer[N]=
{
8191,8191,8191,8191,0,0,0,0
};
COMPLEX y[N];
/* Variable passed to FFT and modified */
/***********************************************************
Shuffle input buffer along one place.
Put latest input from ADC into first buffer location.
Input from ADCIN2 lies in range 0 to FFC0h (65472 decimal).
Divide by 8 to limit range from 0 to 8184.
***********************************************************/
void shuffle_and_read(void)
{
signed int i ;
for(i=N-1;i>0;i--)
{
input_buffer=input_buffer[i-1];
}
input_buffer[0]=(RESULT2>>3);
}
/***********************************************************
Copy from input buffer to complex structure.
When FFT is performed, the complex structure is overwritten
by the return values.
***********************************************************/
void copy_input_to_complex(void)
{
unsigned int i ;
for(i=0;i<N;i++)
{
(y).real=input_buffer;
(y).imag=0 ;
}
}
/***********************************************************
Main program
Uses timers to read analog input on ADCIN2 into a buffer
and then perform an 8-point FFT on it.
**********************************************************/
void main(void)
{
signed int output1,output2 ;
signed int x ; /* General purpose variable. */
signed int i ; /* Counter */
signed long temp ;
init_system(); /* Initialize variables and hardware */
init_ADC(); /* Initialise ADC */
init_GPT1(); /* Turn on timer 1 */
init_GPT2(); /* Turn on timer 2 */
MCRB&=0xFFFE ; /* I/O on IOPC0 for monitoring purposes */
IMR|=INT2 ; /* Turn on INT 2 */
asm(" CLRC INTM"); /* Turn on maskable interrupts */
for(;;)
{
if(perform_fft!=0)
{
perform_fft=0 ; /* Clear flag used to start fft */
PCDATDIR=0x0101 ; /* IOPC0 high */
ADCCTRL2|=SOC_SEQ1 ; /* Start next conversion*/
copy_input_to_complex(); /* Copy inputs from receive buffer */
FFT(y,8);
/* Calls generic FFT function*/
/* Determine magnitude of (y[0]).real */
/* output1 lies in range 0 to 32736 */
if((y[0]).real>0)
output1=(y[0]).real ;
else
output1=-(y[0]).real ;
/* Determine magnitude of (y[0]).real */
/* output2 lies in range -32736 to 32736 */
if((y[2]).real>0)
output2=(y[2]).real ;
else
output2=-(y[2]).real ;
/* Scale output in range 0 to 1475 */
temp=(signed long)(output1*2952);
output1=(signed int)(temp>>16);
T1CMPR=output1 ;
temp=(signed long)(output2*2952);
output2=(signed int)(temp>>16);
T2CMPR=output1 ;
shuffle_and_read();
/* Read in latest value from ADC */
/* and put into buffer */
PCDATDIR=0x0100 ; /* IOPC0 low */
} /* End if */
} /* End for */
}/* End main() */
/************************************************************/
/* Interrupt routine */
/* The interrupt occurs once every 0.1 ms.
/* Will make perform_fft = 1 once every 20 * 0.1 ms = 2 ms */
void c_int2(void)
{
static unsigned int x ;
if(0x0027==PIVR)
{
EVAIFRA|=T1PINT_FLAG ;
/* Clear GPT1 period interrupt */
/* Increase if FFT with more points */
if(x<19)
{
x++;
}
else
{
x=0 ;
perform_fft=1 ; /* Global flag to start FFT */
}
}
}/* End of fft.c */
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |