[ Prev ] [ Index ] [ Next ]

Fast Fourier Transform

Created Sunday 20 August 2023


  1. Open STM32CubeIDE
  2. Select "File" → "New" → "STM32 Project"
  3. In "Commercial Part Number" field type STM32F103C8T6
  4. From the MCUs/MPUs List select STM32F103C8T6 (shipped in plastic trays) or STM32F103C8T6TR (shipped in tapes on reels)
  5. Click "Next >" button
  6. Enter Project Name, e.g. "How to use FFT on STM32F103C8T6" → Click "Finish" button
  7. In "Pinout & Configuration" tab, open "System Core" → "RCC"
  8. Set "High Speed Clock (HSE)" to "Crystal/Ceramic Resonator"
  9. Open "Clock Configuration" tab
  10. Check that "Input frequency" is equal to resonator on STM32F103C8T6 board (usually 8MHz)
  11. Set "PLL Source Mux" to HSE
  12. Set "System Clock Mux" to PLLCLK
  13. Set PLLMul to "X 9"
  14. Set APB1 Prescaler to "/ 2"
  15. Now, microcontroller clocks are set for maximum performance (72 MHz max)
  16. From menu select "Project" → "Generate Code"
  17. Select "C/C++" perspective (small button in upper-right corner), or through menu "Window" → "Perspective" → "Other..." → "C/C++"
  18. Double click on "main.c" under "Project Explorer" tab in "Core" → "Src"
  19. Find directory of STM32F1 firmware package, it is usually placed in C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_Vsome.version.number\
  20. Under this directory, we need to find two paths.
  21. First path ,containing three files arm_common_tables.h, arm_const_structs.h and arm_math.h, e.g. C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5\Drivers\CMSIS\DSP\Include\
  22. Second path, containing libarm_cortexM3l_math.a, e.g. C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5\Drivers\CMSIS\Lib\GCC\
  23. Open "Project" → "Properties" → "C++ general" → "Paths and Symbols"
  24. In "Includes" tab, press "Add..." and paste first path, e.g. C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5\Drivers\CMSIS\DSP\Include (without trailing slash!)
  25. In "Symbols" tab, press "Add..." and enter "Name:" ARM_MATH_CM3 (leave "Value:" field empty)
  26. In "Libraries" tab, press "Add..." and enter arm_cortexM3l_math, note that this name is made by removing "lib" and ".a" from actual filename: libarm_cortexM3l_math.a
  27. In "Library Paths" tab, press "Add..." and paste second path, e.g. C:\Users\Administrator\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.5\Drivers\CMSIS\Lib\GCC (without trailing slash!)
  28. Open main.c file
  29. Add #include "arm_const_structs.h"
  30. Add #define FFT_SIZE 64
  31. Add q15_t inputSignal[FFT_SIZE];
  32. Add q15_t complexSpectrum[FFT_SIZE*2];
  33. Add q15_t realSpectrum[FFT_SIZE];
  34. Generate input signal, e.g. for (int i=0; i<FFT_SIZE; i++) inputSignal[i]=round(32767*sin(2.0*M_PI*freqBin*i/FFT_SIZE));
  35. Change freqBin value from 0 to 31 to generate test frequency peak at certain FFT frequency bin
  36. Fill in complex array for FFT input for (int i=0; i<FFT_SIZE; i++){ complexSpectrum[i*2+0]=inputSignal[i]; complexSpectrum[i*2+1]=0;}
  37. Note that CMSIS FFT function uses the same array for input signal and output spectrum. This means that bofre FFT complexSpectrum array contains input signal (not a scomplex pectrum!)
  38. Perform FFT using arm_cfft_q15(&arm_cfft_sR_q15_len64, &complexSpectrum[0], 0,1); After FFT function is called, complexSpectrum array contains output spectrum
  39. Calculate amplitude from FFT complex spectrum using arm_cmplx_mag_q15(&complexSpectrum[0],&realSpectrum[0],FFT_SIZE); There is also squared version of this function
  40. Open STM32CubeMonitor, find three stripes / hamburger in up-right corner and press it to open menu → Import
  41. In "Import nodes" windows select "Local" → STM32CubeMonitor_BasicFlow.json → press Import button
  42. Delete "show notification", "myChart" and "Clear Graphs" nodes
  43. Three stripes / hamurger → Import → Clipboard tab → "select a file to import" button → find and select cubearrays10.json → Import button (nodes10.zip)
  44. Connect variables node upper output to "CubeArrays v1.0" function node input
  45. Double-click on "myVariables", and add ELF file for STM32CubeIDE FFT project
  46. Use "Expand Variable List" checkbox and filter field to find all elements of inputSignal and realSpectrum arrays, and add them using "Select All" button.
  47. Double-click "CubeArrays v1.0" function node, select "On Message" tab, scroll down to const arrayNames=["arrayName1","arrayName2",...]
  48. Replace "arrayName1", "arrayName2" with inputSignal and realSpectrum
  49. Open "Setup" tab and set "Outputs" to 2
  50. Double-click Chart #1, set "OR points" to 64, set "Y-axis" min to -32767 and max to 32767
  51. Double-click Chart #2, set "OR points" to 64, set "Y-axis" min to 0 and max to 16000
  52. Delete Chart #3
  53. Press "Deploy" button
  54. Press "Dashboard" button, in opened window press "Start monitoring"