打印

stm32f4 用dsp库做fft卡死

[复制链接]
11173|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
KC_CEC|  楼主 | 2013-11-6 12:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 KC_CEC 于 2013-11-6 13:19 编辑

问题1、
描述:
         通过分析arm_cmplx_mag_f32()这个函数可以看出,fft采样点数不一定是必须2的整数次方。那么现在我只需要采样250个点就能满足我的要求。
所以我定义一个输入缓存区f32_fftInBuffer[250],再定义一个输出缓存区f32_fftOutBuffer[250];整个过程是通过ADC采样将250点的电压给输入缓存区,然
后经过fft变化后提取里面的实数,经过2*R/N可以计算出对应频率点的幅度了。代码流程如下:
uint32_t fftSize=250;        
for(i=0;i<250;i++)
{
    f32_fftInBuffer=(float)ADC1Conver_Buffer*3.3f/4096;//电压进缓存
}
//cfft单元初始化
status = arm_cfft_radix4_init_f32(&S,fftSize,ifftFlag, doBitReverse);
//fft运算
arm_cfft_radix4_f32(&S, f32_fftInBuffer);
//提取实数
arm_cmplx_mag_f32(f32_fftInBuffer, f32_fftOutBuffer,fftSize);
for(i=0;i<250;i++,m++)
{
printf("lev==%f ,",f32_fftOutBuffer);//打印实数
if(i%5==0)printf("\r\n");


故障:单片机会卡死在fft运算函数出不来
问题2:
描述:
        后来我将fft采样点改为256个点,改定义一个输入缓存区f32_fftInBuffer[256],再定义一个输出缓存区f32_fftOutBuffer[256];fftSize=256;这个时候是可
以正常运行,但是出来的数据就不正常了。我用串口打印了两次fft转换结果:
第一次转换结果:

根据第一个点计算:339.581696/256=1.326491V,与实际直流电压偏置接近
第二次转换结果:

大得吓死人!
沙发
ilovezeno| | 2013-11-6 12:45 | 只看该作者
Parameters
[in]        *S        points to an instance of the floating-point Radix-4 CFFT/CIFFT structure.
[in,out]        *pSrc        points to the complex data buffer of size 2*fftLen. Processing occurs in-place.

lz,让我说你什么好呢。。。。。

使用特权

评论回复
板凳
KC_CEC|  楼主 | 2013-11-6 13:22 | 只看该作者
ilovezeno 发表于 2013-11-6 12:45
Parameters
        *S        points to an instance of the floating-point Radix-4 CFFT/CIFFT structure.
        *pSrc        poin ...

不是这个原因,我之前试过的。250个点分为500个做输入,输出的效果一样的

使用特权

评论回复
地板
ilovezeno| | 2013-11-6 13:44 | 只看该作者
KC_CEC 发表于 2013-11-6 13:22
不是这个原因,我之前试过的。250个点分为500个做输入,输出的效果一样的 ...

你确定输入数组格式对了么。。。

使用特权

评论回复
5
ilovezeno| | 2013-11-6 13:53 | 只看该作者
不是把250个点分500做输入,而是提供一个500的数组 数组前250是你的数据,后250是空的。。。。
请看Demo:arm_convolution_example_f32.c

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
icecut + 3
6
huangzj121| | 2013-11-6 14:33 | 只看该作者
FFT又称快速傅里叶 一般有基2 基4 方法
基2的 适用与log2(n)为整数的长度
基4的 适用与log4(n)为整数的长度
其实 没有什么不同 只是分块计算的 多项式个数不同
像封装的库 一般是做成基四方法
也就是说 64 256 1240 4096
不够的补零

看这看那 用处不大
还是认认真真 搞懂原理 你就明了
:)

使用特权

评论回复
7
ilovezeno| | 2013-11-6 14:45 | 只看该作者
huangzj121 发表于 2013-11-6 14:33
FFT又称快速傅里叶 一般有基2 基4 方法
基2的 适用与log2(n)为整数的长度
基4的 适用与log4(n)为整数的长度 ...

其实库里都说了,lz没看罢了

The parameter fftLen Specifies length of RFFT/CIFFT process. Supported FFT Lengths are 16, 32, 64, 128, 256, 512, 1024, 2048, 4096.

使用特权

评论回复
8
KC_CEC|  楼主 | 2013-11-6 14:48 | 只看该作者
谢谢帮忙,找到原因了。
arm_cfft_radix4_f32(&S, f32_fftInBuffer); 应该会改写输入缓存区里面的数据,所以我开了512个输入缓存区,
但是我每次赋值只有前面的250个,后面的数据没有赋值,经过循环调用这个函数,后面的262个数据会被改
写,而且在它的基础上再做fft运算,导致输出的结果就像振荡一样,越变越大。
    现在我每次运算,都把后面的数据赋值一次,结果就比较稳定了。
    那么,结贴了

使用特权

评论回复
9
KC_CEC|  楼主 | 2013-11-6 14:50 | 只看该作者
ilovezeno 发表于 2013-11-6 14:45
其实库里都说了,lz没看罢了

