10949|39

66

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

测出FFT(快速傅里叶变换)计算一个周期所花费的时间 [复制链接]

工作上要先计算出FFT(提供的是FFT的一个库,有些函数我们可以调用库)计算一个周期所花费的时间,决定是否采用凌阳的CPU。项目大概是这样的:有一个FM接收器,另外一个凌阳MCU包括A/D转换器(主要是用来控制的),现在要先测试FFT运行的时间,表格如下:
                      采样点
                64    128   256   512

          2

采样频率   4

单位:KHz)8

         16

中间要填入的就是FFT运行的时间。请问采样点是怎样输入到FFT,如果是从A/D寄存器输入,又要怎样输入128,256个这么多点。还是输入FFT的必须为连续信号,也就是说:不能输入128个离散的呢,它的时间又是怎样测出来呢?我这有一段代码(仅仅是演示怎么用FFT库)
int *P_IOB_Data = 0x7005;
int *P_IOB_Dir = 0x7007;      
int *P_IOB_Attrib = 0x7008;

int main()
{
        int i, j, addr;
        unsigned short k, max, sum, *port, *gOut;
        int maxID;
        *P_IOB_Dir = 0xFFFF;
        *P_IOB_Attrib = 0xFFFF;
        *P_IOB_Data = 0x0000;
               
        SystemInitial();
        maxID = Get_FFT256_Version();
        InitFFT();       
        while(1)
        {
                addr = GetFFT();
                max = maxID = 0;
                gOut = addr;
                while (*gOut == 1)
                {
                        gOut+=2;
                        for(i=1;i<128; i++)
                        {       
                                sum = *gOut++;
                               
                                if(sum > max)
                                {
                                        max = sum;
                                        maxID = i;
                                }
                        }
                        (int)port = 0x7000;
                        *port = maxID;
                }
               
                *P_IOB_Data = 0xFFFF;
                FFTServiceLoop();
                *P_IOB_Data = 0x0000;
        }                       
       
        return 0;
}
   
另外一个是system.asm,我认为有用,就贴出来了。其中r1 = C_Timer_Setting_8K 估计是设定采样频率的,为什么采样点就没有看到在函数中设定呢?还是要怎样设定
.include GPCE.inc

.text
.public        _SystemInitial
_SystemInitial:                .proc

                int off
                fiq off
               
                r1 = C_49MHz                                        // 49MHz, Fcpu=Fosc
        [P_SystemClock] = r1                  
        r1 = 0x0030                     // TimerA CKA=Fosc/2 CKB=1 Tout:off
        [P_TimerA_Ctrl] = r1                        // Initial Timer A
        r1 = C_Timer_Setting_8K                  // 8K
        [P_TimerA_Data] = r1

        r1 = 0xffff      
        [P_INT_Clear] = r1                  // Clear interrupt occuiped events
        
        r1 = [P_INT_Ctrl]
        r1 |= C_FIQ_TMA                                        // Enable Timer A FIQ
        [P_INT_Ctrl] = r1
        
        fiq on                                //
        
        r1 = [P_ADC_Ctrl]                        // enable AGC,MIC,AD
                r1 |= 0x0005
                [P_ADC_Ctrl] = r1
                r1 = [P_DAC_Ctrl]
                r1 |= 0x0008
                [P_DAC_Ctrl] = r1                       

                r1 = 0
                [P_IOA_Data] = r1
                r1 = 0xffff
                [P_IOA_Dir] = r1
                [P_IOA_Attrib] = r1
        
                retf
.endp

//---------------------------------------------------------------------------
// Get FFT Sample process
// User have to implement this according to get data from mic or line in
// return r1 = FFT sample       
//
.public F_GetFFTSample
F_GetFFTSample:                .proc

L_WaitADCRdy:
                r1 = [P_ADC_Ctrl]
                r1 |= 0x8000
                jz L_WaitADCRdy
                               
                r1 = [P_ADC]

                retf
.endp  


想了很久,还是不知道怎样测试FFT运行的时间,所以就请教高手帮忙看看了,谢谢

最新回复

用定时器不就行了     详情 回复 发表于 2020-9-1 12:43
点赞 关注

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
刚才那采样频率没有对齐,采样频率分别为2、4、8等。怎么没有人懂这个吗?
 
 

回复

92

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
真的没人懂吗?是不是运行main函数,用示波器测试B口任一个电压变化的波形,对应的横坐标的时间就是FFT运行时间呢?我想:FFTServiceLoop(); 之前*P_IOB_Data = 0xFFFF输出高电平,之后*P_IOB_Data = 0x0000为低电平。高电平到低电平时间是不是FFT运行的时间呢???是不是通过 r1 = C_Timer_Setting_8K  // 8K 修改采样频率,for(i=1;i <128; i++) 循环修改采样点呢???
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

4
 
什么凌阳CPU确实不知道,也没时间去了解.
如果你真得想得到帮助可以把你的问题简化抽象出来.
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

5
 
其实就是想测FFT在不同的采样频率、不同采样点下运行的所花费的时间,整个平台是在凌阳的MCU上运行
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

6
 
