|
|
View previous topic :: View next topic |
Author |
Message |
chimcanhcut
Joined: 17 Nov 2015 Posts: 1
|
Problem with FFT |
Posted: Tue Nov 17, 2015 9:25 pm |
|
|
I'm working with FFT code on PIC 18F46K20
this is my code
Code: |
include<18f46k20.h>
#device *=16
#device adc = 10
#use delay(crystal = 20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include<math.h>
const unsigned int N = 36; //N points Fast Fourier Transform (FFT)
const unsigned int L = 6, M = 6; //row - column
typedef struct
{
float32 re; //Phan thuc
float32 im; //Phan ao
}Complex;
Complex adcValue[N];
Complex ComplexMulti(Complex comp1, Complex comp2)
{
Complex result;
result.re = comp1.re*comp2.re - comp1.im*comp2.im;
result.im = comp1.re*comp2.im + comp2.re*comp1.im;
return result;
}
Complex Wkn(unsigned int k, unsigned n, unsigned int _N)
{
Complex result;
result.re = cos(2*PI*k*n/_N);
result.im = -sin(2*PI*k*n/_N);
return result;
}
void DFT(Complex* out, Complex* in, unsigned int _N)
{
unsigned int k;
unsigned int n;
for (k = 0; k < _N; k++)
{
out[k].re = 0;
out[k].im = 0;
for (n = 0; n < _N; n++)
{
out[k].re += ComplexMulti(in[n], Wkn(k, n, _N)).re;
out[k].im += ComplexMulti(in[n], Wkn(k, n, _N)).im;
}
}
}
void FFT(Complex *fftOutput,Complex* data)
{
Complex _tempArray[N];
for (unsigned int _l = 0; _l < L; _l++)
{
//DFT
Complex input[M], output[M]; //cac tham so dau ra va dau ra
for (unsigned int _m = 0; _m < M; _m++)
{
input[_m].re = data[_m*L + _l].re;
input[_m].im = data[_m*L + _l].im;
}
//M points DFT
DFT(output, input, M);
for (unsigned int _q = 0; _q < M; _q++)
{
_tempArray[_q*L+_l] = ComplexMulti(Wkn(_l, _q, N), output[_q]);
}
//Finish the first time DFT
}
//Second time DFT
for (unsigned int _q = 0; _q < M; _q++)
{
Complex input[L], output[L];
for (unsigned int _l = 0; _l < L; _l++)
{
input[_l].re = _tempArray[_l + _q*L].re;
input[_l].im = _tempArray[_l + _q*L].im;
}
DFT(output, input, L);
for (unsigned int _p = 0; _p < L; _p++)
{
_tempArray[_p + _q*L].re = output[_p].re;
_tempArray[_p + _q*L].im = output[_p].im;
}
}
for (int _p = 0; _p < L; _p++)
{
for (int _q = 0; _q < M; _q++)
{
fftOutput[M*_p + _q].re = _tempArray[_p + _q*L].re;
fftOutput[M*_p + _q].im = _tempArray[_p + _q*L].im;
}
}
}
void data_ampli(Complex *data, int length)
{
float32 ampli;
for (int i = 0; i < length/2; i++)
{
ampli = sqrt(data[i].re*data[i].re + data[i].im*data[i].im);
printf("%2d %7.2f\n",i, ampli);
}
}
void main()
{
disable_interrupts(GLOBAL);
for (unsigned int i = 0; i < N; i++)
{
if(i%2==0)
adcValue[i].re = 1;
else adcValue[i].re = 0;
adcvalue[i].im = 0;
}
Complex _fft[N];
while(true)
{
FFT(_fft, adcValue);
data_ampli(_fft,N);
delay_ms(1000);
}
}
|
When I run this code on PIC18F and PC, I had a same result when N<30, but it become 2 different results when N> 30.
I think i had a problem with complex struct or float type. And I try to display a float value through RS232.
Code: |
float xy = 102045020.23321;
printf("%f\n",xy);
|
and result is 16145674.24.
Where I went wrong? Sorry, my english is not very good. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19484
|
|
Posted: Wed Nov 18, 2015 2:21 am |
|
|
What compiler version?.
There is a generic problem with several CCS versions, if you use an 'unlimited' size in printf.
If you use printf("%7f\n",xy);
or some similar limited size, it may well start working.
It's going to be very different anyway, since a 32bit float only gives about 6.5 digits of accuracy. It should give 102045020 The .23321 won't even exist.
The same may be the reason for your difference once the term count goes up. The 'odds' are that you are using 64bit float on the PC, so millions of times more accuracy (About 536million times. 52bit mantissa versus 23bit). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|