/**
******************************************************************************
* @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>© 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****/
用户1531493 2013-3-9 04:38
用户1531529 2011-7-28 16:23
用户1531529 2011-7-28 16:11