FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

时间:2024-04-04 09:10:57

STM32F1 DSP官方库的安装

1.下载完毕后进行安装,这里我甩出一个下载链接。

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

2.接收协议。

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

3.安装路径,我这里喜欢选择D盘。

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

4.安装完毕后,有一些需要的库和参考Demo文件。

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

5. STM32F1移植ST 的DSP官方库

在STMF1上移植ST 的FFT官方库运行一下看一下效果,然而STM32F103毕竟不是STM32F4系列的处理器,对于一般的FFT运算程序还是比较缓慢的。官方提供了针对FFT的官方库,下载移植体验一下,下载完毕后,主要有四个文件:

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

cr4_fft_256_stm32.s: Cortex-M3的256点基4复FFT优化。

cr4_fft_1024_stm32.s:Cortex-M3的1024点基4复FFT优化。

stm32_dsp.h:         头文件包含DSP函数的原型。

table_fft.h:           包含FFT计算所需的系数

在正点原子的基础工程上进行移植DSP库,一共就4个文件,不难办吧。移植后的效果如下:

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

添加头文件路径如下:

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

在主函数main.c中直接调用stm32_dsp.h 会报错,提示不能打开stm32f1xx_hal.h,看来dsp库使用的是HAL库,这里我们把它改为标准库就不会报错啦!

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

注释 #include "stm32f1xx_hal.h" 引用#include "stm32f10x.h",再次编译就没有错误啦!

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

7. ST 的DSP官方库函数介绍和简单测试

1.提供STM32 单片机调用的FFT变换的64点、256点、2048点的函数如下:

/* Radix-4 complex FFT for STM32, in assembly  */

/* 64 points*/

void cr4_fft_64_stm32(void *pssOUT, void *pssIN, u16 Nbin);

/* 256 points */

void cr4_fft_256_stm32(void *pssOUT, void *pssIN, u16 Nbin);

/* 1024 points */

void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, u16 Nbin);

pssIN:是输入采样的样本。

pssOUT:调用官方函数后,输出的傅里叶序列。

Nbin:样本的数量(采了多少个点)。

为什么是64、256、1024这个3个值?因为官方使用的是基4蝶形算法,简单理解要使用官方fft库函数,必须遵循采样点数Nbin,是4的n次方。

2.提供了16位的IIR滤波器和FIR滤波器函数,具体如下:

/* FIR 16-bit filter in assembly */

void fir_16by16_stm32(void *y, void *x, COEFS *c, u32 N);

/* IIR filter in assembly */

void iirarma_stm32(void *y, void *x, u16 *h2, u16 *h1, u32 ny );

/* IIR filter in C */

void iir_biquad_stm32(u16 *y, u16 *x, s16 *IIRCoeff, u16 ny);

3.此外还提供了一些PID相关的,这里暂且不深究

/* PID controller in C, error computed outside the function */

u16 DoPID(u16 Error, u16 *Coeff);

/* Full PID in C, error computed inside the function */

u16 DoFullPID(u16 In, u16 Ref, u16 *Coeff);

/* PID controller in assembly, error computed outside the function */

u16 PID_stm32(u16 Error, u16 *Coeff);

4.傅里叶变换后,输出了个啥,咋用?我们需要有个基础知识,傅里叶变换的目的:求取幅频特性/相频特性,fft变换后,输出的是一个傅里叶序列(怎么用?)。傅里叶序列本身,不是我们能够肉眼分析的东西,我们还需要对傅里叶序列进行计算,求取幅频特性/相频特性序列。通过串口打印输出的方式先测试一下64点、256点、2048点的FFT函数。

3.1添加串口驱动,对于正点原子的工程,在system文件夹中已经加入串口1的驱动,直接就可以使用串口1。

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

3.2对串口进行初始化,保证串口可用。

int main(void)

 {     

         delay_init();          //延时函数初始化  

         LED_Init();                        //初始化与LED连接的硬件接口

         uart_init(9600);  //初始化串口 9600波特率

         printf("这是一个FFT 测试实验\r\n");

         while(1)

         {

                   LED0=0;

                   LED1=1;

                   delay_ms(300);        //延时300ms

                   LED0=1;

                   LED1=0;

                   delay_ms(300);        //延时300ms

         }

 }

FFT—快速傅里叶变换算法——STM32F1+DSP库实现(2)

3.3添加测试数据集,验证256点的FFT函数,填充输入数组

//填入数组                                                                                                                                                 

void InitBufInArray()

{

 unsigned short i;

 float fx;

 for(i=0; i<N; i++)   

         {

        fx = 1500 * sin(PI2 * i * 350.0 / Fs) +

             2700 * sin(PI2 * i * 8400.0 / Fs) +

             4000 * sin(PI2 * i * 18725.0 / Fs);

                       FFT_256PointIn[i] = ((signed short)fx) << 16;

    }       

}       

