找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4996|回复: 2
打印 上一主题 下一主题
收起左侧

STM32学习日志--使用dsp库的FFT函数

[复制链接]
跳转到指定楼层
楼主
ID:224401 发表于 2018-5-21 14:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32  dsp  FFT FFT函数单片机源程序如下:
  1. /**
  2.   ******************************************************************************
  3.   * @file FFT_Demo/src/main.c
  4.   * @author  MCD Application Team
  5.   * @version  V2.0.0
  6.   * @brief  Main program body
  7.   ******************************************************************************
  8.   * @copy
  9.   *
  10.   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  11.   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  12.   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  13.   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  14.   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  15.   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  16.   *
  17.   * <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
  18.   */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "stm32f10x.h"
  21. #include <math.h>
  22. #include "stm3210b_lcd.h"
  23. #include "stm32_dsp.h"
  24. #include "table_fft.h"   
  25. //------------------------------------------------------------------------------

  26. #define FreqSample           3200                // 50Hz*64=3200
  27. #define ScalingFactor   20000                // 幅值系数,最大为32767
  28. #define PERCENT_DC                  0.06                // 直流分量对应的百分比,对应直流分量lBUFMAG[0]=1200
  29. #define PI2  6.28318530717959            // 2*3.14
  30. #define NPT 64                                    /* 采样点数,必须为64NPT = No of FFT point*/
  31. //------------------------------------------------------------------------------
  32. extern volatile uint32_t TimingDelay ;
  33. long lBUFIN[NPT];         /* Complex input vector */
  34. long lBUFOUT[NPT];        /* Complex output vector */
  35. long lBUFMAG[NPT + NPT/2];/* Magnitude vector */

  36. /* Private function prototypes -----------------------------------------------*/
  37. void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2);
  38. void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli);
  39. void powerMag(long nfill, char* strPara);
  40. void DSPDemoInit(void);
  41. //------------------------------------------------------------------------------
  42. //------------------------------------------------------------------------------
  43. //------------------------------------------------------------------------------
  44. int main(void)
  45. {
  46.   DSPDemoInit();

  47.   while (1)
  48.   {
  49.         MyDualSweep(FreqSample/NPT,6*FreqSample/NPT);     // 测试fft
  50.   }
  51. }
  52. //-----------------------------------------------------------------------------

  53. /**
  54.   * @brief  Produces a combination of two sinewaves as input signal
  55.   * @param freq1: frequency increment for 1st sweep,频率步进值1
  56.   *   Freq2: frequency increment for 2nd sweep,频率步进值2
  57.   * @retval : None
  58.   */
  59. void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2)
  60. {
  61.   uint32_t freq;
  62.   
  63.   //for (freq=FreqSample/NPT; freq <FreqSample/2; freq+=freqinc1)  // 40--4000,频率步进值为freqinc1
  64.   for (freq=FreqSample/NPT; freq <FreqSample*6/NPT; freq+=freqinc1)  // 40--4000,频率步进值为freqinc1
  65.   {
  66.             MygSin(NPT, FreqSample, freq, 0, ScalingFactor);// 单独的频率,频率步进值2=0;
  67.                                                                                            
  68. #if (NPT==64)
  69.             cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
  70. #elif (NPT==256)
  71.             cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
  72. #else
  73.             cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
  74. #endif

  75.             powerMag(NPT,"2SIDED");
  76.   }

  77. //-----------------------------------------------------------------------------

  78.         for (freq=FreqSample/NPT; freq <FreqSample/2; freq+=freqinc2)
  79.           {
  80.             MygSin(NPT, FreqSample, freq, FreqSample*5/NPT, ScalingFactor);

  81. #if (NPT==64)
  82.             cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
  83. #elif (NPT==256)
  84.             cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
  85. #else
  86.             cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
  87. #endif
  88.    
  89.             powerMag(NPT,"2SIDED");
  90.   }
  91. }
  92. //------------------------------------------------------------------------------
  93. /**
  94.   * @brief  Produces a combination of two sinewaves as input signal
  95.   * @param ill: length of the array holding input signal
  96.   *   Fs: sampling frequency
  97.   *   Freq1: frequency of the 1st sinewave
  98.   *   Freq2: frequency of the 2nd sinewave
  99.   *   Ampli: scaling factor
  100.   * @retval : None
  101.   */
  102. void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli)
  103. {
  104.   uint32_t i;
  105.   float fFs, fFreq1, fFreq2, fAmpli;
  106.   float fZ,fY;

  107.   fFs = (float) Fs;
  108.   fFreq1 = (float) Freq1;
  109.   fFreq2 = (float) Freq2;
  110.   fAmpli = (float) Ampli;

  111.   for (i=0; i < nfill; i++)
  112.   {
  113.     fY =PERCENT_DC/2+sin(PI2 * i * (fFreq1/fFs)) + 0.2*sin(PI2 * i * (fFreq2/fFs));
  114.     fZ = fAmpli * fY;
  115.        
  116. // lBUFIN数组中,每个单元数据高字(高16位)中存储采样数据的实部,低字(低16位)存储采样数据的虚部(总是为0)
  117.     lBUFIN[i]= ((short)fZ) << 16 ;  /* sine_cosine  (cos=0x0) */
  118.                                                                         // 高16bit为实部,低16bit为虚部,没有的话,就用0代替
  119.   }
  120. }
  121. //------------------------------------------------------------------------------
  122. /**
  123.   * @brief  Removes the aliased part of the spectrum (not tested)
  124.   * @param ill: length of the array holding power mag
  125.   * @retval : None
  126.   */
  127. void onesided(long nfill)
  128. {
  129.   uint32_t i;
  130.   
  131.   lBUFMAG[0] = lBUFMAG[0];
  132.   lBUFMAG[nfill/2] = lBUFMAG[nfill/2];
  133.   for (i=1; i < nfill/2; i++)
  134.   {
  135.     lBUFMAG[i] = lBUFMAG[i] + lBUFMAG[nfill-i];
  136.     lBUFMAG[nfill-i] = 0x0;
  137.   }
  138. }
  139. //------------------------------------------------------------------------------
  140. /**
  141.   * @brief  Compute power magnitude of the FFT transform  进行FFT变换,并计算各次谐波幅值
  142.   * @param ill: length of the array holding power mag
  143.   *   : strPara: if set to "1SIDED", removes aliases part of spectrum (not tested)
  144.   * @retval : None
  145.   */
  146. void powerMag(long nfill, char* strPara)
  147. {
  148.   static int32_t lX,lY;
  149.   uint32_t i;

  150.   for (i=0; i < nfill/2; i++)
  151.   {
  152.     lX= (lBUFOUT[i]<<16)>>16; /* 取低16bit,sine_cosine --> cos */
  153.     lY= (lBUFOUT[i] >> 16);   /* 取高16bit,sine_cosine --> sin */   
  154.     {
  155.       float X=  NPT*((float)lX)/32768;
  156.       float Y = NPT*((float)lY)/32768;
  157.       float Mag = sqrt(X*X+ Y*Y)/nfill;
  158.       lBUFMAG[i] = (uint32_t)(Mag*65536);
  159.     }   
  160.   }
  161. }
  162. //------------------------------------------------------------------------------

  163. /**
  164.   * @brief  Inserts a delay time.
  165.   * @param ount: specifies the delay time length (time base 10 ms).
  166.   * @retval : None
  167.   */
  168. void Delay(uint32_t nCount)
  169. {
  170.   /* Configure the systick */
  171.   __enable_irq();
  172.          
  173.      /* Setup SysTick Timer for 10 msec interrupts */
  174.   if (SysTick_Config(SystemFrequency /100)) /* SystemFrequency is defined in
  175.    搒ystem_stm32f10x.h?and equal to HCLK frequency */
  176.    {
  177.     /* Capture error */
  178.      while (1);
  179.     }     
  180.   /* Enable the SysTick Counter */
  181.   TimingDelay = nCount;
  182.    while (TimingDelay )  {}            
  183.    TimingDelay=0;
  184.    __disable_irq();

  185. }

  186. /**
  187.   * @brief  Initializes the DSP lib demo (clock, peripherals and LCD).
  188.   * @param  None
  189.   * @retval : None
  190.   */
  191. void DSPDemoInit(void)
  192. {
  193.   GPIO_InitTypeDef GPIO_InitStructure;
  194.   ErrorStatus HSEStartUpStatus = ERROR;

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

  198.   /* Enable HSE */
  199.   RCC_HSEConfig(RCC_HSE_ON);

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

  202.   if(HSEStartUpStatus == SUCCESS)
  203.   {
  204.     /* Enable Prefetch Buffer */
  205.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  206.     /* Flash 2 wait state */
  207.     FLASH_SetLatency(FLASH_Latency_2);

  208.     /* HCLK = SYSCLK */
  209.     RCC_HCLKConfig(RCC_SYSCLK_Div1);

  210.     /* PCLK2 = HCLK */
  211.     RCC_PCLK2Config(RCC_HCLK_Div1);

  212.     /* PCLK1 = HCLK/2 */
  213.     RCC_PCLK1Config(RCC_HCLK_Div2);

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

  216.     /* Enable PLL */
  217.     RCC_PLLCmd(ENABLE);

  218.     /* Wait till PLL is ready */
  219.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  220.     {
  221.     }

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

  224.     /* Wait till PLL is used as system clock source */
  225.     while(RCC_GetSYSCLKSource() != 0x08)
  226.     {
  227.     }
  228.   }

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

  232.   /* TIM1 Periph clock enable */
  233.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  234.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);


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

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

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



  246.   /*------------------- Drivers Initialization -------------------------------*/
  247.   /* Initialize the LCD */
  248.   STM3210B_LCD_Init();

  249.   /* Clear the LCD */
  250.   LCD_Clear(White);

  251. ……………………

  252. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
STM32学习日志(23)----使用dsp库的FFT函数.zip (446.86 KB, 下载次数: 73)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:730683 发表于 2020-4-24 18:21 | 只看该作者
您好,我使用STM32F103的官方DSP库,对一个2HZ的标准正弦信号进行FFT变换,出来的幅值信号波动大,有30-50个数,您那边有这种问题吗???想问问如何解决的
回复

使用道具 举报

板凳
ID:730683 发表于 2020-4-24 18:23 | 只看该作者
您好,我使用STM32F103的官方DSP库对一个2HZ的标准正弦信号进行FFT变换,但是变换后的幅值波动大,在30-50个数之间,不知道您有没有遇到这种情况,怎么解决的???
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表