基于STM32的FFT频谱分析+波形识别 您所在的位置:网站首页 分析dtmf信号的频谱 基于STM32的FFT频谱分析+波形识别

基于STM32的FFT频谱分析+波形识别

2024-07-15 16:09| 来源: 网络整理| 查看: 265

一.硬件部分

信号发生器,正点原子精英板,3.5’TFTLCD,两根杜邦线(接PC1和GND)

二.基本思路

1.使用ADC采集音频信号

2.使用官方提供的FFT函数(1024点)对采集到的信号进行处理

3.量化、频谱图显示

采样频率:Fs = 2400Hz(触摸版本可以根据实际情况调整)

样本数量:NPT = 1024

三.程序编写

1.ADC采样 这次用到的是ADC的DMA传输,这可以减少对程序的占用。这里着重关注这几行代码:

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC1 工作在独立模式 ADC_InitStructure.ADC_ScanConvMode =DISABLE; //模数转换工作在非扫描模式 ADC_InitStructure.ADC_ContinuousConvMode =DISABLE; //模数转换工作在不连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; //Timer1触发转换开启(定时器T1的CC1通道,控制采样频率)

假设有ADC1有四个通道需要转换(本例中只有一个通道):

连续转换单次转换扫描模式开始转换CH0、CH1、CH2、CH3转换完成后,继续转换CH0开始转换CH0、CH1、CH2、CH3转换完成后停止,等待ADC的下一次启动非扫描模式开始转换CH0,转换完成后,继续转换CH0转换完成后停止,等待ADC的下一次启动

我的代码就是按这个写的,不这样写应该也可以,不过我认为还是要多注意细节,不然根本不知道问题出在哪儿。

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA 外设 ADC 基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Value; //DMA 内存基地址

DMA传输注意这两句,存放地址。

2.FFT频谱分析 先下载一个FFT官方库,添加这几个文件 在这里插入图片描述 主要就是这几个函数

for(i=0;i signed short lX,lY; //算频率的话Fn=i*Fs/NPT //由于此处i是从0开始的,所以不需要再减1 float X,Y,Mag; unsigned short i; for(i=0; i unsigned int *pp = p+1; //p+1相当于我直接把0HZ部分滤掉了 unsigned int i = 0; for(i = 0;i int i,j; float k,k1,m; float aMax =0.0,aSecondMax = 0.0,aThirdMax = 0.0,aFourthMax=0.0; float fMax =0.0,fSecondMax = 0.0,fThirdMax = 0.0,fFourthMax=0.0; int nMax=0,nSecondMax=0,nThirdMax=0,nFourthMax=0; for ( i = 1; i aMax = a[i]; nMax=i; fMax=f[nMax]; } } for ( i=1; i continue;//跳过原来最大值的下标,直接开始i+1的循环 } if (a[i]>aSecondMax&&a[i]>a[i+1]&&a[i]>a[i-1]) { aSecondMax = a[i]; nSecondMax=i; fSecondMax=f[nSecondMax]; } } for ( i=1; i continue;//跳过原来最大值的下标,直接开始i+1的循环 } if (a[i]>aThirdMax&&a[i]>a[i+1]&&a[i]>a[i-1]) { aThirdMax = a[i]; nThirdMax=i; fThirdMax=f[nThirdMax]; } } for ( i=1; i continue;//跳过原来最大值的下标,直接开始i+1的循环 } if (a[i]>aFourthMax&&a[i]>a[i+1]&&a[i]>a[i-1]) { aFourthMax = a[i]; nFourthMax=i; fFourthMax=f[nFourthMax]; } } k=fabs(2*fMax-fSecondMax); k1=fabs(3*fMax-fSecondMax); m=fabs((float)(aMax-3.0*aSecondMax)); if(k LCD_Fill(270,360,320,400,BLACK); delay_ms(200); LCD_Fill(270,360,320,400,YELLOW); ji_shu=ji_shu-200; TIM1_Int_Init(ji_shu-1,fen_pin-1);//只有放这里才能保证只运行一次,不然可能会卡死 POINT_COLOR=BLACK; //画笔颜色 BACK_COLOR=YELLOW; //背景色 LCD_ShowString(284,365,16*2,16,24,"up"); //i++; } if(tp_dev.x[0]>270&&tp_dev.x[0]440&&tp_dev.y[0]


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有