原创 STM32学习日志(24)----使用dsp库的FFT函数测相位

2011-4-20 12:12 7620 13 12 分类: MCU/ 嵌入式

attachment download


/**
  ******************************************************************************
  * @file FFT_Demo/src/main.c
  * @author  MCD Application Team
  * @version  V2.0.0
  * @date  04/27/2009
  * @brief  Main program body
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
  */
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <math.h>
#include "stm3210b_lcd.h"
#include "stm32_dsp.h"
#include "table_fft.h"   
//------------------------------------------------------------------------------


#define FreqSample      (50*NPT) // 50Hz*64=3200
#define ScalingFactor   20000  // 幅值系数,最大为32767
#define PERCENT_DC  0.06  // 直流分量对应的百分比,对应直流分量lBUFMAG[0]=1200
#define PI              3.1415926   
#define PI2             6.28318530717959   // 2*3.14
#define NPT             256                /* 采样点数,必须为64,256,1024之一*/


#if (NPT==64)
     #define cr4_fft_stm32 cr4_fft_64_stm32
#elif (NPT==256)
     #define cr4_fft_stm32 cr4_fft_256_stm32
#else
     #define cr4_fft_stm32 cr4_fft_1024_stm32
        error!!!!
        // 使用的ram超过了22K,超过了EK-STM32F仿真板上的STM32F103VBT6的ram
#endif
//------------------------------------------------------------------------------
extern volatile uint32_t TimingDelay ;
long lBUFIN[NPT];           /* Complex input vector */
long lBUFOUT[NPT];          /* Complex output vector */
long lBUFMAG[NPT + NPT/2];  /* Magnitude vector */
float lBUFPHASE[NPT + NPT/2];/* phase vector,单位为度 */


/* Private function prototypes -----------------------------------------------*/
void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2);
void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli);
void powerMag(long nfill, char* strPara);
void power_Phase_Radians(long nfill);
void DSPDemoInit(void);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
int main(void)
{
  DSPDemoInit();


  while (1)
  {
      MyDualSweep(FreqSample/NPT,6*FreqSample/NPT);     // 测试fft
  }
}
//-----------------------------------------------------------------------------


/**
  * @brief  Produces a combination of two sinewaves as input signal
  * @param freq1: frequency increment for 1st sweep,频率步进值1
  *   Freq2: frequency increment for 2nd sweep,频率步进值2
  * @retval : None
  */
void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2)
{
    uint32_t freq;
    
    freq = freqinc1;
    MygSin(NPT, FreqSample, freq, 0, ScalingFactor);       
    cr4_fft_stm32(lBUFOUT, lBUFIN, NPT);
    powerMag(NPT,"");       // lBUFIN[0]=1192 ,lBUFIN[1]=20008
    power_Phase_Radians(NPT);   
         
    freq = freqinc1;
    MygSin(NPT, FreqSample, freq, freqinc2, ScalingFactor);       
    cr4_fft_stm32(lBUFOUT, lBUFIN, NPT);
    powerMag(NPT,"");        // lBUFIN[0]=1192 ,lBUFIN[1]=20008, lBUFIN[6]=4000   
    power_Phase_Radians(NPT);
}
//------------------------------------------------------------------------------
/**
  * @brief  Produces a combination of two sinewaves as input signal
  * @param ill: length of the array holding input signal
  *   Fs: sampling frequency
  *   Freq1: frequency of the 1st sinewave
  *   Freq2: frequency of the 2nd sinewave
  *   Ampli: scaling factor
  * @retval : None
  */
void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli)
{
  uint32_t i;
  float fFs, fFreq1, fFreq2, fAmpli;
  float fZ,fY;


  fFs = (float) Fs;
  fFreq1 = (float) Freq1;
  fFreq2 = (float) Freq2;
  fAmpli = (float) Ampli;


  for (i=0; i < nfill; i++)
  {
    fY =PERCENT_DC/2            // 相位范围0°----360°
            + sin((196.0*PI/180.0)+PI2 * i * (fFreq1/fFs)) ;
    if (fFreq2)
            fY += 0.2*sin((293.0*PI/180.0)+PI2 * i * (fFreq2/fFs));
   
    fZ = fAmpli * fY;
 
// lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)
    lBUFIN= ((short)fZ) << 16 ;  /* sine_cosine  (cos=0x0) */
         // 高16bit为实部,低16bit为虚部,没有的话,就用0代替
  }
}
//------------------------------------------------------------------------------
/**
  * @brief  Removes the aliased part of the spectrum (not tested)
  * @param ill: length of the array holding power mag
  * @retval : None
  */
void onesided(long nfill)
{
  uint32_t i;
 
  lBUFMAG[0] = lBUFMAG[0];
  lBUFMAG[nfill/2] = lBUFMAG[nfill/2];
  for (i=1; i < nfill/2; i++)
  {
    lBUFMAG = lBUFMAG + lBUFMAG[nfill-i];
    lBUFMAG[nfill-i] = 0x0;
  }
}
//------------------------------------------------------------------------------
/**
  * @brief  Compute power magnitude of the FFT transform  进行FFT变换,并计算各次谐波幅值
  * @param ill: length of the array holding power mag
  *   : strPara: if set to "1SIDED", removes aliases part of spectrum (not tested)
  * @retval : None
  */
