打印
[STM32F1]

使用STM32提供的DSP库进行FFT

[复制链接]
284|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wilhelmina2|  楼主 | 2024-7-26 19:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
FFT官方库的使用条件
FFT官方库在使用上并不灵活:属于基4的FFT,即FFT点数必须是4^n。也就是说,如果要做512点或2048点的FFT,那么对不起,没法使用官方库了;
FFT官方库的输入输出是等长的,即256点的FFT输入也必须是256点,如果你的输入小于这个长度,是没有任何性能提升的。

FFT官方库的使用
准备工作
下载得到STM32的DSP库之后,就可以将其添加到自己的工程项目中了。

其中,stm32_dsp.h和table_fft.h两个文件是必须添加的。stm32_dsp.h是STM32的DSP库的头文件。

另外,对于**.s文件可以有选择的添加**(用到那个添加那个即可)。由于本文只用到了256点的FFT,所以这里只添加了cr4_fft_256_stm32.s文件。


FFT函数说明
进行256点的FFT,只需要调用STM32 DSP库函数中的cr4_fft_256_stm32()函数即可。该函数的原型为:

void cr4_fft_256_stm32(void *pssOUT, void *pssIN, uint16_t Nbin);
其中,参数pssOUT表示FFT输出数组指针,参数pssIN表示要进行FFT运算的输入数组指针,参数Nbin表示了点数。至于该函数的具体实现,因为是用汇编语言编写的,我也不懂,这里就不妄谈了。

需要说明的是:按照FFT官方库的说明,pssOUT和pssIN都必须是32位的数据类型,其中高16位存储实部,低16位存储虚部。对于pssIN来说,低16位存储的虚部总是为0。

代码实例
假设ADC采样的声音数据为adc_buf[NPT],FFT运算的输入数组为lBufInArray[NPT]。由于FFT计算出来的数据是对称的,因此通常而言输出数组取一半的数据,为lBufOutArray[NPT/2]。除此之外,还定义各次谐波幅值lBufMagArray[NPT/2]。即:

#define NPT 256

uint32_t adc_buf[NPT]={0};
long lBufInArray[NPT];
long lBufOutArray[NPT/2];
long lBufMagArray[NPT/2];
调用FFT官方库的代码为:

//填充数组
for(i=0;i<NPT;i++)
        //这里因为单片机的ADC只能测正的电压 所以需要前级加直流偏执
        //加入直流偏执后,需要在软件上减去2048即一半,达到负半周期测量的目的(需要根据具体情况来进行配置)
        lBufInArray[i] = ((signed short)(adc_buf[i]-2048)) << 16;
       
cr4_fft_256_stm32(lBufOutArray, lBufInArray, NPT);
同时,计算各次谐波幅值的函数为:
void GetPowerMag()
{
    signed short lX,lY;
    float X,Y,Mag;
    unsigned short i;
    for(i=0; i<NPT/2; i++)
    {
        lX  = (lBufOutArray[i] << 16) >> 16;
        lY  = (lBufOutArray[i] >> 16);

        //除以32768再乘65536是为了符合浮点数计算规律
        X = NPT * ((float)lX) / 32768;
        Y = NPT * ((float)lY) / 32768;
        Mag = sqrt(X * X + Y * Y) / NPT;
        if(i == 0)
            lBufMagArray[i] = (unsigned long)(Mag * 32768);
        else
            lBufMagArray[i] = (unsigned long)(Mag * 65536);
    }
}
https://blog.csdn.net/qq_38410730/article/details/90116695

使用特权

评论回复
沙发
kzlzqi| | 2024-7-29 15:14 | 只看该作者
虽然FFT官方库的性能很高,但由于FFT点数限制,请选择合适的点数进行计算。

使用特权

评论回复
板凳
范德萨发额| | 2024-7-29 15:44 | 只看该作者
输入数组 pssIN 和输出数组 pssOUT 都必须是32位的,格式为高16位实部,低16位虚部。对于输入数据,虚部为0。

使用特权

评论回复
地板
申小林一号| | 2024-7-29 22:38 | 只看该作者
感谢分享

使用特权

评论回复
5
喂什么玩意| | 2024-7-31 11:41 | 只看该作者
FFT点数必须是4^n。需要遵循一些特定的条件和要求,特别是对于FFT点数和输入输出格式

使用特权

评论回复
6
喂什么玩意| | 2024-7-31 11:41 | 只看该作者
输入和输出数组必须是32位的,其中高16位存储实部,低16位存储虚部。
对于输入数据,虚部总是为0,所以实部数据被左移16位后存储在32位整数的高16位中。

使用特权

评论回复
7
AdaMaYun| | 2024-7-31 14:21 | 只看该作者
FFT官方库的输入输出是等长的,即256点的FFT输入也必须是256点,如果你的输入小于这个长度,是没有任何性能提升的。

使用特权

评论回复
8
gaonaiweng| | 2024-8-29 12:11 | 只看该作者
输入和输出数组长度必须相等。对于256点FFT,输入和输出数组都必须有256个数据点。

使用特权

评论回复
9
gaonaiweng| | 2024-8-29 12:15 | 只看该作者
该库仅支持基于4的FFT点数,即FFT的点数必须是4的幂(例如256点、1024点等)。如果需要进行512点或2048点的FFT,您可能需要使用其他库或自定义实现。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

1187

帖子

1

粉丝