您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 第32章ARM官方DSP库实数FFT的实现
安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第11页页共共1111页页第第3322章章实实数数FFFFTT的的实实现现本章主要讲解实数的浮点和定点Q31,Q15的实现。关于这部分的知识点和函数的计算结果上,官方的文档有一些小错误,在章节中会跟大家详细讲述,还有一个要注意的问题,调用实数FFT函数一定要使用CMSIS-DSPV1.4.4及其以上版本,以前的版本有bug。本章节使用的复数FFT函数来自ARM官方库的TransformFunctions部分32.1复数FFT32.2复数FFT-基2算法32.3复数FFT-基4算法32.4总结3322..11实实数数FFFFTT3322..11..11描描述述CMSISDSP库里面包含一个专门用于计算实数序列的FFT库,很多情况下,用户只需要计算实数序列即可。计算同样点数FFT的实数序列要比计算同样点数的虚数序列有速度上的优势。快速的rfft算法是基于混合基cfft算法实现的。一个N点的实数序列FFT正变换采用下面的步骤实现:由上面的框图可以看出,实数序列的FFT是先计算N/2个实数的CFFT,然后再重塑数据进行处理从而获得半个FFT频谱即可(利用了FFT变换后频谱的对称性)。一个N点的实数序列FFT逆变换采用下面的步骤实现:实数FFT支持浮点,Q31和Q15三种数据类型。安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第22页页共共1111页页3322..22实实数数FFFFTT3322..22..11aarrmm__rrfffftt__ffaasstt__ff3322函数定义如下:voidarm_rfft_fast_f32(arm_rfft_fast_instance_f32*S,float32_t*p,float32_t*pOut,uint8_tifftFlag)参数定义:[in]*Spointstoanarm_rfft_fast_instance_f32structure.[in]*ppointstotheinputbuffer.[in]*pOutpointstotheoutputbuffer.[in]ifftFlagRFFTifflagis0,RIFFTifflagis1注意事项:结构arm_rfft_fast_instance_f32的定义如下(在文件arm_math.h文件):typedefstruct{arm_cfft_instance_f32Sint;/**InternalCFFTstructure.*/uint16_tfftLenRFFT;/**lengthoftherealsequence*/float32_t*pTwiddleRFFT;/**Twiddlefactorsrealstage*/}arm_rfft_fast_instance_f32;下面通过在开发板上运行函数arm_rfft_fast_f32和arm_cfft_f32计算幅频响应,然后将相应的频率响应结果在Matlab上面绘制出来。/***********************************************************************************************************函数名:arm_rfft_fast_f32_app*功能说明:调用函数arm_rfft_fast_f32计算1024点实数序列的幅频响应并跟使用函数arm_cfft_f32计算结果做对比*形参:无*返回值:无**********************************************************************************************************/staticvoidarm_rfft_fast_f32_app(void){uint16_ti;arm_rfft_fast_instance_f32S;/*实数序列FFT长度*/fftSize=1024;/*正变换*/ifftFlag=0;/*初始化结构体S中的参数*/arm_rfft_fast_init_f32(&S,fftSize);安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第33页页共共1111页页/*按照实部,虚部,实部,虚部.....的顺序存储数据*/for(i=0;i1024;i++){/*50Hz正弦波,采样率1KHz*/testInput_f32_10khz[i]=1.2f*arm_sin_f32(2*3.1415926f*50*i/1000)+1;}/*1024点实序列快速FFT*/arm_rfft_fast_f32(&S,testInput_f32_10khz,testOutput_f32_10khz,ifftFlag);/*为了方便跟函数arm_cfft_f32计算的结果做对比,这里求解了1024组模值,实际函数arm_rfft_fast_f32只求解出了512组*/arm_cmplx_mag_f32(testOutput_f32_10khz,testOutput,fftSize);/*串口打印求解的模值*/for(i=0;ifftSize;i++){printf(%f\r\n,testOutput[i]);}printf(****************************分割线***************************************\r\n);for(i=0;i1024;i++){/*虚部全部置零*/testInput_f32_10khz[i*2+1]=0;/*50Hz正弦波,采样率1KHz,作为实部*/testInput_f32_10khz[i*2]=1.2f*arm_sin_f32(2*3.1415926f*50*i/1000)+1;}arm_cfft_f32(&arm_cfft_sR_f32_len1024,testInput_f32_10khz,ifftFlag,doBitReverse);/*求解模值*/arm_cmplx_mag_f32(testInput_f32_10khz,testOutput,fftSize);/*串口打印求解的模值*/for(i=0;ifftSize;i++){printf(%f\r\n,testOutput[i]);}}运行如上函数可以通过串口打印出函数arm_rfft_fast_f32和arm_cfft_f32计算的幅频模值,下面通过Matlab绘制波形来对比这两种模值。对比前需要先将串口打印出的两组数据加载到Matlab中,arm_rfft_fast_f32的计算结果起名signal,arm_cfft_f32的计算结果起名sampledata,加载方法在前面的教程中已经讲解过,这里不做赘述了。Matlab中运行的代码如下:Fs=1000;%采样率N=1024;%采样点数n=0:N-1;%采样序列f=n*Fs/N;%真实的频率subplot(3,1,1);安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第44页页共共1111页页plot(f,signal);%绘制RFFT结果title('实数FFT');xlabel('时间');ylabel('幅值');subplot(3,1,2);plot(f,sampledata);%CFFT结果title('复数FFT');xlabel('时间');ylabel('幅值');Matlab运行结果如下:从上面的前512点对比中,我们可以看出两者的计算结果是相符的。这里有一点要特别注意,官方文档中对于函数arm_rfft_fast_f32输出结果的实部,虚部排列顺序说明是错误的。函数arm_rfft_fast_f32的输出结果仍然是实部,虚部,实部,虚部…..依次排列下去。函数arm_rfft_fast_f32在计算直流分量(也就是频率为0的值)的虚部上是有错误的。关于这点大家可以将实际的实部和虚部输出结果打印出来做对比,但差别很小,基本可以忽略。010020030040050060070080090010000200400600实数FFT时间幅值010020030040050060070080090010000200400600复数FFT时间幅值安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第55页页共共1111页页3322..22..22aarrmm__rrfffftt__qq1155函数定义如下:voidarm_rfft_q15(constarm_rfft_instance_q15*S,q15_t*pSrc,q15_t*pDst)参数定义:[in]*SpointstoaninstanceoftheQ15RFFT/RIFFTstructure.[in]*pSrcpointstotheinputbuffer.[out]*pDstpointstotheoutputbuffer.returnnone.注意事项:结构arm_rfft_instance_q15的定义如下(在文件arm_math.h文件):typedefstruct{uint32_tfftLenReal;uint8_tifftFlagR;uint8_tbitReverseFlagR;uint32_ttwidCoefRModifier;q15_t*pTwiddleAReal;q15_t*pTwiddleBReal;constarm_cfft_instance_q15*pCfft;}arm_rfft_instance_q15;下面通过在开发板上运行函数arm_rfft_q15和arm_cfft_f32计算幅频响应,然后将相应的频率响应结果在Matlab上面绘制出来。/***********************************************************************************************************函数名:arm_rfft_q15_app*功能说明:调用函数arm_rfft_q15计算1024点实数序列的幅频响应并跟使用函数arm_cfft_f32计算的结果做对比。*形参:无*返回值:无**********************************************************************************************************/staticvoidarm_rfft_q15_app(void){uint16_ti,j;arm_rfft_instance_q15S;/*实数序列FFT长度*/fftSize=1024;/*正变换*/安安富富莱莱UUMM440033DDSSPP教教程程SSTTMM3322--VV55开开发发板板系系统统篇篇手手册册22001155年年0011月月1155日日版版本本::11..00第第66页页共共1111页页ifftFlag=0;/*码位倒序*/doBitReverse=1;/*初始化结构体S*/arm_rfft_init_q15(&S,fftSize,ifftFlag,
本文标题:第32章ARM官方DSP库实数FFT的实现
链接地址:https://www.777doc.com/doc-5072131 .html