网站大量收购独家精品文档,联系QQ:2885784924

STM32-FFT代码的说明 .docx

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
STM32-FFT代码的说明

FFT代码说明FFT为Fast Fourier Transformation,即快速傅里叶变换,本项目中,FFT的目标是识别频率为形如式的一个正弦信号:其中,;因为单片机通过ADC接口读取该正弦信号的电压值,而12位精度的ADC的值范围在0-4096之间,如信号经过放大器后映射到0-3.3V之间,则振幅A的取值0-4096之间。假设,信号经过放大器后,其电压值最大为3.3V,最小为0V,则此信号的振幅为1.65V,对应A=2048,即该信号为:本文中给出的例程即通过FFT识别式这种正弦信号。假设采样频率为Fs,信号频率Fn,采样点数为N。那么FFT之后结果就是一个为N点的复数。每一个点就对应着一个频率点。这个点的模值,就是该频率值下的幅度特性。具体跟原始信号的幅度有什么关系呢?假设原始信号的峰值为A,那么FFT的结果的每个点(除了第一个点直流分量之外)的模值就是A的N/2倍。而第一个点就是直流分量,它的模值就是直流分量的N倍。第一个点表示直流分量(即0Hz),而最后一个点N的再下一个点(实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后)则表示采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率依次增加。例如某点n所表示的频率为:频率分辨率()等于采样时间的倒数。例如要分辨0.1Hz,则需要采集10s。基于STM32官方DSP库的FFT算法工程文件中包含三个函数库,分别为:cr4_fft_64_stm32.scr4_fft_256_stm32.scr4_fft_1024_stm32.s分别对应数据点数为64,256和1024时的FFT算法。下面将以数据点数是1024为例,说明FFT的实现过程。通过函数生成原始数据for(i=0;iNPT;i++) {Fx=2048+2048*sin(PI2*i*21/Fs+20)+1000*sin(PI2*i*15/Fs)+100*sin(PI2*i*25/Fs)+rand()%100;//振幅2048,频率21HZ,为主要的谐波分量,21HZ也是所需信号的频率,rand()%100为0-100之间的随机噪声lBUFIN[i] = ((s16)fx)16; //高位为实部,低位为虚部 }Fs为采样频率,此处设为102.4Hz,NPT为数据长度(即前文中提到的N),为了能够分辨0.1Hz,数据长度NPT设为1024,则频率分辨率=102.4/1024=0.1Hz。对原始数据进行FFTSTM32 库中给出的FFT函数格式如下:Void cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);其中,NPT为数据点个数,通过修改宏定义来修改NPT代表的值,此处为1024;LBUFOUT[NPT]和LBUFIN[NPT]均是长度为NPT的32位长整型的数组,高16位为实部,低16位为虚部,LBUFOUT[NPT]用于保存FFT之后的输出值;LBUFIN[NPT]用于保存输入的数值。对原始数据进行FFT之后,需要对输出数据进行处理。频率计算每个频率点处代表的真实频率为for(i=0;iNPT/2;i++){Fn=i*Fs/NPT//由于此处i是从0开始的,所以不需要再减1}幅值计算经过FFT后,每个频率点处的真实幅值的计算公式如下。voiddsp_asm_powerMag(void){s16lX,lY;u32i; for(i=0;iNPT/2;i++) //由于FFT的频谱结果是关于奈奎斯特频率对称的,所以只计算一半的点即可 {lX = (lBUFOUT[i] 16) 16;//取低16位,虚部lY = (lBUFOUT[i] 16);//取高16位,实部{float X= NPT * ((float)lX) /32768;float Y= NPT * ((float)lY) /32768;float Mag = sqrt(X*X + Y*Y)/NPT;lBUFMAG[i]= (u32)(Mag * 65536); } //真实振幅lBUFMAG[i]=sqrt(lX*lX + lY*lY)*2/NPT,先除以32768,又乘以65536是为了符合浮点数的计算规律 }lBUFMAG[0]= lBUFMAG[0]/2;//直流分量不需要乘以2,所以按照乘以2计算后,要除以2}得到每个频率点所代表的真实频率Fn,以及该真实频率所代表的原始信号的振幅A,将其通过串口打印到电脑上。for(i=0;iNPT/2;i++) {printf(%4d,%.2f%10d\n,i,((float)i*Fs/NPT),lBUFMAG[i]); }结果如下图所示。图1 f=0hz 处幅值图2 f=15Hz处幅值图3

文档评论(0)

ctuorn0371 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档