FFT是软件运行的吧,运行时间应该很容易DUMP出来. 能否说清楚你的困难点在什么地方?
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 
我这提供的是FFT库(就是我们可以利用一些库中的函数),比如:int* GetFFT(void)。通过利用这些函数来测试不同采样点在不同的采样频率下运行的所花费的时间,当然这些函数调用都是在凌阳的编译器中编写,应该也要在MCU上跑,测试FFT计算的时间。goldencode可不可以给个QQ之类的,想这样更容易表达清楚。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

8
 
抱歉啊,我不用QQ的,也不用其他聊天工具.
我想弄明白这个问题究竟是哪里困难, 最简单地,你可以在MAIN函数里打印系统时间嘛,这样可以看出FFT的运行时间啊. 至于你说要在不同的采样频率下测试应该是硬件设置就可以了吧.
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

9
 
MAIN函数里打印系统时间,感觉不准确,并且其他代码运行也需时间。另外采样频率是看到在初始化中可以设置,就是没有看到采样点的设置或其输入接口,这也是我犯愁的。
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

10
 
抱歉刚看到,你说的采样频率指的是FFT的采样频率吧, 因此你的问题应该是如何读懂软件中设置采样频率的部分.你提供的源代码是谁提供的,凌阳?他们应该很容易回答你这个问题.
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

11
 
采样频率倒是有一个语句,也就是上面代码中的红色字:r1 = C_Timer_Setting_8K  // 8K ,但我就是没有看到采样点是怎样设置的。不知道是要我们自己通过A/D寄存器输入口。是我们老大发给我们的,他从哪拿到的就不知道。这个问题我现在也还不是很清楚,等明天在问清楚,再来请教你了,先谢了
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

12
 
抵制法国货,抵制傅里叶变换!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

13
 
真对不住大家了,我也真讨厌TMD法国,尤其是这次萨科齐会见了达赖喇嘛。但没办法,我还是得完成任务。O(∩_∩)O哈哈~
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

14
 
引用 11 楼 stephen_yin 的回复:
抵制法国货,抵制傅里叶变换!

我倒!这是个理论。可以用到信号分析上,不能抵制。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

15
 
计算后时间-计算前时间=计算时间。
我对嵌入式开发不懂,不知道用的什么平台,应该有计算时间的API吧。
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

16
 
这里我贴出了FFT256 Library User’s Manual说明书的一些说明:
1.The FFT256 library provides 256 points Fast Fourier Transform. If the sampling rate is 8KHz, we have 128 points spectrum from 0 to 4KHz.(这个库是256个采样点的)
2.Users have to put the service loop in the main loop to keep entering the serviceregularly. Inside the FFT256service loop, there will be a mechanism to decide any task should be carried on. Some overhead will produced inevitably. The amount of overhead varies and depends on the payload of CPU.
Example:
In main.c
int main()
{
System_Initial();// System initial
InitFFT ();// FFT initial
while(1)// start FFT
{
addr = GetFFT();// Get FFT result
FFTServiceLoop ();// FFT Service loop
System_ServiceLoop();// Service loop for watchdog clear
}
return 0;
}

In isr.asm:
_FIQ:
Push r1, r5 to [sp] // Save registers
Call F_FFTService_ISR // Interrupt service routine
R1 = C_IRQ0_TMA
[P_INT_Clear] = R1 // Clear interrupt flag
Pop r1, r5 from [sp] // restore registers
reti




Remark:
1. This function is used in assembly only and it can be hooked on the _FIQ, _IRQ1 or _IRQ2:
label. (See isr.asm for details)
2. The F_FFTSerivce_ISR will not take up any time to process the Interrupt routine except
minor overheads if the program is not in FFT mode. It is possible for users to place
user-define function in the same FIQ or IRQ.
3. This function calls the F_GetFFTSample to get data from mic or line in.
3.How to use the FFT256 library
Main()
{
InitFFT (); // FFT initial
while(1)
{
addr = GetFFT();
FFTServiceLoop ();
System_ServiceLoop();
} // end of while
return 0;
} // end of main
其中,函数GetFFT()说明:
返回值:int*: spectrum address
Library: FFT256.lib
Remark:
1. address[0] is spectrum ready flag
2. address[1:128] are FFT results from 0 to 4KHz while sampling rate is 8KHz.
函数InitFFT()说明:
Remark:
1. This function initializes the Kernel of FFT.
2. The hardware setting is opened for user’s reference (see SystemInitial in system.asm). It
initializes the System Clock, Timer A, ADC, DAC and enables the Timer A FIQ at the sample rate
on 8KHz.

上面差不多就是给的FFT说明书的内容了。我觉的采样频率其实就是for(i=1;i <128; i++)中的128来改变。如果不是这样设置,那要通过A/D输入寄存器读入buffer,那这个buffer又是怎样传入到FFT中呢。在第一页的for循环中,也没有看到怎样传采样点,只是循环外调用FFTServiceLoop()函数。
内容有点长,希望懂这方面的人帮帮忙,谢谢了

