3167 views|0 replies

3836

Posts

19

Resources
The OP
 

DSP28335 implements high frequency filtering through FFT transformation [Copy link]

This post was last edited by fish001 on 2019-11-5 21:17

Since the high-frequency switching noise collected by AD is large, it greatly interferes with data processing. After measuring with an oscilloscope, it is found that the noise frequency is mainly concentrated at 80kHz. I seek help from the teacher, who recommends using FFT filtering. Some students use FIR filtering and obtain parameters through the FDA tool built into Matlab. The effect declines when the noise amplitude is greater than 0.6V. I use FFT filtering. Due to limited online information, the Internet recommends using filters such as FIR filtering directly. FFT filtering may have some problems, but for this project, I still think I should try FFT filtering to see how it works.
First, use Matlab for simulation. The code is as follows

SampleFreq = 800000; % To filter out the 80k high frequency, the sampling frequency must be greater than 2*80k
S1_Freq = 20000; % The initial signal frequency of the simulation
S2_Freq = 80000; % The frequency of the high-frequency switching noise
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; %Get 20KHz fundamental wave + 80KHz harmonic signal,
%where the +2 amplitude is to ensure that the (actually collected) input signal is always positive

subplot(2,2,1); plot(x);title('Inputs');
axis([0 SAMPLE_NODES 0 5]);


y = fft(x, SAMPLE_NODES); %Perform fft transformation on x
subplot(2,2,2); plot(abs(y)); title('FFT');


axis([0 SAMPLE_NODES 0 80]);

for m=3:31 %Filter x after fft transformation
y(m) = 0;
end

z = ifft(y, SAMPLE_NODES); %Perform IFFT on filtered y
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]);

This resulted in the following FFT implementation code
Header file .h

/*
* DSP_2833x_FFT.h
*
* Created on: April 1, 2019
* Author: ChenQingye
*/
/* Date Implementation function
* 0327 Implement FFT transformation, which can successfully filter out the high-frequency part, but still needs to be improved: IFFT transformation, filtering within 2k frequency
* Graph coordinate axis values: x-axis: X(n) = (fs/N)*n Y(n) = (N/2)*A A is the initial amplitude, the default is 1024
* 0328 Improve the FFT function to meet the 200kHZ sampling frequency and sample 80kHZ high-frequency noise.
* 0401 Write your own ifft program and optimize the code
* 0402 Using 256-point FFT requires 310,048 clock cycles, a total of 814,224 clock cycles
* Using 128-point FFT requires 103,892 clock cycles, a total of 386,111 clock cycles
* Using 64-point FFT requires 69,980 clock cycles, a total of 183,774 clock cycles
* Using 32-point FFT requires 83,462 clock cycles, a total of 83,462 clock cycles
*
*
*
* */
#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 // To filter out the 80k high frequency, a sampling frequency greater than 2*80k is required
#define S1_Freq 20000 // Initial signal frequency of simulation
#define S2_Freq 80000 // Frequency of high-frequency switching noise
#define PI 3.1415926
#define SAMPLENUMBER 32 // 0-256 FFT sample points cover all frequency information of a low-frequency signal 0-FS, FS is the sampling frequency.
#define M log(SAMPLENUMBER)/log(2) // Change the number of FFT points to modify the fft subroutine for convenience 2^8 = 256->M = 8;log(SAMPLENUMBER)/log(2)

void InitForFFT();
void FFT256(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);//Newly added x7
void FFT128(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);
void FFT64(float32 dataR[SAMPLENUMBER] ,float32 dataI[SAMPLENUMBER]);//Remove x6
void FFT32(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]);//Remove x5
void IFFT();
void FilterFFT();//Implement FFT filter
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_ */


Implementation Code

