F2833x 调用DSP函数库实现复数的FFT的方法
转载自:http://blog.csdn.net/aeecren/article/details/67644363;个人觉得写的很详细,值得一看
在数字信号处理中,FFT变换是经常使用到的,在DSP中自己编写的FFT变换函数通常会存在计算效率太慢的问题,有时需要调用DSP函数库自带的变换函数。但是,DSP在对FFT运算效率优化的同时,对于函数的调用方式也就有了比较多的要求,下面结合自己的调试经验做一下简单的介绍。
1、准备工作
DSP的数字信号处理的一系列函数都在C28x_FPU_Lib.lib库中,因此,首先需要在CCS的工程文件中连接此库:在工程设置中C2000 Linker——file search path中添加该库和路径。并在主程序中包含下面头文件:#include "FPU.h"。
2、结构体介绍
FFT函数的输入为一个结构体,该结构体的定义方式如下:
typedef struct
{ float32 *InPtr;
float32 *OutPtr;
float32 *CoefPtr;
float32 *CurrentInPtr;
float32 *CurrentOutPtr;
Uint16 Stages;
Uint16 FFTSize;
} CFFT_F32_STRUCT;
其中InPtr为输入数组指针,假设你的CFFT的采样点1024个点,那么你的输入数组为inputdata[2*FFTSize],长度为2048是因为输入数据为复数,实部和虚部需要分开进行存储的,所以输入数组的长度为2*FFTSize.其中实部和虚部的存储方式为inputdata[0]存储你第一点的实部,inputdata[1]存储第一点的虚部,接着依次向下inputdata[2]存储第二个点的实部,inputdata[3]第二个点的虚部。
OutPtr为指向输出数组的指针,输出数组的大小也为2*FFTSize,存储方式同样的outputdata[0]。
CoefPtr,为指向转化因子数组的指针,长度为FFTSize,决定傅里叶转化因子的只有傅里叶变换的阶数。
CurrentInPtr也是指向输入数组的指针,但是该输入数组是用来计算幅值所用的。
CurrentOutPtr来指向幅值输出的数组。
stage为傅里叶变换的阶数。
FFTSize为FFT变换的长度,也就是常说的多少点的FFT变换,其与阶数的关系为FFTSize=2^stage。
3、函数介绍
下面介绍一下各个函数的应用:
第一个函数是: CFFT_f32_sincostable(&cfft)
其中cfft就是上述的一个结构体。这个函数的作用就是计算傅里叶变换的转化因子。转化因子由公式可知只与傅里叶变换的阶数有关,所以只要在结构体中对stage和FFTSize进行了赋值就可以计算转化因子了,而且转化因子是固定的,如果不需改变傅里叶变换的阶数,只需要计算一次就好了。
第二个函数是: CFFT_f32(&cfft)
这个函数就是做复数傅里叶变换的函数,需要注意的是该函数要求输入数组的数据格式对齐,即变量存储的起始地址为2*FFTsize*sizeof(float),实现方式在下面3中定义。如果数据格式不对齐,则该函数的计算结果不定。
第三个函数是:
CFFT_f32u(&cfft)
这个函数同样是做FFT变换的,但是其不要求输入数据的格式对齐,适用于输入数据格式比较乱时,但是同样相对与前一个函数来说,其计算效果会比较差。
第四个函数为 : CFFT_f32_mag(&cfft)
这个函数是计算幅值的函数,主要作用就是计算*CurrentInPtr指向的复数数组中的复数的模值,将计算出来的模值保存在*CurrentOutPtr该成员指向的数组中,与其他成员无关。
最后一个函数是: ICFFT_f32(&cfft)
该函数计算FFT的逆变换。同样要求输入数组格式对齐。
4、 格式对齐的实现方式
前面介绍的CFFT和ICFFT函数都要求输入的数组格式对齐,即变量存储的起始地址为2*FFTsize*sizeof(float)。例如256点的FFT变换,则变量的起始地址必须是1024的倍数。格式对齐的方式利用变量定义的方式进行。
首先确定变量存储的区域,该代码与普通对存储空间分区的代码无区别,只是定义一个区域用来存储自己定义的变量:
ZONE6C : origin = 0x108000, length = 0x004000
然后在上面存储分区中定义变量存储的段,用来定义后续变量的具体位置,ALIGH的作用就是使该段的起始地址为2*FFTsize*sizeof(float)的倍数,但是其功能也仅仅如此,如果在该段中定义了多个变量,则不能保证每个变量的起始地址均为1024倍数。因此一般一个段只定义一个变量,可以在同一个区中定义出多个段,从而实现多个变量的定义。如下面例子中,在ZONE6C区中定义了四个段,每个段首地址均为1024的倍数。
ZONE6FFTinDATA : > ZONE6C, PAGE = 1 ALIGN(1024)
ZONE6w_change_DATA : > ZONE6C, PAGE = 1 ALIGN(1024)
ZONE6x_frequency_amp : > ZONE6C, PAGE = 1 ALIGN(1024)
ZONE6FFToutDATA : > ZONE6C, PAGE = 1 ALIGN(1024)
然后定义变量所在的段,每个变量占了一个段:
#pragma DATA_SECTION(fft_data_1024,"ZONE6FFTinDATA");
#pragma DATA_SECTION(CFFToutBuff,"ZONE6FFToutDATA");
#pragma DATA_SECTION(x_frequency_amp_1024,"ZONE6x_frequency_amp");
#pragma DATA_SECTION(W_fft_change,"ZONE6w_change_DATA");
最后定义变量类型和大小:
float32 fft_data_1024[512]; //定义FFT内部变换使用的复数数组
float32 CFFToutBuff[512]; //定义FFT处理复数结果数据
float32 W_fft_change[256];
float32 x_frequency_amp_1024[256]; //定义FFT处理幅值结果数据
通过上面的定义的方式实现了对于变量格式对齐的定义。
F2833x 调用DSP函数库实现复数的FFT的方法的更多相关文章
- 转:在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档
在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档 一直以来,我都想为 PDF 补丁丁添加一个 PDF 渲染引擎.可是,目前并没有可以在 .NET 框架上运行的免费 PDF ...
- ThinkPHP 3.2 调用自定义函数库
ThinkPHP3.2 和3.1 区别还是有点大的 引入了命名空间,强化了驱动化和行为,增强了模块化的概念和对云平台的支持,并改进了诸多的细节.主要改进包括:模块化架构的全新设计全新命名空间和自动导入 ...
- Rstudio调用plot()函数时,出现错误的处理方法
按照书上的例子敲出代码后,发现Rstudio无法识别C盘user文件夹下的中文用户名.如下图所示: 按照网上的做法,尝试修改计算机user下的用户名,没修改成功. 另一种做法是在plot()函数前面加 ...
- python网络编程调用recv函数完整接收数据的三种方法
最近在使用python进行网络编程开发一个通用的tcpclient测试小工具.在使用socket进行网络编程中,如何判定对端发送一条报文是否接收完成,是进行socket网络开发必须要考虑的一个问题.这 ...
- python调用C函数
python 与 c可以相互调用,在做后台服务时底层服务用C/C++编写,通过python调用C库可以极大的提高开发效率. 下面对几种调用方式举例说明 1 python通过指针传递浮点型数组给C函数 ...
- [UE4]蓝图函数库
在任何蓝图上都可以调用“蓝图函数库”的方法
- jsp el函数库
EL函数库介绍 由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,所以SUN公司针对一些常见的处理定义了一套EL函数库供开发者使用. 这些EL函数在JSTL开发包中进行描述,因此在JSP页 ...
- java使用JNA框架调用dll动态库
这两天了解了一下java调用dll动态库的方法,总的有三种:JNI.JNA.JNative.其中JNA调用DLL是最方便的. ·JNI ·JNA ·JNative java使用 JNI来调用dll动态 ...
- Phpcms v9系统类库与函数库调用方法
在分享了n多phpcms的教程后,cmsyou继续分享关于phpcms v9系统类库与函数库的调用方法. 系统类库位于系统的 /libs/functions目录下面,函数库文件名为*.func.php ...
随机推荐
- Unity3d外包团队:Unity3d最新版本更新内容
GPU Instancing Improvement 只能改进了一些功能吧,原GPU Instancing shader可参考 https://docs.unity3d.com/Manual/GPUI ...
- Testlink与MantisBT集成
Testlink与MantisBT集成 关于两者集成的文章网上有很多,但是有些文章可能是作者写的时候自己不理解或有纰漏,有些文章写得是不够详细导致在配置中遗漏什么导致不成功.经过一天的不停尝试,终于完 ...
- C# 在类中使用Timer定时器以及延时处理的方法
我们平时在C#中要用到定时功能时,有自带定时器,一般在定时器里面写函数就行了,现在需要在类里面写了一个定时器,不和界面绑定,一开始的时候感觉没什么思路,然后看了一下界面的设计代码,有了思路,还是很简单 ...
- ArcGIS Pro开发Web3D应用(4)——Portal发布三维没有“发布”选项解决
如题,将三维场景包.slpk上传并发布,未看到发布选项. 问题核心就在于环境没配置好,主要有2点: 1.验证联合托管状态 需要将托管服务器与Portal进行联合,并进行验证,此情况需要在WebAdap ...
- Java中封装类型.valueOf()
@Test public void test() { Integer i3 =128; Integer i4=128; boolean integerGT127=i3==i4; //false Sys ...
- Redis(二)--Jedis使用
1.Jedis是连接java和redis的jar,这里用maven来添加jar包 # 在eclipse中新建maven project,填写GroupID.Artifactid # 在百度搜索mave ...
- 如何运行一个Vue项目
一开始很多刚入手vue.js的人,会扒GitHub上的开源项目,但是发现不知如何运行GitHub上的开源项目,很尴尬.通过查阅网上教程,成功搭建好项目环境,同时对前段工程化有了朦朦胧胧的认知,因此将环 ...
- C++函数指针与指针函数干货
C++要是不常用,相信过四天你的指针函数与函数指针的概念就该忘个精光. 其实只要记住谁在后面谁就是哪个本质. 先了解下指针数组与数组指针吧 数组指针 就是指向数组的指针,它表示的是一个指针,它指向的是 ...
- C语言实现过滤ASCII在0~127范围内的字符,并去除重复的字符
#include <stdio.h> #include <string.h> /* 1.以字符串作为参数 2.找出ASCII在1~127范围内的字符 3.去掉重复字符 */ i ...
- 嵌入式Linux开发之uboot启动Linux整体流程分析
嵌入式Linux开发之uboot启动Linux整体流程分析 Uboot全称Universal Boot Loader,一个遵循GPL协议的的开源项目,其作用是引导操作系统,支持引导linux.VxWo ...