標(biāo)題:
STM32學(xué)習(xí)日志--使用dsp庫的FFT函數(shù)
[打印本頁]
作者:
a353114532
時(shí)間:
2018-5-21 14:02
標(biāo)題:
STM32學(xué)習(xí)日志--使用dsp庫的FFT函數(shù)
STM32 dsp FFT FFT函數(shù)單片機(jī)源程序如下:
/**
******************************************************************************
* @file FFT_Demo/src/main.c
* @author MCD Application Team
* @version V2.0.0
* @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 3200 // 50Hz*64=3200
#define ScalingFactor 20000 // 幅值系數(shù),最大為32767
#define PERCENT_DC 0.06 // 直流分量對應(yīng)的百分比,對應(yīng)直流分量lBUFMAG[0]=1200
#define PI2 6.28318530717959 // 2*3.14
#define NPT 64 /* 采樣點(diǎn)數(shù),必須為64NPT = No of FFT point*/
//------------------------------------------------------------------------------
extern volatile uint32_t TimingDelay ;
long lBUFIN[NPT]; /* Complex input vector */
long lBUFOUT[NPT]; /* Complex output vector */
long lBUFMAG[NPT + NPT/2];/* Magnitude 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 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,頻率步進(jìn)值1
* Freq2: frequency increment for 2nd sweep,頻率步進(jìn)值2
* @retval : None
*/
void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2)
{
uint32_t freq;
//for (freq=FreqSample/NPT; freq <FreqSample/2; freq+=freqinc1) // 40--4000,頻率步進(jìn)值為freqinc1
for (freq=FreqSample/NPT; freq <FreqSample*6/NPT; freq+=freqinc1) // 40--4000,頻率步進(jìn)值為freqinc1
{
MygSin(NPT, FreqSample, freq, 0, ScalingFactor);// 單獨(dú)的頻率,頻率步進(jìn)值2=0;
#if (NPT==64)
cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
#elif (NPT==256)
cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
#else
cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
#endif
powerMag(NPT,"2SIDED");
}
//-----------------------------------------------------------------------------
for (freq=FreqSample/NPT; freq <FreqSample/2; freq+=freqinc2)
{
MygSin(NPT, FreqSample, freq, FreqSample*5/NPT, ScalingFactor);
#if (NPT==64)
cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
#elif (NPT==256)
cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
#else
cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
#endif
powerMag(NPT,"2SIDED");
}
}
//------------------------------------------------------------------------------
/**
* @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+sin(PI2 * i * (fFreq1/fFs)) + 0.2*sin(PI2 * i * (fFreq2/fFs));
fZ = fAmpli * fY;
// lBUFIN數(shù)組中,每個(gè)單元數(shù)據(jù)高字(高16位)中存儲(chǔ)采樣數(shù)據(jù)的實(shí)部,低字(低16位)存儲(chǔ)采樣數(shù)據(jù)的虛部(總是為0)
lBUFIN[i]= ((short)fZ) << 16 ; /* sine_cosine (cos=0x0) */
// 高16bit為實(shí)部,低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[i] = lBUFMAG[i] + lBUFMAG[nfill-i];
lBUFMAG[nfill-i] = 0x0;
}
}
//------------------------------------------------------------------------------
/**
* @brief Compute power magnitude of the FFT transform 進(jìn)行FFT變換,并計(jì)算各次諧波幅值
* @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)
{
static int32_t lX,lY;
uint32_t i;
for (i=0; i < nfill/2; i++)
{
lX= (lBUFOUT[i]<<16)>>16; /* 取低16bit,sine_cosine --> cos */
lY= (lBUFOUT[i] >> 16); /* 取高16bit,sine_cosine --> sin */
{
float X= NPT*((float)lX)/32768;
float Y = NPT*((float)lY)/32768;
float Mag = sqrt(X*X+ Y*Y)/nfill;
lBUFMAG[i] = (uint32_t)(Mag*65536);
}
}
}
//------------------------------------------------------------------------------
/**
* @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);
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
STM32學(xué)習(xí)日志(23)----使用dsp庫的FFT函數(shù).zip
(446.86 KB, 下載次數(shù): 73)
2018-5-21 14:01 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
DONGpig
時(shí)間:
2020-4-24 18:21
您好,我使用STM32F103的官方DSP庫,對一個(gè)2HZ的標(biāo)準(zhǔn)正弦信號(hào)進(jìn)行FFT變換,出來的幅值信號(hào)波動(dòng)大,有30-50個(gè)數(shù),您那邊有這種問題嗎???想問問如何解決的
作者:
DONGpig
時(shí)間:
2020-4-24 18:23
您好,我使用STM32F103的官方DSP庫對一個(gè)2HZ的標(biāo)準(zhǔn)正弦信號(hào)進(jìn)行FFT變換,但是變換后的幅值波動(dòng)大,在30-50個(gè)數(shù)之間,不知道您有沒有遇到這種情況,怎么解決的???
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1