/*
* DSP_2833x_FFT.c
*
* Created on: April 3, 2019
* 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()//Butterfly operation coefficient table calculation
{
int16 i;

float32 wt1,wt2;


for ( i=0;i<SAMPLENUMBER;i++ )
{
// Generate the triangular table required for butterfly operation
sin_tab =sin(PI*2*i/SAMPLENUMBER);
cos_tab =cos(PI*2*i/SAMPLENUMBER); // f = w/2pi =1hz

// Generate analog signal
wt1=2*PI*i*S1_Freq;
wt1=wt1/SampleFreq;

wt2=2*PI*i*S2_Freq;
wt2=wt2/SampleFreq;

INPUT =sin(wt1)*1024+0.2*cos(wt2)*1024+1024; //f = w/2pi = 3hz
}
//Initialize input data and clear output array
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR = INPUT ;
DATAI = 0.0f;
FFTDATA = 0.0f;
IFFTDATA = 0.0f;
}
}

void FilterFFT()//Implement FFT filter
{
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:
upLimit = 240;
downLimit = 12;
break;
default:
break;
}

for(i = downLimit;i < upLimit;i++)//100kHZ sampling 256 points
{
DATAR = 0;
DATAI = 0;
}
}
void IFFT()
{
int16 k = 0;

for (k=0; k<=SAMPLENUMBER-1; k++) {
DATAI[k] = -DATAI[k];
}

switch(SAMPLENUMBER)
{
case 32:
FFT32(DATAR,DATAI);
break;
case 64:
FFT64(DATAR,DATAI);
break;
case 128:
FFT128(DATAR,DATAI);
break;
case 256:
FFT256(DATAR,DATAI) ;
break;
default:
break;
}
//
// if(SAMPLENUMBER == 256)/* using FFT */
// FFT256(DATAR,DATAI);
// else if(SAMPLENUMBER == 128)
// FFT128(DATAR, DATAI);
// else if(SAMPLENUMBER == 64)
// FFT64(DATAR,DATAI);
// else if(SAMPLENUMBER == 32)
// FFT32(DATAR,DATAI);

for (k=0; k<=SAMPLENUMBER-1; k++) {
DATAR[k] = DATAR[k] / SAMPLENUMBER;
DATAI[k] = -DATAI[k] / SAMPLENUMBER;
}

}
void MakeFFTOut()
{
Uint16 i;
for ( i=0;i<SAMPLENUMBER;i++ )
{
FFTDATA =sqrt(DATAR *DATAR +DATAI *DATAI );
}
}

void MakeIFFTOut()
{
Uint16 i;
for ( i=0;i<SAMPLENUMBER;i++ )
{
IFFTDATA =sqrt(DATAR *DATAR +DATAI *DATAI );
}
}


void FFT256(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER])//Add x7 310,048 clock cycles
{
int16 x0,x1,x2,x3,x4,x5,x6,xx,x7;//x7
int16 i,j,k,b,p,L;
float32 TR,TI,temp;

/********** following code invert sequence ************/
for ( i=0;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4 =x5=x6=0;
x0=i&0x01; x1=(i/2)&0x01; x2=(i/4)&0x01; x3=(i/8)&0x01; i/32
) &0x01; *4+x6*2+x7;
dataI[xx]=dataR ;
}
for ( i=0;i<SAMPLENUMBER;i++ )
{
dataR =dataI ; dataI =0;
}

/**************** following code FFT *******************/
for ( L=1;L<=M;L++ )
{ /* for(1) */
b=1; i=L-1;
while ( i>0 )
{
b=b*2; i--;
} /* b= 2^(L-1) * /
for ( j=0;j<=b-1;j++ ) /* for (2) */
{
p=1; i=ML;
while ( i>0 ) /* p=pow(2,ML)* j; */
{
p=p*2; i--;
}
p=p*j;
for ( k=j;k<SAMPLENUMBER;k=k+2*b ) /* for (3) */
{
TR =dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b] *sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p] ;
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR = dataR ;
DATAI = dataI ;
}
} /* END FFT */

void FFT128(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]) //103,892 clock cycles
{
int16 x0,x1,x2,x3,x4,x5,x6,xx;
int16 i,j,k,b,p,L;
float32 TR,TI,temp;

/********** following code invert sequence ************/
for ( i=0;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4 =x5=x6=0;
x0=i&0x01; x1=(i/2)&0x01; x2=(i/4)&0x01; x3=(i/8)&0x01; i/32) & 0x01
; } for ( i=0;i<SAMPLENUMBER;i++ ) { dataR =dataI ; dataI =0; }