只提供上面几个函数,没有时间的API,main中的*P_IOB_Data = 0xFFFF;FFTServiceLoo();*P_IOB_Data=0x0000;
我想可能是通过B口电平高0xFFFF,运行FFTServiceLoo();*,后B口电平低0x0000,在示波器上看出高低电平时间,但这样测出的感觉只是FFTServiceLoo()的时间,不知道采样点是怎样实现的。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

17
 
我现在也在做类似工作,不过是在PPC上使用FFTW来做FFT,你说的周期是指的是你信号的周期还是FFT计算周期,关于通过一个IO口来计算时间
先将PORT_A设置为高,然后执行FFT算法,执行完成以后,在将PORT_B设置为低,你可以通过示波器来读PORT_A高电平的时间,或者通过单片机的计数器数个数,应该比较简单呀!
 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(初级)

18
 
就是FFT在不同的采样频率、不同的采样点下运算的时间,但关键是不知道采样点是怎样获得,又怎样设置为FF的采样点呢,采样频率可以通过在system.asm文件中r1 = C_Timer_Setting_8K //8K 来设置。下面是syste.asm的参考代码

  1. .include GPCE.inc

  2. .text
  3. .public        _SystemInitial
  4. _SystemInitial:                .proc

  5.                 int off
  6.                 fiq off
  7.                
  8.                 r1 = C_Fcpu_49M //C_49MHz                                        // 49MHz, Fcpu=Fosc
  9.         [P_SystemClock] = r1                  
  10.         r1 = 0x0030                     // TimerA CKA=Fosc/2 CKB=1 Tout:off
  11.         [P_TimerA_Ctrl] = r1                        // Initial Timer A
  12.         r1 = C_Timer_Setting_16K  // 8K[color=#FF0000]这应该是设置采样频率[/color]
  13.         [P_TimerA_Data] = r1

  14.         r1 = 0xffff      
  15.         [P_INT_Clear] = r1                  // Clear interrupt occuiped events
  16.         
  17.         r1 = [P_INT_Ctrl]
  18.         r1 |= C_FIQ_TMA                                        // Enable Timer A FIQ
  19.         [P_INT_Ctrl] = r1
  20.         
  21.         fiq on                                //
  22.         
  23.         r1 = [P_ADC_Ctrl]                        // enable AGC,MIC,AD
  24.                 r1 |= 0x0005
  25.                 [P_ADC_Ctrl] = r1
  26.                 r1 = [P_DAC_Ctrl]
  27.                 r1 |= 0x0008
  28.                 [P_DAC_Ctrl] = r1                       

  29.                 r1 = 0
  30.                 [P_IOA_Data] = r1
  31.                 r1 = 0xffff
  32.                 [P_IOA_Dir] = r1
  33.                 [P_IOA_Attrib] = r1
  34.         
  35.                 retf
  36. .endp

  37. //---------------------------------------------------------------------------
  38. // Get FFT Sample process
  39. // User have to implement this according to get data from mic or line in
  40. // return r1 = FFT sample       
  41. //
  42. .public F_GetFFTSample
  43. F_GetFFTSample:                .proc

  44. L_WaitADCRdy:
  45.                 r1 = [P_ADC_Ctrl]
  46.                 r1 |= 0x8000//[color=#FF0000]设置采样点个数吗?但具体的buffer怎样读入呢?[/color]
  47.                 jz L_WaitADCRdy
  48.                                
  49.                 r1 = [P_ADC]

  50.                 retf
  51. .endp
复制代码


另外有一个怎样使用FFT256库的流程:
                                                Set Storage
                                          Start Address

                                          Initial FFT

                   ISR(Get ADC Data)      FFT In Buffer
                                               FFT
                                          FFT Out Buffer

                                          Write Result
                                          To Storage

不知道怎样插入本地图片,其中ISR(Get ADC Data)有一箭头指向FFT In Buffer那一模块,其他都是顺序往下的箭头
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

19
 
a stable signal pattern (e.g. a 1kHz sine-wave)  input to the Sunplus's A/D input pin for your FFT data input and trial calculation.

Regarding to the FFT time consumption measurement:
1. the start point is measured during the input data is ready (e.g. the Window size is 128, so after A/D convert complete the 128th data sampling, it's the starting point)
2. the end point is counted during the output data is ready (same as the example above, when the 128th output data is done, that is the end point)
How to mark the starting and end point, you may use programming to read the time, or program the GPIO (e.g. to generate a pulse) on Sunplus to indicate the start and end point.

这是给的参考,我还是对时间的测试及采样点不是太明白,看看大家是怎么理解的?谢谢
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

20
 
引用 19 楼 zhongyuanceshi 的回复:
How to mark the starting and end point, you may use programming to read the time, or program the GPIO (e.g. to generate a pulse) on Sunplus to indicate the start and end point.


大概看了一下,好像是说如果做128点的FFT,那么就让CPU采到128个点作为一个队列送给FFT函数运算吧,
同样的输出也是要成128点的队列才输出FFT的结果。。。

是不是要求你准确到利用CPU的时间,来判断何时读完这128点的队列??  

T=128*一个采集点的CPU周期 ??


你的凌阳芯片的主频应该是知道的吧,知道主频的话,T就很容易算出来了。。。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表