首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

TMS320F2812 FFT 源 码

TMS320F2812 FFT 源 码

/* 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 */

返回列表