/**************** following code FFT *******************/
for ( L=1;L<=M;L++ )
{ /* for(1) */
b=1; i=L-1;
while ( i>0 )
{
b=b*2; i--;
} /* b= 2^(L-1) * /
for ( j=0;j<=b-1;j++ ) /* for (2) */
{
p=1; i=ML;
while ( i>0 ) /* p=pow(2,7-L )*j; */
{
p=p*2; i--;
}
p=p*j;
for ( k=j;k<SAMPLENUMBER;k=k+2*b ) /* for (3) */
{
TR=dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b] *sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p] ;
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR = dataR ;
DATAI = dataI ;
}
} /* END FFT */

void FFT64(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]) //103,892 clock cycles
{
int16 x0,x1,x2,x3,x4,x5,xx;
int16 i,j,k,b,p,L;
float32 TR,TI,temp;

/********** following code invert sequence ************/
for ( i=0;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4 =x5=0;
x0=i&0x01; x1=(i/2)&0x01; x2=(i/4)&0x01; x3=(i/8)&0x01; 32)&0x01;
xx=x0*32+x1*16+x2*8+x3*4+x4*2+x5;
dataI[xx]=dataR ;
}
for ( i=0;i<SAMPLENUMBER;i++ )
{
dataR =dataI ; dataI =0;
}

/**************** following code FFT *******************/
for ( L=1;L<=M;L++ )
{ /* for(1) */
b=1; i=L-1;
while ( i>0 )
{
b=b*2; i--;
} /* b= 2^(L-1) * /
for ( j=0;j<=b-1;j++ ) /* for (2) */
{
p=1; i=ML;
while ( i>0 ) /* p=pow(2,7-L )*j; */
{
p=p*2; i--;
}
p=p*j;
for ( k=j;k<SAMPLENUMBER;k=k+2*b ) /* for (3) */
{
TR=dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b] *sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p] ;
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR = dataR ;
DATAI = dataI ;
}
} /* END FFT */

void FFT32(float32 dataR[SAMPLENUMBER],float32 dataI[SAMPLENUMBER]) //103,892 clock cycles
{
int16 x0,x1,x2,x3,x4,xx;
int16 i,j,k,b,p,L;
float32 TR,TI,temp;

/********** following code invert sequence ************/
for ( i=0;i<SAMPLENUMBER;i++ )
{
x0=x1=x2=x3=x4 =0;
x0=i&0x01; x1=(i/2)&0x01; x2=(i/4)&0x01; x3=(i/8)&0x01
; *8+x2*4+x3*2+x4;
dataI[xx]=dataR ;
}
for ( i=0;i<SAMPLENUMBER;i++ )
{
dataR =dataI ; dataI =0;
}

/**************** following code FFT *******************/
for ( L=1;L<=M;L++ )
{ /* for(1) */
b=1; i=L-1;
while ( i>0 )
{
b=b*2; i--;
} /* b= 2^(L-1) * /
for ( j=0;j<=b-1;j++ ) /* for (2) */
{
p=1; i=ML;
while ( i>0 ) /* p=pow(2,7-L )*j; */
{
p=p*2; i--;
}
p=p*j;
for ( k=j;k<SAMPLENUMBER;k=k+2*b ) /* for (3) */
{
TR=dataR[k]; TI=dataI[k]; temp=dataR[k+b];
dataR[k]=dataR[k]+dataR[k+b]*cos_tab[p]+dataI[k+b]*sin_tab[p];
dataI[k]=dataI[k]-dataR[k+b] *sin_tab[p]+dataI[k+b]*cos_tab[p];
dataR[k+b]=TR-dataR[k+b]*cos_tab[p]-dataI[k+b]*sin_tab[p] ;
dataI[k+b]=TI+temp*sin_tab[p]-dataI[k+b]*cos_tab[p];
} /* END for (3) */
} /* END for (2) */
} /* END for (1) */
for ( i=0;i<SAMPLENUMBER;i++ )
{
DATAR = dataR ;
DATAI = dataI ;
}
} /* END FFT */


Finally, 800KHz sampling frequency and 32 points are used. Due to the limited speed of PID adjustment in the project, 32 points can meet the filtering requirements. Theoretically, the more points there are, the better the filtering effect is. 800KHz/32 points = 25kHz, which means that frequencies below 25KHz cannot be filtered out, and frequencies below 50KHz in 1.6MHz cannot be filtered out, which leads to poor filtering effect.

This post is from DSP and ARM Processors
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list