OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4498|回复: 9

两个问题,问题2:问题1:stm32f3的FPU咋没显著提升运算速度?FIR滤波出来后再FFT傅里叶变换,数据感觉有问题。

[复制链接]

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-9-15
在线时间
6 小时
发表于 2017-9-15 22:34:50 | 显示全部楼层 |阅读模式
1金钱
#include "stm32f30x.h"
//#include "math"
#include "arm_math.h"
#include "FFT.h"
#include "TIM6.h"

#define FFT_FENGTH        1024

uint16_t u16FFT_time_ms = 0;
uint16_t u16FIR_time_ms = 0;
float32_t fFFT_InputBuf[FFT_FENGTH * 2] = {0.0};
float32_t fFFT_OutputBuf[FFT_FENGTH] = {0.0};

float32_t fFFT_FIR_OutputBuf[FFT_FENGTH] = {0.0};

#define BLOCK_SIZE                1024        //μ÷óÃarm_fir_f32′|àíμÄ2éÑùμã¸öêy
#define NUM_TAPS 100                //ÂË2¨Æ÷Ïμêy¸öêy

uint32_t u32BlockSize = BLOCK_SIZE;
uint32_t u32NumBlocks = FFT_FENGTH / BLOCK_SIZE;        //Dèòaμ÷óÃarm_fir_f32μÄ′Îêy
float32_t fFIR_input[FFT_FENGTH] = {0.0};        //2éÑùμã
float32_t fFIR_Output[FFT_FENGTH] = {0.0};        //ÂË2¨oóμÄêä3ö
float32_t        fFIR_StateBuf[BLOCK_SIZE + NUM_TAPS - 1] = {0.0};        //×′쬻o′æ
float32_t fFIR_Coeffs[NUM_TAPS] = {
-0.0004449822882,-0.000529786048,-0.0004296849656, -0.00015425522, 0.000231205282,
   0.000608043687,0.0008274181164,0.0007575381314,0.0003448091738,-0.0003353640495,
  -0.001068142592,-0.001550090848,-0.001498236787,-0.0007839158643,0.0004647070309,
   0.001848744578, 0.002804118674,  0.00280921231, 0.001625645091,-0.0005284877843,
   -0.00296607567,-0.004720899742,-0.004900803789,-0.003084987402,0.0003970534308,
   0.004448343068, 0.007507949602, 0.008109144866, 0.005506821442,0.0001263979357,
  -0.006383617874, -0.01158876345, -0.01310589258,-0.009574958123,-0.001402036985,
   0.009059074335,  0.01805452444,  0.02162205242,  0.01708529331, 0.004346948117,
   -0.01352019794, -0.03069991618, -0.04007250071, -0.03531132266, -0.01301661879,
    0.02580606192,  0.07545947284,   0.1266504675,   0.1687272042,   0.1924432814,
     0.1924432814,   0.1687272042,   0.1266504675,  0.07545947284,  0.02580606192,
   -0.01301661879, -0.03531132266, -0.04007250071, -0.03069991618, -0.01352019794,
   0.004346948117,  0.01708529331,  0.02162205242,  0.01805452444, 0.009059074335,
  -0.001402036985,-0.009574958123, -0.01310589258, -0.01158876345,-0.006383617874,
  0.0001263979357, 0.005506821442, 0.008109144866, 0.007507949602, 0.004448343068,
  0.0003970534308,-0.003084987402,-0.004900803789,-0.004720899742, -0.00296607567,
  -0.0005284877843, 0.001625645091,  0.00280921231, 0.002804118674, 0.001848744578,
  0.0004647070309,-0.0007839158643,-0.001498236787,-0.001550090848,-0.001068142592,
  -0.0003353640495,0.0003448091738,0.0007575381314,0.0008274181164, 0.000608043687,
   0.000231205282, -0.00015425522,-0.0004296849656,-0.000529786048,-0.0004449822882
};        //ÂË2¨Ïμêy

void FFT_test(void)
{
        uint32_t u32i = 0;
        arm_cfft_radix4_instance_f32 scFFT;
       
        u16TIM6_couter_FFT = 0;

        arm_cfft_radix4_init_f32(&scFFT, FFT_FENGTH, 0, 1);        //3õê¼»ˉscFFT½á11ì壬é趨FFT2Îêy
        for(u32i = 0; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_InputBuf[u32i*2] = 100 + 10*arm_sin_f32(2*PI*u32i/FFT_FENGTH) + 30*arm_sin_f32(2*PI*u32i*4/FFT_FENGTH) + 50*arm_sin_f32(2*PI*u32i*8/FFT_FENGTH) + 100*arm_sin_f32(2*PI*u32i*200/FFT_FENGTH);        //êμ2&#191;
                fFFT_InputBuf[u32i*2+1] = 0;        //Dé2&#191;è&#171;2&#191;&#206;a0
                fFIR_input[u32i] = fFFT_InputBuf[u32i*2];
        }
        arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf);        //FFT±&#228;&#187;&#187;
        arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_OutputBuf, FFT_FENGTH);        //&#199;ó&#196;£
        fFFT_OutputBuf[0] = fFFT_OutputBuf[0] / FFT_FENGTH;        //&#199;ó·ù&#214;μ
        for(u32i = 1; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_OutputBuf[u32i] = fFFT_OutputBuf[u32i] / (FFT_FENGTH / 2);
        }
       
        u16FFT_time_ms = u16TIM6_couter_FFT;
}