The parameter fftLen Specifies length of RFFT/CIFFT process. Supported ...
 /* Run the below code for Cortex-M4 and Cortex-M3 */
  uint32_t blkCnt;                               /* loop counter */

  /*loop Unrolling */
  blkCnt = numSamples >> 2u;

  /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
   ** a second loop below computes the remaining 1 to 3 samples. */
  while(blkCnt > 0u)
  {

    /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
    realIn = *pSrc++;
    imagIn = *pSrc++;
    /* store the result in the destination buffer. */
    arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);

    realIn = *pSrc++;
    imagIn = *pSrc++;
    arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);

    realIn = *pSrc++;
    imagIn = *pSrc++;
    arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);

    realIn = *pSrc++;
    imagIn = *pSrc++;
    arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);


    /* Decrement the loop counter */
    blkCnt--;
  }

  /* If the numSamples is not a multiple of 4, compute any remaining output samples here.   
   ** No loop unrolling is used. */
  blkCnt = numSamples % 0x4u;

  while(blkCnt > 0u)
  {
    /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
    realIn = *pSrc++;
    imagIn = *pSrc++;
    /* store the result in the destination buffer. */
    arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);

    /* Decrement the loop counter */
    blkCnt--;
  }

使用特权

评论回复
10
KC_CEC|  楼主 | 2013-11-6 14:51 | 只看该作者
本帖最后由 KC_CEC 于 2013-11-6 14:53 编辑

上面的代码说了的,如果不是4阶,会计算余数计算幅度。所以,我用500的话,上面那个函数应该是可以运行的。
但是卡死在的是在fft运算函数,所以上面说的意思应该是做fft运算时,必须是2的整数次方,但是取出数据就可以随意了。

使用特权

评论回复
11
KC_CEC|  楼主 | 2013-11-6 14:55 | 只看该作者
ilovezeno 发表于 2013-11-6 14:45
其实库里都说了,lz没看罢了

The parameter fftLen Specifies length of RFFT/CIFFT process. Supported ...

确实没仔细看,谢谢提醒

使用特权

评论回复
12
huangqi412| | 2013-11-6 21:13 | 只看该作者
KC_CEC 发表于 2013-11-6 14:48
谢谢帮忙,找到原因了。
arm_cfft_radix4_f32(&S, f32_fftInBuffer); 应该会改写输入缓存区里面的数据,所 ...

虚数输入没有赋值

使用特权

评论回复
13
chuangpu| | 2013-11-6 21:28 | 只看该作者
学习帖子  这一块  我要加强学习了  顶一个

使用特权

评论回复
14
icecut| | 2013-11-7 10:20 | 只看该作者
我看lz怎么就这么喜欢 数组 250 ,被哪本书害了???

使用特权

评论回复
15
香水城主| | 2013-11-7 10:29 | 只看该作者
嘿嘿,Lucky number...................

使用特权

评论回复
16
KC_CEC|  楼主 | 2013-11-7 11:00 | 只看该作者
icecut 发表于 2013-11-7 10:20
我看lz怎么就这么喜欢 数组 250 ,被哪本书害了???

显示区域横轴有250个像素点,所以就想一个点对应一个频率,一次将250个幅度构成曲线坐标一次性画上去

使用特权

评论回复
17
KC_CEC|  楼主 | 2013-11-7 11:01 | 只看该作者
香水城主 发表于 2013-11-7 10:29
嘿嘿,Lucky number...................

大哥,你想多了:L

使用特权

评论回复
18
KC_CEC|  楼主 | 2013-11-7 11:53 | 只看该作者
ilovezeno 发表于 2013-11-6 13:53
不是把250个点分500做输入,而是提供一个500的数组 数组前250是你的数据,后250是空的。。。。
请看Demo:a ...

我现在用的是cfft库,就是复数库。做fft变化,输入数组的格式是实部和虚部交替存放的。后面的空间不足的再补0.
The <code>pSrc</code> points to the array of in-place buffer of size <code>2*fftLen</code> and inputs and outputs are stored in an interleaved fashion as shown below.   
* <pre> {real[0], imag[0], real[1], imag[1],..} </pre>   

使用特权

评论回复
19
ilovezeno| | 2013-11-8 09:38 | 只看该作者
KC_CEC 发表于 2013-11-7 11:53
我现在用的是cfft库,就是复数库。做fft变化,输入数组的格式是实部和虚部交替存放的。后面的空间不足的再 ...

了解了!

使用特权

评论回复
20
tangqilin324| | 2014-7-23 10:38 | 只看该作者
KC_CEC 发表于 2013-11-6 14:48
谢谢帮忙,找到原因了。
arm_cfft_radix4_f32(&S, f32_fftInBuffer); 应该会改写输入缓存区里面的数据,所 ...

请问下你把后面 的数据赋值一次 是把后262个数据清零么?还有做fft的时候,你有没有分虚部和实部的方式放数据呢》

使用特权

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

本版积分规则

20

主题

169

帖子

1

粉丝