⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft.c

📁 dsp arm的很多讲义和说明。 关于怎样使用ccs bios以及matlab到dsp的代码转化
💻 C
字号:
/****************************************************************************
**                       $TITLE: FFT.C$
** FFT.C
** ---------
**    Brings data in from the codec, and runs it through an fft algorithm.
**    the data can be plotted in real time at the host or be sent to 
**    oscilloscope through the codec.
**
****************************************************************************/
/*--------------------------------------------------------------------------
   EXTERNAL DECLARATIONS
--------------------------------------------------------------------------*/
extern volatile int user_tx_buf[6];
extern volatile int user_tx_ready;
extern volatile int user_rx_buf[6];
extern volatile int user_rx_ready;
/*--------------------------------------------------------------------------
    INCLUDES
--------------------------------------------------------------------------*/
#include <def21060.h>
#include <21065l.h>
#include <signal.h>
#include <macros.h>
#include <limits.h>
#include <trans.h>
#include <float.h>
#include <math.h>
#include <ezkit/1819regs.h>

/*--------------------------------------------------------------------------
   CONSTANT & MACRO DEFINITIONS
--------------------------------------------------------------------------*/
#define PI	3.1425926
/* Codec tag word to send out left and right samples */
#define DOUT_TAG         0x9800

/* Codec tag word to send out address and data slots */
#define REGOUT_TAG       0xe000

/* This is the codec register setting for line input on both channels */
#define SOURCE_IS_LINE   0x0404
/* This is the codec register setting for mic input on both channels */
#define SOURCE_IS_MIC   0

/* interrupt SIG_SPT1I's service routine Address*/ 
#define CODEC_ISR_VECT 0X9001

/* Codec addreses */
#define SOURCE_ADDR      0x1a00
#define RECGAIN_ADDR     0x1c00
/* Number of sample points in the calculation */
#define NUM_POINTS 256
#define BETWEEN_SAMPLES  25000   
/* The program can be in 1 of 3 modes.  The other mode is a wait mode
   and is anything greater than 2 */
#define SAMPLE_MODE     1
#define CALCULATE_MODE  2
/*--------------------------------------------------------------------------
   GLOBAL DECLARATIONS
--------------------------------------------------------------------------*/
int mode; //  mode 1 = collecting data points. mode 2 = calculating FFT

int data_count;//ADC sample Counter
int out_count;//DAC Output	Counter

int window;//control the window type
float Windows[NUM_POINTS];//Windows
/* Use this array for calculating the FFT, then copy result into data[] */
int tempdata[NUM_POINTS];
float fdata[NUM_POINTS];     /* array to convertg int points to floats */
float Magnitude[NUM_POINTS];

/* The output data is stored here */
int	OutputBuffer[NUM_POINTS];
/*--------------------------------------------------------------------------
   FUNCTION PROTOTYPES
--------------------------------------------------------------------------*/
void main (void);
void sample_codec( void );
void init_codec( void );

