这次项目中,由于AD采集到的高频开关噪声大,对数据处理存在极大干扰,经过示波器测量,发现噪声频率主要集中在80kHz,寻求老师帮助,老师推荐使用FFT滤波,有同学使用的是FIR滤波,通过Matlab中自带的FDA工具获得参数,效果在噪声幅值大于0.6V存在阶段性下滑,我使用的FFT滤波,由于网上资料有限,网上都是推荐的是直接使用FIR滤波这类的滤波器,FFT滤波可能会存在一些问题,但是目前对于本次项目,我还是觉得尝试一下FFT滤波,查看一下效果如何。
首先使用的Matlab进行仿真,代码如下
SampleFreq = 800000; %为滤去80k高频 需大于2*80k的采样频率
S1_Freq = 20000; %模拟的初始信号频率
S2_Freq =80000; %高频开关噪声的频率
SAMPLE_NODES = 32;
i = 1:SAMPLE_NODES;
wt1=2*pi*i*S1_Freq;
wt1=wt1/SampleFreq;
wt2=2*pi*i*S2_Freq;
wt2=wt2/SampleFreq;
x = sin(wt1) +0.2*cos(wt2)+2; %获得20KHz基波+80KHz谐波信号,
%其中+2幅值是为了保证(实际采集到的)输入信号始终为正
subplot(2,2,1); plot(x);title('Inputs');
axis([0 SAMPLE_NODES 0 5]);
y = fft(x, SAMPLE_NODES); %对x进行fft变换
subplot(2,2,2); plot(abs(y));title('FFT');
axis([0 SAMPLE_NODES 0 80]);
for m=3:31 %对fft变换后的x进行滤波
y(m) = 0;
end
z = ifft(y, SAMPLE_NODES); %对滤波后的y进行IFFT
subplot(2,2,3); plot(abs(z));title('IFFT');
axis([0 SAMPLE_NODES 0 5]);
subplot(2,2,4);; plot(abs(y));title('IFFT-FFT');
axis([0 SAMPLE_NODES 0 80]);
在经过matlab仿真后,发现能达到预期滤波效果,动手!
在网上查阅各种资料,发现本科期间学过fft但是没怎么使用过,对FFT原理不太有印象了,恰好发现一篇神文:
https://zhuanlan.zhihu.com/p/19763358
对知识点进行了巩固哈哈哈哈
从而得到了以下FFT实现代码
头文件.h
/*
* DSP_2833x_FFT.h
*
* Created on: 2019年4月1日
* Author: ChenQingye
*/
/* 日期 实现功能
* 0327 实现FFT变换,能成功滤掉高频部分,但还需完善:IFFT变换,2k频率以内进行滤波
* Graph坐标轴值:x轴:X(n) = (fs/N)*n Y(n) = (N/2)*A A为初始幅值默认1024
* 0328 完善FFT功能,满足200kHZ采样频率采到80kHZ高频噪声。
* 0401 自己编写ifft程序,需优化代码
* 0402 使用256点的FFT时钟周期需310,048个时钟周期,总814,224时钟周期
* 使用128点的FFT需要103,892个时钟周期,总386,111时钟周期
* 使用64点的FFT需要69,980个时钟周期,总183,774时钟周期
* 使用32点的FFT需要83,462个时钟周期,总83,462时钟周期
*
*
*
* */
#ifndef DSP_2833X_FFT_H_
#define DSP_2833X_FFT_H_
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include"math.h"
#define SampleFreq 1000000 // 为滤去80k高频 需大于2*80k的采样频率
#define S1_Freq 20000 // 模拟的初始信号频率
#define S2_Freq 80000 // 高频开关噪声的频率
#define PI 3.1415926
#define SAMPLENUMBER 32 // 0-256个FFT样本点涵盖了一个低频信号0-FS的所有频率信息,FS是采样频率。
#define M log(SAMPLENUMBER)/log(2) // 变更FFT点数修改fft子程序方便的需要 2^8 = 256->M = 8;log(SAMPLENUMBER)/log(2)
void InitForFFT();
void FFT256(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);//新加x7
void FFT128(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);
void FFT64(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);//去掉x6
void FFT32(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);//去掉x5
void IFFT();
void FilterFFT();//实现FFT滤波器
void MakeFFTOut();
void MakeIFFTOut();
void CLearFFtData();
//void FFT(float dataR[SAMPLENUMBER],float dataI[SAMPLENUMBER]);
extern int16 INPUT[SAMPLENUMBER],FFTDATA[SAMPLENUMBER],IFFTDATA[SAMPLENUMBER];
extern float32 DATAR[SAMPLENUMBER],DATAI[SAMPLENUMBER];
extern float32 sin_tab[SAMPLENUMBER],cos_tab[SAMPLENUMBER];
#endif /* DSP_2833X_FFT_H_ */
实现代码
/*
* DSP_2833x_FFT.c
*
* Created on: 2019年4月3日
* Author: ChenQingye
*/
#include "DSP_2833x_FFT.h"
int16 INPUT[SAMPLENUMBER],FFTDATA[SAMPLENUMBER],IFFTDATA[SAMPLENUMBER];
float32 DATAR[SAMPLENUMBER],DATAI[SAMPLENUMBER];
float32 sin_tab[SAMPLENUMBER],cos_tab[SAMPLENUMBER];
void InitForFFT()//蝶形运算系数表计算
{
int16 i;
float32 wt1,wt2;
for ( i=0;i<SAMPLENUMBER;i++ )
{
// 生成蝶形运算需要的三角表
sin_tab[i]=sin(PI*2*i/SAMPLENUMBER);
cos_tab[i]=cos(PI*2*i/SAMPLENUMBER); // f = w/2pi =1hz
// 生成模拟信号
wt1=2*PI*i*S1_Freq;
wt1=wt1/SampleFreq;
wt2=2*PI*i*S2_Freq;
wt2=wt2/SampleFreq;
INPUT[i]=sin(wt1)*1024+0.2*cos(wt2)*1024+1024; //f = w/2pi = 3hz
}
//初始化输入数据以及清空输出数组
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR[i] = INPUT[i];
DATAI[i] = 0.0f;
FFTDATA[i] = 0.0f;
IFFTDATA[i] = 0.0f;
}
}
void FilterFFT()//实现FFT滤波器
{
int16 i = 0;
int16 upLimit,downLimit;
switch(SAMPLENUMBER)
{
case 32:
upLimit = 31;
downLimit = 3;
break;
case 64:
upLimit = 62;
downLimit = 4;
break;
case 128:
upLimit = 120;
downLimit = 9;
break;
case 256