找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2254|回复: 3
收起左侧

stm32中用dsp做fft运算

[复制链接]
ID:373362 发表于 2018-7-17 16:02 | 显示全部楼层 |阅读模式
stm32中用dsp做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. /* Includes ------------------------------------------------------------------*/
  8. #include "stm32f10x.h"
  9. #include <math.h>
  10. #include "stm3210b_lcd.h"
  11. #include "stm32_dsp.h"
  12. #include "table_fft.h"


  13. /** @addtogroup FFT_Demo
  14.   * @{
  15.   */


  16. /* Private typedef -----------------------------------------------------------*/
  17. /* Private define ------------------------------------------------------------*/
  18. #define PI2  6.28318530717959

  19. #define NPT 64            /* NPT = No of FFT point*/
  20. #define DISPLAY_RIGHT 310 /* 224 for centered, 319 for right-aligned */
  21. #define DISPLAY_LEFT 150  /* 224 for centered, 319 for right-aligned */

  22. /* Private macro -------------------------------------------------------------*/
  23. /* Private variables ---------------------------------------------------------*/
  24. extern uint16_t TableFFT[];
  25. extern volatile uint32_t TimingDelay ;
  26. long lBUFIN[NPT];         /* Complex input vector */
  27. long lBUFOUT[NPT];        /* Complex output vector */
  28. long lBUFMAG[NPT + NPT/2];/* Magnitude vector */

  29. /* Private function prototypes -----------------------------------------------*/
  30. void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2);
  31. void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli);
  32. void powerMag(long nfill, char* strPara);
  33. void In_displayWaveform(uint32_t DisplayPos);
  34. void Out_displayWaveform(uint32_t DisplayPos);
  35. void displayPowerMag(uint32_t DisplayPos, uint32_t scale);
  36. void DisplayTitle(void);
  37. void DSPDemoInit(void);

  38. /* Private functions ---------------------------------------------------------*/


  39. /**
  40.   * @brief  Main program.
  41.   * @param  None
  42.   * @retval : None
  43.   */
  44. int main(void)
  45. {

  46.   DSPDemoInit();
  47.   DisplayTitle();

  48.   while (1)
  49.   {
  50.     MyDualSweep(30,30);
  51.   }
  52. }



  53. /**
  54.   * @brief  Produces a combination of two sinewaves as input signal
  55.   * @param eq1: frequency increment for 1st sweep
  56.   *   Freq2: frequency increment for 2nd sweep
  57.   * @retval : None
  58.   */
  59. void MyDualSweep(uint32_t freqinc1,uint32_t freqinc2)
  60. {
  61.   uint32_t freq;

  62.   for (freq=40; freq <4000; freq+=freqinc1)
  63.   {
  64.     MygSin(NPT, 8000, freq, 0, 32767);
  65.     GPIOC->BSRR = GPIO_Pin_7;
  66.    
  67.     cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);

  68.     GPIOC->BRR = GPIO_Pin_7;
  69.     powerMag(NPT,"2SIDED");
  70.     In_displayWaveform(DISPLAY_RIGHT);

  71.     displayPowerMag(DISPLAY_RIGHT, 9);

  72.     while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0x00);
  73.   }

  74.   for (freq=40; freq <4000; freq+=freqinc2)
  75.   {
  76.     MygSin(NPT, 8000, freq, 160, 32767/2);
  77.     GPIOC->BSRR = GPIO_Pin_7;
  78.    
  79.     cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
  80.    
  81.     GPIOC->BRR = GPIO_Pin_7;
  82.     powerMag(NPT,"2SIDED");
  83.     In_displayWaveform(DISPLAY_LEFT);
  84.     displayPowerMag(DISPLAY_LEFT, 8);

  85.     while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0x00);
  86.   }

  87. }



  88. /**
  89.   * @brief  Produces a combination of two sinewaves as input signal
  90.   * @param ill: length of the array holding input signal
  91.   *   Fs: sampling frequency
  92.   *   Freq1: frequency of the 1st sinewave
  93.   *   Freq2: frequency of the 2nd sinewave
  94.   *   Ampli: scaling factor
  95.   * @retval : None
  96.   */
  97. void MygSin(long nfill, long Fs, long Freq1, long Freq2, long Ampli)
  98. {

  99.   uint32_t i;
  100.   float fFs, fFreq1, fFreq2, fAmpli;
  101.   float fZ,fY;

  102.   fFs = (float) Fs;
  103.   fFreq1 = (float) Freq1;
  104.   fFreq2 = (float) Freq2;
  105.   fAmpli = (float) Ampli;

  106.   for (i=0; i < nfill; i++)
  107.   {
  108.     fY = sin(PI2 * i * (fFreq1/fFs)) + sin(PI2 * i * (fFreq2/fFs));
  109.     fZ = fAmpli * fY;
  110.     lBUFIN[i]= ((short)fZ) << 16 ;  /* sine_cosine  (cos=0x0) */
  111.   }
  112. }




  113. /**
  114.   * @brief  Removes the aliased part of the spectrum (not tested)
  115.   * @param ill: length of the array holding power mag
  116.   * @retval : None
  117.   */
  118. void onesided(long nfill)
  119. {
  120.   uint32_t i;
  121.   
  122.   lBUFMAG[0] = lBUFMAG[0];
  123.   lBUFMAG[nfill/2] = lBUFMAG[nfill/2];
  124.   for (i=1; i < nfill/2; i++)
  125.   {
  126.     lBUFMAG[i] = lBUFMAG[i] + lBUFMAG[nfill-i];
  127.     lBUFMAG[nfill-i] = 0x0;
  128.   }
  129. }




  130. /**
  131.   * @brief  Compute power magnitude of the FFT transform
  132.   * @param ill: length of the array holding power mag
  133.   *   : strPara: if set to "1SIDED", removes aliases part of spectrum (not tested)
  134.   * @retval : None
  135.   */
  136. void powerMag(long nfill, char* strPara)
  137. {
  138.   int32_t lX,lY;
  139.   uint32_t i;

  140.   for (i=0; i < nfill; i++)
  141.   {
  142.     lX= (lBUFOUT[i]<<16)>>16; /* sine_cosine --> cos */
  143.     lY= (lBUFOUT[i] >> 16);   /* sine_cosine --> sin */   
  144.     {
  145.       float X=  64*((float)lX)/32768;
  146.       float Y = 64*((float)lY)/32768;
  147.       float Mag = sqrt(X*X+ Y*Y)/nfill;
  148.       lBUFMAG[i] = (uint32_t)(Mag*65536);
  149.     }   
  150.   }
  151.   if (strPara == "1SIDED") onesided(nfill);
  152. }



  153. /**
  154.   * @brief  Displays the input array before filtering
  155.   * @param splayPos indicates the beginning Y address on LCD
  156.   * @retval : None
  157.   */
  158. void In_displayWaveform(uint32_t DisplayPos)
  159. {
  160.   uint8_t aScale;
  161.   uint16_t cln;

  162.   for (cln=0; cln < 64; cln++)       /* original upper limit was 60 */
  163.   {
  164.     /* Clear previous line */
  165.     LCD_SetTextColor(White);
  166.     LCD_DrawLine(48,DisplayPos-(2*cln),72,Vertical);
  167.     /* and go back to normal display mode */
  168.     LCD_SetTextColor(Black);
  169.     aScale = lBUFIN[cln]>>(10 + 16);  /* SINE IS LEFT ALIGNED */
  170.     if (aScale > 127)         /* Negative values */
  171.     {
  172.       aScale = (0xFF-aScale) + 1; /* Calc absolute value */
  173.       LCD_DrawLine(84-aScale,DisplayPos-(2*cln),aScale,Vertical);
  174.     }
  175.     else  /* Display positive values */
  176.     {
  177.       LCD_DrawLine(84,DisplayPos-(2*cln),aScale,Vertical);
  178.     }
  179.   }/* for */
  180. }




  181. /**
  182.   * @brief  Displays the output array after filtering
  183.   * @param splayPos indicates the beginning Y address on LCD
  184.   * @retval : None
  185.   */
  186. void Out_displayWaveform(uint32_t DisplayPos)
  187. {
  188.   uint8_t aScale;
  189.   uint16_t cln;

  190.   for (cln=0; cln < 64; cln++)    /* original upper limit was 60 */
  191.   {
  192.     aScale = lBUFOUT[cln]>>(10 + 16);  /* SINE IS LEFT ALIGNED */
  193.     if (aScale > 127)         /* Negative values */
  194.     {
  195.       aScale = (0xFF-aScale) + 1; /* Calc absolute value */
  196.       LCD_DrawLine(156-aScale,DisplayPos-(2*cln),aScale,Vertical);
  197.     }
  198.     else  /* Display positive values */
  199.     {
  200.       LCD_DrawLine(156,DisplayPos-(2*cln),aScale,Vertical);
  201.     }
  202.   }/* for */
  203. }



  204. /**
  205.   * @brief  Displays the power magnitude array following a FFT
  206.   * @param splayPos indicates the beginning Y address on LCD
  207.   *   : scale allows to normalize the result for optimal display
  208.   * @retval : None
  209.   */
  210. void displayPowerMag(uint32_t DisplayPos, uint32_t scale)
  211. {
  212.   uint16_t aScale;
  213.   uint16_t cln;

  214.   for (cln=0; cln < 64; cln++)
  215.   {
  216.     /* Clear previous line */
  217.     LCD_SetTextColor(White);
  218.     LCD_DrawLine(120,DisplayPos-(2*cln),72,Vertical);
  219.     /* and go back to normal display mode */
  220.     LCD_SetTextColor(Red);

  221.     aScale =lBUFMAG[cln]>>scale ; /* spectrum is always divided by two */
  222.     /* Power Mag contains only positive values */
  223.     LCD_DrawLine(192-aScale,DisplayPos-(2*cln),aScale,Vertical);
  224.   }/* for */
  225. }



  226. /**
  227.   * @brief  Displays the initial menu and then background frame
  228.   * @param  None
  229.   * @retval : None
  230.   */
  231. void DisplayTitle(void)
  232. {
  233.   uint8_t *ptr = "   STM32 DSP Demo   ";

  234.   LCD_DisplayStringLine(Line0, ptr);

  235.   ptr = " 64-pts Radix-4 FFT ";
  236.   LCD_DisplayStringLine(Line1, ptr);

  237.   ptr = "Press Key to freeze ";
  238.   LCD_DisplayStringLine(Line9, ptr);

  239.   {
  240.     unsigned long long Delay = 0x600000;
  241.     while (Delay--);
  242.     while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0x00);
  243.   }

  244.   ptr = "   Sine   Dual sine ";
  245.   LCD_DisplayStringLine(Line9, ptr);
  246. }






  247. /**
  248.   * @brief  Inserts a delay time.
  249.   * @param ount: specifies the delay time length (time base 10 ms).
  250.   * @retval : None
  251.   */
  252. void Delay(uint32_t nCount)
  253. {
  254.   /* Configure the systick */
  255.   __enable_irq();
  256.          
  257.      /* Setup SysTick Timer for 10 msec interrupts */
  258.   if (SysTick_Config(SystemFrequency /100)) /* SystemFrequency is defined in
  259.    搒ystem_stm32f10x.h?and equal to HCLK frequency */
  260.    {
  261.     /* Capture error */
  262.      while (1);
  263.     }     
  264.   /* Enable the SysTick Counter */
  265.   TimingDelay = nCount;
  266.    while (TimingDelay )  {}            
  267.    TimingDelay=0;
  268.    __disable_irq();

  269. }




  270. /**
  271.   * @brief  Initializes the DSP lib demo (clock, peripherals and LCD).
  272.   * @param  None
  273.   * @retval : None
  274.   */
  275. void DSPDemoInit(void)
  276. {
  277.   GPIO_InitTypeDef GPIO_InitStructure;
  278.   ErrorStatus HSEStartUpStatus = ERROR;

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

  282.   /* Enable HSE */
  283.   RCC_HSEConfig(RCC_HSE_ON);

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

  286.   if(HSEStartUpStatus == SUCCESS)
  287.   {
  288.     /* Enable Prefetch Buffer */
  289.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  290.     /* Flash 2 wait state */
  291.     FLASH_SetLatency(FLASH_Latency_2);

  292.     /* HCLK = SYSCLK */
  293.     RCC_HCLKConfig(RCC_SYSCLK_Div1);

  294.     /* PCLK2 = HCLK */
  295.     RCC_PCLK2Config(RCC_HCLK_Div1);

  296.     /* PCLK1 = HCLK/2 */
  297.     RCC_PCLK1Config(RCC_HCLK_Div2);

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

  300.     /* Enable PLL */
  301.     RCC_PLLCmd(ENABLE);

  302.     /* Wait till PLL is ready */
  303.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  304.     {
  305.     }

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

  308.     /* Wait till PLL is used as system clock source */
  309.     while(RCC_GetSYSCLKSource() != 0x08)
  310.     {
  311.     }
  312.   }

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

  316.   /* TIM1 Periph clock enable */
  317.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  318.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);


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

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

  323.   /*------------------- Resources Initialization -----------------------------*/
  324.   /* GPIO Configuration */
  325. ……………………

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

所有资料51hei提供下载:
STM32F10x_DSP_fft_V2.0.0.rar (1.48 MB, 下载次数: 37)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:376076 发表于 2018-7-20 18:05 | 显示全部楼层
这个是用外部输入来进行fft的吗
回复

使用道具 举报

ID:95821 发表于 2018-8-13 09:55 | 显示全部楼层
學習了
回复

使用道具 举报

ID:374525 发表于 2018-8-13 10:24 | 显示全部楼层
学习了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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