void powerMag(long nfill, char* strPara)
{
  int32_t lX,lY;
  uint32_t i;


  for (i=0; i < nfill/2; i++)
  {
    lX= (lBUFOUT<<16)>>16; /* 取低16bit,sine_cosine --> cos */
    lY= (lBUFOUT >> 16);   /* 取高16bit,sine_cosine --> sin */   
    {
      float X=  (float)lX*(NPT/32768.0);      
      float Y = (float)lY*(NPT/32768.0);
      float Mag = sqrt(X*X+ Y*Y)/nfill;
      lBUFMAG = (uint32_t)(Mag*65536);
    }   
  }
}
//------------------------------------------------------------------------------
/*
参考 labwindows的函数 ToPolar1D
Converts the set of rectangular coordinate points (arrayXReal, arrayXImg) to a
set of polar coordinate points (magnitude, phase). ToPolar1D obtains the 
element of the polar coordinate set using the following formulas:
 
The phase value is in the range [-pi: pi].


ToPolar1D can perform the operations in place;
that is, the input and output arrays can be the same.


 Prototype


AnalysisLibErrType ToPolar1D (double Array_X_Real[], double Array_X_Imaginary[], int Number_of_Elements, double Magnitude[], double Phase_Radians[]);


*/
void power_Phase_Radians(long nfill)
{
    int32_t lX,lY;
    uint32_t i;


    for (i=0; i < nfill/2; i++)
    {
        lX= (lBUFOUT<<16)>>16; /* 取低16bit,sine_cosine --> cos */
        lY= (lBUFOUT >> 16);   /* 取高16bit,sine_cosine --> sin */   
        {
            float X=  NPT*((float)lX)/32768;
            float Y = NPT*((float)lY)/32768;
            float phase = atan(Y/X);
             if (Y>=0)
             {
                if (X>=0)
                  ;
                else
                  phase+=PI; 
             }
             else
             {            
                if (X>=0)
                  phase+=PI2;                 
                else
                  phase+=PI;                   
             }                  
           
            lBUFPHASE = phase*180.0/PI;
        }   
    }
}
//------------------------------------------------------------------------------
/**
  * @brief  Inserts a delay time.
  * @param ount: specifies the delay time length (time base 10 ms).
  * @retval : None
  */
void Delay(uint32_t nCount)
{
  /* Configure the systick */
  __enable_irq();
   
     /* Setup SysTick Timer for 10 msec interrupts */
  if (SysTick_Config(SystemFrequency /100)) /* SystemFrequency is defined in
   搒ystem_stm32f10x.h?and equal to HCLK frequency */
   {
    /* Capture error */
     while (1);
    }    
  /* Enable the SysTick Counter */
  TimingDelay = nCount;
   while (TimingDelay )  {}    
   TimingDelay=0;
   __disable_irq();


}
//------------------------------------------------------------------------------
/**
  * @brief  Initializes the DSP lib demo (clock, peripherals and LCD).
  * @param  None
  * @retval : None
  */
void DSPDemoInit(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  ErrorStatus HSEStartUpStatus = ERROR;


  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();


  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);


  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();


  if(HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);


    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);


    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);


    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);


    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);


    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);


    /* Enable PLL */
    RCC_PLLCmd(ENABLE);


    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }


    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);


    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }


  /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
         | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);


  /* TIM1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);



  /* SPI2 Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);


  /* TIM2  and TIM4 clocks enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM4, ENABLE);


  /*------------------- Resources Initialization -----------------------------*/
  /* GPIO Configuration */
  /* Configure PC.06 and PC.07 as Output push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);



  /*------------------- Drivers Initialization -------------------------------*/
  /* Initialize the LCD */
  STM3210B_LCD_Init();


  /* Clear the LCD */
  LCD_Clear(White);


  LCD_SetTextColor(White);
  LCD_SetBackColor(Black);


}
//------------------------------------------------------------------------------
#ifdef  USE_FULL_ASSERT


/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */


  /* Infinite loop */
  while (1)
  {
  }
}
#endif


/**
  * @}
  */


/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1531493 2013-3-9 04:38

学习一下!谢谢楼主分享!

用户1531529 2011-7-28 16:23

我用IAR ARMV6.21版本编译的,怎么很多错误啊~求教

用户1531529 2011-7-28 16:11

博主,您好。我想问下你这个工程是用那个编译器的。MDK,还是IAR的。我下载后 怎么找不到工程
相关推荐阅读
sz_lihongtao 2011-04-20 21:32
32bit无符号数快速开平方根
//*******************************************************************************// 32bit无符号数开平方根// ...
sz_lihongtao 2011-04-19 14:57
STM32学习日志(23)----使用dsp库的FFT函数.rar
attachment download/**  ****************************************************************************...
sz_lihongtao 2011-04-19 10:39
stm32 dsp lib V2.0
attachment downloadattachment download...
sz_lihongtao 2011-04-19 10:37
STM32学习日志(22)----使用DMA功能自动更新PWM的输出
attachment download/*******************************************************************************编...
sz_lihongtao 2010-09-08 21:59
Labwindows/cvi8.5学习日志(56)----任意波形发生器
//******************************************************************************// Labwindows/cvi8.5...
EE直播间
更多
我要评论
3
13
关闭 站长推荐上一条 /3 下一条