|
|
View previous topic :: View next topic |
Author |
Message |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
CCS C Conversion Help |
Posted: Tue Feb 14, 2006 8:32 am |
|
|
Hello all,
I've been trying to convert a couple of pieces of code available on the web for DFTs and have been having problems because of my limited knowledge of C. One of the pices of code is below with the original code in comments then my code, and my questions within the code near the areas that are troubling me. Any help would be greatly appreciated, as I'm on day two with little progress and my ICD-U40 just went south...
Here is the link to the article with the original code:
http://www.elecdesign.com/Articles/Index.cfm?AD=1&ArticleID=5575
The general:
3.236
18F4620
I'm reading 8bit values from the ADC of a clean sine wave @105hz. So values are from 10 to about 240. When I try to use the code I get some negative results for the DFTs. I think I have a problem when I've modified the code from it's original form.... Problems seem to be variable scope, pointers, data types, etc. THis is not the code in it's entirety, but the troublesome part.
Code: |
/*
hrft
A C Program For Spectrum Magnification: When The FFT Is Not Enough
Version 1.0
March 27, 2003
by
Stefan Hollos, stefan@exstrom.com
Richard Hollos, richard@exstrom.com
Exstrom Laboratories LLC
P.O. Box 7651
Longmont, CO 80501
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
/*
Calculates the Fourier transform over Nf points from
frequency
f1 to frequency f2, of N (N>1) samples of a signal taken at
sps samples per second. The values of cos(n*Omega) &
sin(n*Omega)
are calculated using Chebyshev polynomials.
*/
//void hrft( int N, double *q, double Omega, double *Qr, double *Qi )
//Why if N and Omega are defined in MAIN are they passed to the
//function? Aren't they available for GLOBAL use anyway?
//Also, if I define the array "q" do I need to pass "q" to the function?
//I've tried with and without.
void hrft( int L_N, FLOAT *q, FLOAT L_Omega, FLOAT *Qr, FLOAT *Qi )
{
int n;
//double C0, S0; /* cos(Omega) & sin(Omega) */
//double T0, T1, T2; /* Type I Chebyshev polynomials */
//double U0, U1, U2; /* Type II Chebyshev polynomials */
//double Cn, Sn; /* cos(n*Omega) & sin(n*Omega) */
FLOAT C0, S0; /* cos(Omega) & sin(Omega) */
FLOAT T0, T1, T2; /* Type I Chebyshev polynomials */
FLOAT U0, U1, U2; /* Type II Chebyshev polynomials */
FLOAT Cn, Sn; /* cos(n*Omega) & sin(n*Omega) */
C0 = cos(L_Omega);
S0 = sin(L_Omega);
T0 = 1.0;
T1 = C0;
U0 = 1.0;
U1 = 2.0*C0;
/* this takes care of n = 0,1 */
*Qr = q[0] + q[1]*T1;
*Qi = q[1]*S0*U0;
//I added this for debugging and got compilation errors
//Only way it will compile is with format %u
//Aren't Qr and Qi FLOATS?
printf("%f %f\n\r", Qr, Qi);
C0 *= 2.0;
for( n = 2; n < L_N; ++n )
{
T2 = C0*T1 - T0;
T0 = T1;
T1 = T2;
U2 = C0*U1 - U0;
U0 = U1;
U1 = U2;
Cn = T2;
Sn = S0*U0;
*Qr += q[n]*Cn;
*Qi += q[n]*Sn;
} /* end for n */
} /* end function hrft */
/****************************************************/
int main()
{
double f1, f2;
int Nf;
double df;
//int N;
int N = 64;
//int i, n;
//n is declared locally in the function
int i;
//double sps;
//double Omega;
//double dOmega;
//double *q;
//double Qr, Qi;
FLOAT sps;
FLOAT Omega;
FLOAT dOmega;
//Big problems here....
//I don't want to use malloc, so I just define the array
FLOAT q[64]; //I store my ADC values here for processing
FLOAT Qr, Qi;
/* allocate a double array of size N */
//Don't use this.....
//q = (double *)malloc( N * sizeof(double) );
df = (f2-f1)/((FLOAT)(Nf-1));
//Omega = 2.0 * M_PI * f1 / sps;
//dOmega = 2.0 * M_PI * df / sps;
Omega = 2.0 * 3.1415927 * f1 / sps;
dOmega = 2.0 * 3.1415927 * df / sps;
for( i = 0; i < Nf; ++i )
{
hrft( N, q, Omega, &Qr, &Qi );
fprintf( fp, "%lf %lf\n", Qr, Qi );
Omega += dOmega;
} /* end for i */
}
|
So, to recap my confusion.... The inability to use the printf statement on the FLOATs or the values I THINK are floats, baffles me. To avoid using "malloc" have I done the conversion correctly? Why are global variables passed to the function?
Thanks,
John
EDIT:
BTW, here is some more kind of bizarre results. When I add the following code the printf code works as expected.
Code: |
FLOAT test1;
FLOAT test2;
test1 = q[0] + q[1]*T1;
test2 = q[1]*S0*U0;
printf("Qr=%f Qi=%f\n\r", test1, test2);
|
|
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 14, 2006 9:13 am |
|
|
No. Qr, and Qi, are _not_ floats. They are _pointers_ to floats.
*Qr, is the float _pointed to_, by Qr.
Use:
printf("%f %f\n\r", *Qr, *Qi);
Best Wishes |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Feb 14, 2006 9:22 am |
|
|
Thanks RJ,
I just looked at "Absolute Beginner's Guide to C" and just figured that out. I was in the process of changing that around.
Any ideas on the declaration of the array and how it gets passed to the function?
Thanks guys,
John |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 14, 2006 10:06 am |
|
|
I don't quite understand the other part of your question. You declare an array 'q[64]'. Now in C, there is a 'shorthand', that the name of an array, is it's address. So the address of this gets passed to the function.
Now 'q', is not a global array. It is a local array to _main_. You could declare it as 'global', by declaring it outside main, and then you would not need to pass it's address to the function, but could access it directly. For the single array, this might well be easier.
Best Wishes |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Feb 14, 2006 12:39 pm |
|
|
Made that change to the declaration of the array and modified the function and the call appropriately.
Started a methodical verification of the math and discovered PIC has a hard time with the sin and cos calcs, as I expected. I'm going to move to a lookup table and continue on with the "math validation".
Thanks again for the help,
John |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Feb 14, 2006 12:59 pm |
|
|
Disregard the last post. My cheapy scientific calculator was giving me bad numbers. I'll stick to my TI-89 from now on.....
PIC calcs were real good. |
|
|
|
|
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
|