void FIR_test(void)
{
        uint32_t u32i = 0;
        arm_fir_instance_f32 S;
        float32_t *fInput;
        float32_t *fOutput;
        arm_cfft_radix4_instance_f32 scFFT;
       
        u16TIM6_couter_FIR = 0;
       
        fInput = fFIR_input;
        fOutput = fFIR_Output;
        arm_fir_init_f32(&S, NUM_TAPS, fFIR_Coeffs, fFIR_StateBuf, u32BlockSize);
        for(u32i = 0; u32i < u32NumBlocks; u32i++)
        {
                arm_fir_f32(&S, fInput+(u32i*u32BlockSize), fOutput+(u32i*u32BlockSize), u32BlockSize);
        }
       
        arm_cfft_radix4_init_f32(&scFFT, FFT_FENGTH, 0, 1);        //3&#245;ê&#188;&#187;ˉscFFT&#189;á11ì&#229;£&#172;éè&#182;¨FFT2&#206;êy
        for(u32i = 0; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_InputBuf[u32i*2] = fFIR_Output[u32i];        //êμ2&#191;
                fFFT_InputBuf[u32i*2+1] = 0;        //Dé2&#191;è&#171;2&#191;&#206;a0
        }
        arm_cfft_radix4_f32(&scFFT, fFFT_InputBuf);        //FFT±&#228;&#187;&#187;
        arm_cmplx_mag_f32(fFFT_InputBuf, fFFT_FIR_OutputBuf, FFT_FENGTH);        //&#199;ó&#196;£
        fFFT_FIR_OutputBuf[0] = fFFT_FIR_OutputBuf[0] / FFT_FENGTH;        //&#199;ó·ù&#214;μ
        for(u32i = 1; u32i < FFT_FENGTH; u32i++)
        {
                fFFT_FIR_OutputBuf[u32i] = fFFT_FIR_OutputBuf[u32i] / (FFT_FENGTH / 2);
        }
       
        u16FIR_time_ms = u16TIM6_couter_FIR;
}


先上代码
问题1:
void FFT_test(void)   未使用FPU耗时14ms,使用FPU耗时13ms
void FIR_test(void)   未使用FPU耗时18ms,使用FPU耗时18ms
时间使用u16FFT_time_ms 、u16FIR_time_ms分别测量(TIM6定时1ms)的,测量精度比较低,但还是可以看出FPU基本没起作用,请问是否正常?
问题2:
void FFT_test(void)是对常量+1Hz+4Hz+8Hz+200Hz的1024个点的FFT变换,结果如下:
0  100.000038
1 10.0000191
4 30.0000877
8 99.9999161
200 10.0000191
其他频率都在 0.000135251816附近
可以看出FFT的计算还是很靠谱的

void FIR_test(void)是对常量+1Hz+4Hz+8Hz+200Hz先进行99阶的FIR低通滤波,截止频率为100Hz,后再对FIR滤波结果进行FFT变换。结果见附图
可以看到0、1、4、8以外的点都从0.0001左右上升到1~4左右了,FIR使得低频信号有所失真,请问这种失真属于正常么?


问题3:安富莱DSP FIR教程中有每次处理数据量的做法,请问是何意义?我测试了一次处理1024个点也是没有问题的。见附图2

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-9-15
在线时间
6 小时
 楼主| 发表于 2017-9-15 22:36:24 | 显示全部楼层
图第一次发不上去,只能再次发了。(话说Openedv配图真不方便)

FIR+FFT后的数据

FIR+FFT后的数据
捕获5.PNG
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2017-9-16 01:07:30 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-9-15
在线时间
6 小时
 楼主| 发表于 2017-9-16 08:28:51 来自手机 | 显示全部楼层
原子老师,请问FPU作用不明显是咋回事呢?
回复

使用道具 举报

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-9-15
在线时间
6 小时
 楼主| 发表于 2017-9-16 08:33:54 来自手机 | 显示全部楼层
我的FIR的阶数设置对的吧?看到说dsp库要求FIR系数是4的整数倍,我就用MATLAB设计了99阶,系数为100。这点安福来教程忽略了,教程中取得28阶,即系数有29个,是不是有问题呢?
回复

使用道具 举报

88

主题

7377

帖子

5

精华

资深版主

Rank: 8Rank: 8

积分
14980
金钱
14980
注册时间
2013-11-13
在线时间
1823 小时
发表于 2017-9-16 08:49:07 | 显示全部楼层
看一下你的汇编代码里面有没有用到浮点寄存器和浮点指令
开往春天的手扶拖拉机
回复

使用道具 举报

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2017-9-15
在线时间
6 小时
 楼主| 发表于 2017-9-16 09:57:52 | 显示全部楼层
