STM32 FFT优化最终版!速度逼近官方库,不再折腾了再搞剁手
本帖最后由 Borden 于 2014-4-7 11:58 编辑简介:这是一个在STM32F103开发板上做的FFT计算演示程序。程序以36kHz采样率从AD采集播放器的音频信号,然后以同样速率发送到DA通过喇叭播放。同时采下来的信号做FFT变换,在屏幕上显示两路音频波形以及频谱。
之前的程序(http://www.amobbs.com/forum.php?mod=viewthread&tid=5574904&page=1#pid7424203)搞好之后本来不打算再弄了,但是在本坛另外一个帖子里面发现原来ST是有官方DSP库的,文档:(http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/CD00208762.pdf),里面的benchmark结果显示官方库的1024点FFT的速度居然达到了2.138ms,基本上是我之前程序速度的一倍,于是我又不淡定了。。。
去官网找了半天居然找不到那个库的下载,放狗一搜才发现有人说官方早就把那个库下架了,我估计是为了给带DSP指令集的F4系列让路。还好有老外放出了下载(https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/DispForm.aspx?ID=30831&RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fSTM32F10x%20DSP%20library%2c%20where%20is%20it),下回来看了看,官方库确实是高度优化的,但是代价是非常固化,不灵活,实用性比较差。说白了就是跑分很好看,真正用那个库就不是那么回事了。主要体现在:
1、它的输入是1024点32bit的数组(以1024FFT为例),那么要用这个库你必须把数据拷贝到数组里面。在实时运算的时候基本上只有双缓冲这一个唯一的选择。而双缓冲是有缓冲切换开销的。我的程序是给个指针直接从循环缓冲区任意位置读数据的,任意缓冲区长度,自动回卷。
2、它用的是基-4的FFT,我用的是最简单的基-2的。基-4的FFT理论上运算量就比基-2的小,速度肯定快,但是代价是FFT点数必须是4^n,如果你要做512点或者2048点的FFT,那么你就没法用官方库了。另外看它的代码,实际上stm32做基-4的FFT寄存器是不大够用的,所以它里面有很多数据倒来倒去的过程,如果寄存器能像64位ARM那样有32个的话,官方库这个程序还可以更快~
3、它的输入输出是等长的,就是说你做1024点的FFT输入必须是1024点,如果你的输入小于这个长度,是没有任何性能提升的。我的程序可以随意设置输入长度,自动补零自动优化,当输入长度小于FFT点数的时候速度可以成倍提升。实际上我工作中用的FFT是4096点的,但是输入数据只有128点。所以这一点优化在实际应用中还是非常有用的。
好了,基本情况就是这样。我之前那个FFT是32位精度的,为了跟官方库比较,也跟着改为16位了。前前后后改了一个礼拜,每天都能发现一些新的地方可以提高速度,搞到现在觉得基本上到头了。也实在是不能再搞了,我觉得自己有点走火入魔了,再搞工作都要丢了~~
成果:视频演示的是跟官方benchmark一样的配置,1024入1024出,16bit,三角函数表在flash里。视频中关闭显示之后即是纯FFT循环,此时除了FFT之外只有AD,DA以及帧率显示。可以看到实测是365fps,也就是2.74ms,比官方的2.138ms还是差一点,残念。。。作为基-2的FFT,我基本上只能接受这样的结果啦,哎~~~~
http://v.youku.com/v_show/id_XNjk1NDE3NTI0.html
很不错! 32
2
32
32
0
0
ddddddddddddddddddd 楼主能分享一下代码不,毕竟能在FFT上卡住的,肯定是math不过关 还有,如果采集的是一个标准波形,要求初始相位的话,是不是做完1024个点的FFT后再找出实部最大的数据,用atan(虚部,实部)计算出该点相位即为这波形的初始相位??正研究这块,有了解的兄弟麻烦讲解下,多谢多谢! 求问用STM32采集波形做FFT的流程。。。。是不是这样子的:STM32先按36K频率AD采集1024个点,然后1024个数据一起FFT?如果AD只有一个通道采集的话,整个过程(采集加FFT一次)大概耗时多久? 楼主呢不能给大家分享一下呢。共同学习。 强,哈哈:D:D:D:D:D:D:D 我只想说:楼主不放代码给我们学习学习?