3.4计算各次谐波幅值,先将lBufOutArray分解成实部(X)和虚部(Y),然后计算幅值(sqrt(X*X+Y*Y)。

void GetPowerMag()

{

    signed short lX,lY;

    float X,Y,Mag;

    unsigned short i;

    for(i=0; i<N/2; i++)

    {

        lX  = (FFT_256PointOut[i] << 16) >> 16;

        lY  = (FFT_256PointOut[i] >> 16);

        X = N * ((float)lX) / 32768;

        Y = N * ((float)lY) / 32768;

        Mag = sqrt(X * X + Y * Y) / N;

        if(i == 0)

            lBufMagArray[i] = (unsigned long)(Mag * 32768);

        else

            lBufMagArray[i] = (unsigned long)(Mag * 65536);

                                    

                                     printf("%d      ",i);

                                     printf("%d      ",F*i);

                                     printf("%d      ",lBufMagArray[i]);

                                     printf("%d      ",lX);

                                     printf("%d      \r\n",lY);                       

    }

}

3.5主函数测试,先填充输入数组再做fft256点运算,最后求出赋值,打印测试。

int main(void)

 {     

         delay_init();          //延时函数初始化  

         LED_Init();                        //初始化与LED连接的硬件接口

         uart_init(9600);  //初始化串口 9600波特率

         printf("这是一个FFT 测试实验\r\n");  

    InitBufInArray();

         cr4_fft_256_stm32(FFT_256PointOut, FFT_256PointIn,N);   

         printf("点数   频率  幅值   实部  虚部\n");

         GetPowerMag();

                  

                     while(1)

                    {

                                     LED0=0;

                                     LED1=1;

                                     delay_ms(300);        //延时300ms

                                     LED0=1;

                                     LED1=0;

                                     delay_ms(300);        //延时300ms

                            }

 }

3.6串口测试界面如下:

点数   频率   幅值    实部   虚部

0      0        4       0       -4     

1      175      14        -6      -4     

2      350      1500      -380      647     

3      525      11      -5      -3     

4      700      10      -4      -3     

5      875      8      -4      -2     

6      1050      8      -4      -1     

7      1225      6      -3      0     

8      1400      8      -3      -3     

9      1575      8      -4      -1     

10      1750      8      -4      -1     

11      1925      8      -4      0     

12      2100      5      -2      -2     

13      2275      6      -3      -1     

14      2450      8      -3      -3     

15      2625      7      -3      -2     

16      2800      5      -2      -2     

17      2975      6      -3      -1     

18      3150      6      -3      0     

19      3325      6      -3      0     

20      3500      6      -3      -1     

21      3675      6      -3      0     

22      3850      6      -3      0     

23      4025      2      -1      0     

24      4200      6      -3      -1     

25      4375      6      -3      0     

26      4550      4      -2      0     

27      4725      4      -2      0     

28      4900      2      -1      -1     

29      5075      4      -2      0     

30      5250      2      -1      0      

31      5425      4      -2      0     

32      5600      2      -1      0     

33      5775      6      -3      -1     

34      5950      6      -3      0     

35      6125      6      -3      -1     

36      6300      4      -2      -1     

37      6475      6      -3      0     

38      6650      4      -2      0     

39      6825      6      -3      0     

40      7000      5      -2      -2     

41      7175      6      -3      0     

42      7350      2      0      -1     

43      7525      6      -3      0     

44      7700      2      -1      -1     

45      7875      4      -2      0     

46      8050      6      -3      -1     

47      8225      2      -1      0     

48      8400      2704      -676      -1171      

49      8575      4      -2      0     

50      8750      2      -1      0     

51      8925      4      -2      -1     

52      9100      2      -1      -1     

53      9275      4      -2      0     

54      9450      2      -1      0     

55      9625      2      -1      -1     

56      9800      2      -1      -1     

57      9975      4      -2      0     

58      10150      2      0      -1     

59      10325      4      -2      0     

60      10500      2      -1      -1     

61      10675      2      -1      -1     

62      10850      4      -2      -1     

63      11025      2      -1      -1     

64      11200      0      0      0     

65      11375      2      -1      0     

66      11550      4      -2      0     

67      11725      2      0      -1     

68      11900      2      -1      -1     

69      12075      2      -1      1     

70      12250      2      -1      1     

71      12425      4      -2      1     

72      12600      4      -2      -1     

73      12775      2      -1      1     

74      12950      2      -1      -1     

75      13125      4      -2      1     

76      13300      2      -1      -1     

77      13475      4      -2      1     

78      13650      2      -1      -1     

79      13825      4      -2      0     

80      14000      2      -1      0     

81      14175      4      -2      0     

82      14350      4      -2      1     

83      14525      4      -2      1     

84      14700      2      -1      0     

85      14875      2      -1      1     

86      15050      4      -2      0     

87      15225      4      -2      0     

88      15400      2      -1      -1     

89      15575      4      -2      1     

90      15750      2      -1      1     

91      15925      2      -1      1      

92      16100      0      0      0     

93      16275      4      -2      1     

94      16450      2      -1      1     

95      16625      4      -2      1     

96      16800      2      -1      0     

97      16975      4      -2      0     

98      17150      4      -2      1     

99      17325      4      -2      0     

100      17500      2      -1      0     

101      17675      4      -2      0     

102      17850      2      -1      0     

103      18025      4      -2      0     

104      18200      4      -2      -1     

105      18375      4      -2      1     

106      18550      2      -1      -1     

107      18725      3996      1998      1     

108      18900      2      -1      0     

109      19075      2      -1      1     

110      19250      4      -2      0     

111      19425      4      -2      1     

112      19600      2      -1      0     

113      19775      2      -1      1     

114      19950      2      -1      1     

115      20125      4      -2      1     

116      20300      0      0      0     

117      20475      4      -2      1     

118      20650      2      -1      1     

119      20825      2      0      1     

120      21000      2      -1      0     

121      21175      2      -1      1     

122      21350      2      -1      0     

123      21525      4      -1      2     

124      21700      2      -1      0     

125      21875      2      0      1     

126      22050      2      -1      0     

127      22225      2      0      1     

由以上的实验数据,我们可以看出,在频率为350Hz,8400Hz和18725Hz时,幅值出现峰值,分别为1500、2696和3996,这与我们所预期的结果正好相符,从而验证了实验结果的正确性。