fFFT_InputBuf[u32i*2] = 100 + 10*arm_sin_f32(2*PI*u32i/FFT_FENGTH) + 30*arm_sin_f32(2*PI*u32i*4/FFT_FENGTH) + 50*arm_sin_f32(2*PI*u32i*8/FFT_FENGTH) + 100*arm_sin_f32(2*PI*u32i*200/FFT_FENGTH);的汇编

0x080008AC EE004A10  VMOV          s0,r4
0x080008B0 EEB80A40  VCVT.F32.U32  s0,s0
0x080008B4 EDDF0A57  VLDR          s1,[pc,#0x15C]
0x080008B8 EE200A20  VMUL.F32      s0,s0,s1
0x080008BC EDDF0A56  VLDR          s1,[pc,#0x158]
0x080008C0 EE801A20  VDIV.F32      s2,s0,s1
0x080008C4 EEB08A41  VMOV.F32      s16,s2
0x080008C8 EEB00A48  VMOV.F32      s0,s16
0x080008CC F7FFFCF0  BL.W          arm_sin_f32 (0x080002B0)
0x080008D0 EDDF8A52  VLDR          s17,[pc,#0x148]
0x080008D4 EEF20A04  VMOV.F32      s1,#10
0x080008D8 EE408A80  VMLA.F32      s17,s1,s0
0x080008DC EE004A10  VMOV          s0,r4
0x080008E0 EEB80A40  VCVT.F32.U32  s0,s0
0x080008E4 EDDF0A4B  VLDR          s1,[pc,#0x12C]
0x080008E8 EE200A20  VMUL.F32      s0,s0,s1
0x080008EC EEF10A00  VMOV.F32      s1,#4
0x080008F0 EE200A20  VMUL.F32      s0,s0,s1
0x080008F4 EDDF0A48  VLDR          s1,[pc,#0x120]
0x080008F8 EE801A20  VDIV.F32      s2,s0,s1
0x080008FC EEB08A41  VMOV.F32      s16,s2
0x08000900 EEB00A48  VMOV.F32      s0,s16
0x08000904 F7FFFCD4  BL.W          arm_sin_f32 (0x080002B0)
0x08000908 EEF30A0E  VMOV.F32      s1,#30
0x0800090C EE408A80  VMLA.F32      s17,s1,s0
0x08000910 EE004A10  VMOV          s0,r4
0x08000914 EEB80A40  VCVT.F32.U32  s0,s0
0x08000918 EDDF0A3E  VLDR          s1,[pc,#0xF8]
0x0800091C EE200A20  VMUL.F32      s0,s0,s1
0x08000920 EEF20A00  VMOV.F32      s1,#8
0x08000924 EE200A20  VMUL.F32      s0,s0,s1
0x08000928 EDDF0A3B  VLDR          s1,[pc,#0xEC]
0x0800092C EE801A20  VDIV.F32      s2,s0,s1
0x08000930 EEB08A41  VMOV.F32      s16,s2
0x08000934 EEB00A48  VMOV.F32      s0,s16
0x08000938 F7FFFCBA  BL.W          arm_sin_f32 (0x080002B0)
0x0800093C EDDF0A38  VLDR          s1,[pc,#0xE0]
0x08000940 EE408A80  VMLA.F32      s17,s1,s0
0x08000944 EE004A10  VMOV          s0,r4
0x08000948 EEB80A40  VCVT.F32.U32  s0,s0
0x0800094C EDDF0A31  VLDR          s1,[pc,#0xC4]
0x08000950 EE200A20  VMUL.F32      s0,s0,s1
0x08000954 EDDF0A33  VLDR          s1,[pc,#0xCC]
0x08000958 EE200A20  VMUL.F32      s0,s0,s1
0x0800095C EDDF0A2E  VLDR          s1,[pc,#0xB8]
0x08000960 EE801A20  VDIV.F32      s2,s0,s1
0x08000964 EEB08A41  VMOV.F32      s16,s2
0x08000968 EEB00A48  VMOV.F32      s0,s16
0x0800096C F7FFFCA0  BL.W          arm_sin_f32 (0x080002B0)
0x08000970 EDDF0A2A  VLDR          s1,[pc,#0xA8]
0x08000974 EE408A80  VMLA.F32      s17,s1,s0
0x08000978 492B      LDR           r1,[pc,#172]  ; @0x08000A28
0x0800097A EB0100C4  ADD           r0,r1,r4,LSL #3
0x0800097E EDC08A00  VSTR          s17,[r0,#0x00]


我对内核不了解,不好意思,请问是否使用了FPU?
回复

使用道具 举报

13

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2016-9-26
在线时间
38 小时
发表于 2017-11-22 20:35:03 | 显示全部楼层
我求出来的幅值也很尴尬,第一个数组的幅值有90这样的数据出来
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2019-7-12
在线时间
3 小时
发表于 2019-10-1 22:11:10 | 显示全部楼层
路过 看看
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2019-7-12
在线时间
3 小时
发表于 2019-10-1 22:11:32 | 显示全部楼层
路过 学习中!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-16 19:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表