用STM32实现FFT
前言
电子设计大赛已经过去很久了,一直想写一篇关于FFT的文章也没有来得及,现在写一下来记录分享一下。
本篇文章不讲复杂的FFT原理,只讲如何在stm32里面怎么实现FFT
一、FFT是什么,能干啥?
FFT(fast Fourier transform)快速傅里叶变换,把时域信号变换到频域,至于换到频域后能做啥,那就多了,你能搜到这篇文章,说明你已经知道他是干啥的了,,,,
二、先用matlab来认识一下FFT
1.上代码
代码如下:
fs = 1024; %采样频率
NPT = 1024; %样点个数
t=0:1/fs:1; %采样步长,模拟单片机采样频率
y= 2+200*cos(2*pi*15*t)+40*cos(2*pi*100*t+pi*90/180)+15*cos(2*pi*250*t+pi*90/180);
plot(t,y); %画出未变换前的时域信号波形
fbl=fs/NPT; %分辨率
f=(0:NPT)*fbl; %每个点所代表的频率
Y=fft(y); %进行FFT变换,matlab中fft函数,输入多少采样数据,就输出多少幅频值(是个复数)%所以length(y)=length(Y);
figure(2)
plot(f(1:NPT/2),abs(Y(1:NPT/2)));%以每个点所代表的频率画出其对应的赋值
2.代码关键字讲解
思想都是一样的,matab知道了,在32里面也差不多
采样频率: 用单片机ADC采样,结果是离散的数字信号,参考采样定理,采样频率至少大于信号频率的两倍,在这里我们采样频率1024,远大于基波频率2,选取1024也是为了方便自己,可以更直观的观察输出(2的整数倍都可)。
分辨率: 输出时,最小频率间隔(Fs/N),第n个点所代表的频率即为Fn=(n-1)*Fs/N,在这个程序中,采样频率是1024,采样点数是1024,所以,分辨率为1Hz
输出赋值 fft输出就是复数,取模值即可
3.程序结果
未变换前的时域信号波形图:
转换后输出的幅频函数波形图:
由图可看出输入信号大概有三个频率,15,100,250.与输入信号相符
二、淦! 上32
STM32官方给了三个函数库文件,分别是:
cr4_fft_64_stm32.s
cr4_fft_256_stm32.s
cr4_fft_1024_stm32.s
(这些都是汇编语言写的,好在我们不需要看懂,只需要会调用就好。)
分别对应这采样点数为64,256,1024。库函数的获取,可以在官网上获取
我们的目标是计算周期为1ms波形的THD值!,使用采样点数为64位的函数
1、代码移植
新建文件夹,把
cr4_fft_64_stm32.s
cr4_fft_256_stm32.s
cr4_fft_1024_stm32.s
和stm32_dsp.h
文件添加到工程里(就像添加.C文件一样),注:stm32_dsp.h文件里第27行需要根据自己单片机型号来修改
2,ADC采集
ADC采集没有什么好说的,我想让大家注意一点就是采样周期,在这里,为了方便使用,我们设ADC采样频率为64KHz,注意,这里直接调用正点原子的Get_Adc();函数的话,他的执行周期很长,需要改短(自己跳进Get_Adc()函数里,看函数定义,再改),要不然,在定时器中,ADC采集时间会超过中断事件,导致采样周期不是64KHz,最好在中断中设置一个LED灯反转的程序,检测ADC采样周期,确保ADC采集频率稳定
3、上函数
在上函数之前,我们把函数的每一个输入输出变量的含义说一下
在我的程序里是这样调用的:cr4_fft_64_stm32(output,input,NPT);
她的输入变量是input:是一个int32_t类型的数组,高十六位是实部,第十六位是虚部,显然,我们ADC采集只能采集实数。所以我对采集到的数据进行这样的处理:
ADC_Value[i]=Get_Adc(ADC_Channel_5);input[i] = ((s16)ADC_Value[i])<<16;
至于虚部,就不用管啦,移位后默认是0
他的另一个输入是NPT ,采样点数。最好是定义成宏定义,因为要用到他定义的数组太多,这里是64
他的输出是output,也是个复数,高十六位代表实部,低十六位代表虚部,他们的模值就是我们要的幅值
呐,官方给了专门求赋值的函数
void dsp_asm_powerMag(int32_t *IBUFOUT)
{s16 lx,ly;u32 i;for(i=0;i<NPT/2;i++)//由于FFT的频域结果是关于奈奎斯特频率对称的,所以只计算一半{lx = (IBUFOUT[i] << 16)>>16; //取低十六位,虚部ly = (IBUFOUT[i] >> 16); //取高十六位,实部float X = NPT*((float)lx)/32768;float Y = NPT*((float)ly)/32768;float Mag = sqrt(X*X+Y*Y)/NPT;OUTPUT_MAG[i] = (u32)(Mag*65536);}//这些就是计算振幅IBUFOUT[i] = sqrt(lx*lx+ly*ly)*2/NPT//之所以先除以32768后乘以65536是为了符合浮点数的计算规律OUTPUT_MAG[0] = OUTPUT_MAG[0]/2;//这个是直流分量,不需要乘以2
}
直接用就很OK了
dsp_asm_powerMag(output);
那么我们调用了函数,也转换成幅值了,所以,我该怎么用这些输出的数呢。他输出的是什么***,接下来就需要对应起来,
我们需要知道的是 每个频率点对应的幅值,现在有幅值,怎么把他对应的点找到,这样我们就大功告成了
还记得前面讲的分辨率嘛,对,我们采样点是64个,采样频率也是64KHz,那么分辨率就是fs/NPT即为1KHz,也就是说输出的output每隔一个对应着一个相差位1Hz的频率,那么output[1]就对应着1KHz,output[2]就对应着2KHz,output[3]就对应着3KHz,,,,我们只取前NPT/2个,不要问为什么,问奈奎斯特吧。
还有就是output[0]对应着直流分量
我只用了前几个意思意思。
cr4_fft_64_stm32(output,input,NPT);dsp_asm_powerMag(output); LCD_ShowxNum(100,0, OUTPUT_MAG[0] ,7,16,0); LCD_ShowxNum(100,16, OUTPUT_MAG[1] ,7,16,0); LCD_ShowxNum(100,32, OUTPUT_MAG[2] ,7,16,0); LCD_ShowxNum(100,48, OUTPUT_MAG[3] ,7,16,0); LCD_ShowxNum(100,64, OUTPUT_MAG[4] ,7,16,0); LCD_ShowxNum(100,80, OUTPUT_MAG[5] ,7,16,0); THD=100*(float)sqrt((Voltage[4]*Voltage[4]+Voltage[2]*Voltage[2]+Voltage[3]*Voltage[3]+Voltage[5]*Voltage[5]))/(float)(Voltage[1]);
总结
YSJX
用STM32实现FFT相关推荐
- STM32 实数FFT 极速配置
想要进行FFT操作就得配置DSP环境,操作如下 STM32 keil极速配置DSP环境 关于FFT,先上操作再讲含义 操作 添加定义 #define fftsize 256 //对256个数据进行FF ...
- 音乐频谱显示小玩具——FFT在STM32中的实现与应用
0.前言 音乐频谱显示说白了就是"儿童版"频谱仪.笔者平时比较喜欢听音乐,闲暇之余听音乐的时候如果有个频谱显示的小玩具在旁边跳来跳去的也挺有意思的,所以笔者去万能的某宝上搜索了一下 ...
- 2020电子设计大赛E题复盘
今年参加电赛,选择了E题.赛题基本要求: 这道题大体来说有两个方案. 方案一:用五个晶体管放大电路分别产生波形.(好处:好调试,同时不会因为其中一个元器件故障导致其他的波形都出不了结果.劣处:工作量大 ...
- 单片机c语言三角波采样点,E题_江苏赛区_南京信息工程大学——放大器非线性失真分析装置 一等奖...
放大器非线性失真研究装置(E题) 摘 要 本设计是一个能产生非线性失真的晶体管放大器,**由两级共射放大电路以及一级推挽电路构成.可以通过调节放大器内各个电阻的阻值,来变更静态工作点,以及通过短路推挽 ...
- 22年电赛冬令营授课
2022综合方向冬令营 课程安排 内容 日期 注意 视频地址 熟悉开发方式,IO(点灯),中断 1.16 回顾IO和EXTI(非教学)--冬令营_哔哩哔哩_bilibili 串口的使用,重定向prin ...
- STM32CubeMX配置ADC采样(轮询、中断、DMA)
选择DMA循环采集DMA_CIRCULAR uint16_t ADCRes[ADC_DMA_BUF_SIZE]; //变量易变,编译器不能随便优化 #define ADC_Ech_Channel 3 ...
- STM32 CubeMX配置ADC+DMA进行FFT(1)
STM32 CubeMX配置ADC+DMA,计算采样率和ADC电压 原创:睿智嵌入式 最近,因为项目需要处理音频信号,对AD采集的音频信号进行FFT运算,记录一下学习过程. 主要内容: 1.ADC和D ...
- STM32 FFT DMA ADC THD
利用STM32 FFT算法计算THD 一.设备准备 -->粤嵌STM32F429IGT6开发板 1块 -->串口调试助手 二.FFT算法意义 使用FFT算法,是为了获取信号在频域的相关参数 ...
- STM32+CubeMX 通过RMS和FFT进行波形识别
波形识别 本文所展示的程序可以用于分辨正弦波.三角波.方波三种波形. 文章目录 波形识别 思路 可以判断波形的两个特点 时域方面 频域方面 外设配置 & DSP库配置 代码部分 串口重定向 时 ...
最新文章
- 【java】兴唐第十五节课
- sublime使用技巧(4)-- 其他技巧【持续更新】
- Eigen求解数学问题(一)
- JAVA 两个简单的抽奖算法
- Jsoup获取动态js生成的内容
- python 邮件中生成图表_60秒一口Python:147个demo,助你从新手小白步步进阶编程高手...
- Web的未来:语义网
- graphql java中文文档_GraphQL学习指南 PDF 下载
- 怎么彻底卸载cad2017_彻底卸载cad2010的方法步骤
- 组装台式计算机的部件,组装台式电脑各配件的简单介绍
- halcon模板匹配实践(5)使用橡皮擦涂抹功能实现减少模板匹配特征
- 打开计算机文档左边,打开.chm的文件后,看不到左边的目录,该怎样解决?
- 机器学习——算法介绍-4
- 单片机c语言拟合二次曲线y=a0+a1x+a2x^2
- 微软Visio流程图软件,Visio流程图制作工具下载安装教程(1)
- 打印菱形图案的两种方法
- 【XXE漏洞01】XML漏洞原理及实验
- c语言洗牌发牌 无大小王 分四堆,C语言入门题
- 基于CC2530设计的自动晾衣杆
- RFC系列协议--rfc2373--IP Version 6 Addressing Architecture
热门文章
- 对外API接口的安全性设计及鉴权方式
- 密码与确认密码自动验证html,html表单验证确认密码
- ChatGPT神奇应用:定制化学习体验,get专属家教
- 腾讯云账号怎么看服务器密码是什么格式,腾讯云服务器怎么查看FTP账号密码?...
- python traceback print_python traceback捕获并打印异常
- win11 端口设置(本地网站搭建)
- 大咖说|“网上浙大”数字化之路
- 32位Win7下安装Ubuntu 16.04
- echarts双y轴实现(解决刻度线不对齐)
- 优利德UT61E+ 说明书电子版 - 技术参数节选