/****************************************************************************
** Procedure:  sample_codec()
**
** Arguments:  None
**
** Returns:    None
**
** Desc:       Gets data in from the codec and sends the output buffer to the codec.
**             If mode = SAMPLE_MODE, 128 consecutive samples are taken from the 
**             codec for calculating the FFT.
**
****************************************************************************/
void sample_codec( void )
{
// Copy output buffers to transmit data buffers.

   user_tx_buf[LEFT_CHANL] = OutputBuffer[out_count];
   user_tx_buf[RIGHT_CHNL] = OutputBuffer[out_count];
   out_count++;
   if(out_count>=NUM_POINTS) out_count=0;
   user_tx_buf[TAG] = DOUT_TAG;
   user_tx_ready = 1;  
 
   /* Put this sample in the array if we're in sample mode */
   if( mode == SAMPLE_MODE )
   {
      tempdata[data_count] = user_rx_buf[LEFT_CHANL];
      data_count++;
      
      /* If we have 256 samples, stop sampling and calculate */
      if( data_count >= 256 )
      {
          data_count = 0;
          mode = CALCULATE_MODE;
      }
   }
}
/****************************************************************************
**
** Procedure:  init_codec()
**
** Arguments:  None
**
** Returns:    None
**
** Desc:       Turns on the codec interrupt then initializes the codec
**             source and record gain.
**
****************************************************************************/
void init_codec( void )
{
   asm("#include <def21065l.h>");
   interrupt(SIG_SPT1I,(void (*)(int))CODEC_ISR_VECT);
   asm("BIT SET IMASK SPT1I;");   /* unmasks sport interrupt */
    
   /* Set source to LINE */
   user_tx_buf[TAG] =  REGOUT_TAG;
   user_tx_buf[ADDR] = SOURCE_ADDR;
   user_tx_buf[DATA] = SOURCE_IS_LINE;
   user_tx_ready = 1;
   idle();                       /* Wait for codec register to get set */
   idle();

   /* Set record gain */
   user_tx_buf[TAG] =  REGOUT_TAG;
   user_tx_buf[ADDR] = RECGAIN_ADDR;
   user_tx_buf[DATA] = 0;
   user_tx_ready = 1;
   idle();                      /* Wait for codec register to get set */
   idle();

   return;
}
/****************************************************************************
**
** Procedure:  main()
**
** Arguments:  None
**
** Returns:    None
**
** Desc:       Sets everything up and then goes into its sampling and
**             processing loop.
**
****************************************************************************/
void main ( void )
{
   int i;                       /* counter variable */
   int cntr;                    /* counter variable */

   float fmin, fmax; 
   float range; 
   float i_output[NUM_POINTS];  /* Imaginary part of FFT */
   float r_output[NUM_POINTS];  /* Real part of FFT */
   int *optr;                  
   float *fptr, *rptr, *iptr;
   float favg;
   int offset;
   float scale_value;
   
   window =	0; 
 
   fmin = FLT_MAX;  /* make sure the min is updated the first time */
   fmax = FLT_MIN;  /* make sure the max is updated the first time */
   data_count = 0;
   out_count = 0;
   mode = SAMPLE_MODE;   /* Start with the first 128 samples */
   
   init_codec();         /* Set up codec for line in */
   
   if(window)  	{for(i=0;i<NUM_POINTS;i++)	Windows[i]=0.54-0.46*cos(2*PI*i/(NUM_POINTS-1));}
   	   else  {for(i=0;i<NUM_POINTS;i++)	Windows[i]=1.0;}
   
   for(;;)              /* Start the sample/calculate/wait loop */
   {

        /* Just after accumulating the 128 points, calculate the FFT */
        if( mode == CALCULATE_MODE )
        {

            for( i=0 ; i<NUM_POINTS ; i++ )
                fdata[i] =(float)tempdata[i]*Windows[i];
            

                            
                offset = 50;
                scale_value = 25.0;

                /* do FFT.*/
                rfft256( fdata, r_output, i_output );
                
                /* do Magnitude*/
                fptr = Magnitude;
                rptr = r_output;
                iptr = i_output;
                for( i=0 ; i<NUM_POINTS ; i++ )
                {
                    *fptr = *rptr * *rptr + *iptr * *iptr;
                    fptr++;
                    iptr++;
                    rptr++;
                }
            

            	/*Scale initialize*/
  
                fmin = FLT_MAX;
                fmax = FLT_MIN;

                  /* log	Scale*/
                fptr = Magnitude;
                for( i=0 ; i<NUM_POINTS ; i++ )
                {
                    if( *fptr < 0.0 )
                        *fptr = -logf( -*fptr );
                    else
                        *fptr = logf( *fptr );
                    fptr++;
                }
           /* search the array's max and min to scale*/
            favg = 0;
            fptr = &Magnitude[0];
            for( i=0 ; i<NUM_POINTS ; i++ )
            {
                fmax = fmax > *fptr ? fmax : *fptr;
                fmin = fmin < *fptr ? fmin : *fptr;
                favg += *fptr;
                fptr++;
            }
            favg /= (NUM_POINTS - 2);
            range = fmax - favg;
        
            optr = OutputBuffer;
            fptr = Magnitude;
            for( i=0 ; i<NUM_POINTS ; i++ )
            {
                *optr++ = (offset + (int)(scale_value * ( (*fptr++ - favg) / range )))*100;
            }
            OutputBuffer[0]=16383;//set trigger

	  }


      /* don't calculate the FFT every 256 samples*/
      if (mode >= CALCULATE_MODE)
      {
         mode++;
		if (mode >= BETWEEN_SAMPLES)
         {   
            mode = SAMPLE_MODE;
         }
      }

	  user_rx_ready = 1;          /* Tell codec isr we're ready for data */
      while(user_rx_ready) idle(); /* Wait for codec data */
      sample_codec();              /* Get data */
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -