From: Robby on
Hello,

This question is geared more towards seeking a voice of programming
experience.

I am running into a situation where I need some advice on how to do things.
Perhaps I am seeing this the wrong way. In summary, from main(), I would like
to call a defined macro called "Config_delay_timers", and in that macro I
would like to do some calculations where the result can be assigned to the
value of another #define statement.

Please view the following code:
==========================main.h

#ifndef TEST_H
#define TEST_H

// *** SYSTEM OSCILLATION *** //
#define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

#define CURR_SYS_OSC FREQ
#define OSC_PERIOD (1.0/CURR_SYS_OSC)

#endif // TEST_H //

=====================================main.c
#include <stdio.h>
#include "test.h"

int main()
{

Config_delay_timers(8, 2, 21, 8);
//SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);

return 0;
}
===================================

I am getting an error where the compiler complains about FREQ is undefclared.
So how is one supposed to carry out a particular calculation via a define
macro and then further assign this result to other define variables in the
program.

I am thinking of mayby using #ifdef preprocessor command but I don't see how
this would be of any use in this particular case.

All help or reccomendations is very welcome and apprciated. Thanks in advance!

--
Best regards
Roberto
From: Bo Persson on
Robby wrote:
> Hello,
>
> This question is geared more towards seeking a voice of programming
> experience.
>
> I am running into a situation where I need some advice on how to do
> things. Perhaps I am seeing this the wrong way. In summary, from
> main(), I would like to call a defined macro called
> "Config_delay_timers", and in that macro I would like to do some
> calculations where the result can be assigned to the value of
> another #define statement.
>
> Please view the following code:
> ==========================main.h
>
> #ifndef TEST_H
> #define TEST_H
>
> // *** SYSTEM OSCILLATION *** //
> #define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
> FREQ =
> (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
>
> #define CURR_SYS_OSC FREQ
> #define OSC_PERIOD (1.0/CURR_SYS_OSC)
>
> #endif // TEST_H //
>
> =====================================main.c
> #include <stdio.h>
> #include "test.h"
>
> int main()
> {
>
> Config_delay_timers(8, 2, 21, 8);
> //SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
>
> return 0;
> }
> ===================================
>
> I am getting an error where the compiler complains about FREQ is
> undefclared. So how is one supposed to carry out a particular
> calculation via a define macro and then further assign this result
> to other define variables in the program.

Macros don't do variables, they are just text processing.

>
> I am thinking of mayby using #ifdef preprocessor command but I
> don't see how this would be of any use in this particular case.
>
> All help or reccomendations is very welcome and apprciated. Thanks
> in advance!

If you want a constant value in the program, declare one:

const float FREQ = ...


Bo Persson


From: Igor Tandetnik on
Robby <Robby(a)discussions.microsoft.com> wrote:
> I am running into a situation where I need some advice on how to do
> things. Perhaps I am seeing this the wrong way. In summary, from
> main(), I would like to call a defined macro called
> "Config_delay_timers", and in that macro I would like to do some
> calculations where the result can be assigned to the value of another
> #define statement.

This makes no sense. Macros a just text substitutions, performed at compile time. If you want to calculate a value at run time, you need a variable for it.

> Please view the following code:
> ==========================main.h
>
> #ifndef TEST_H
> #define TEST_H
>
> // *** SYSTEM OSCILLATION *** //
> #define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
> FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
>
> #define CURR_SYS_OSC FREQ
> #define OSC_PERIOD (1.0/CURR_SYS_OSC)
>
> #endif // TEST_H //
>
> =====================================main.c
> #include <stdio.h>
> #include "test.h"
>
> int main()
> {
>
> Config_delay_timers(8, 2, 21, 8);
> //SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
>
> return 0;
> }

Well, since you are hardcoding all the constants anyway, why not something like this:

#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

If, on the other hand, you expect these values to change from run to run, then you need real functions to calculate them and real variables to store them.

> So how is one supposed to carry out a particular
> calculation via a define macro and then further assign this result to
> other define variables in the program.

One is not supposed to.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925

From: Robby on
Thank you fellows for your feedback!

--
Best regards
Roberto


"Igor Tandetnik" wrote:

> Robby <Robby(a)discussions.microsoft.com> wrote:
> > I am running into a situation where I need some advice on how to do
> > things. Perhaps I am seeing this the wrong way. In summary, from
> > main(), I would like to call a defined macro called
> > "Config_delay_timers", and in that macro I would like to do some
> > calculations where the result can be assigned to the value of another
> > #define statement.
>
> This makes no sense. Macros a just text substitutions, performed at compile time. If you want to calculate a value at run time, you need a variable for it.
>
> > Please view the following code:
> > ==========================main.h
> >
> > #ifndef TEST_H
> > #define TEST_H
> >
> > // *** SYSTEM OSCILLATION *** //
> > #define Config_delay_timers(extCrys, fpllidiv, fpllmul, fpllodiv) \
> > FREQ = (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
> >
> > #define CURR_SYS_OSC FREQ
> > #define OSC_PERIOD (1.0/CURR_SYS_OSC)
> >
> > #endif // TEST_H //
> >
> > =====================================main.c
> > #include <stdio.h>
> > #include "test.h"
> >
> > int main()
> > {
> >
> > Config_delay_timers(8, 2, 21, 8);
> > //SYSTEMConfig(CURR_SYS_OSC, SYS_CFG_ALL);
> >
> > return 0;
> > }
>
> Well, since you are hardcoding all the constants anyway, why not something like this:
>
> #define extCrys 8
> #define fpllidiv 2
> #define fpllmul 21
> #define fpllodiv 8
> #define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)
>
> If, on the other hand, you expect these values to change from run to run, then you need real functions to calculate them and real variables to store them.
>
> > So how is one supposed to carry out a particular
> > calculation via a define macro and then further assign this result to
> > other define variables in the program.
>
> One is not supposed to.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
>
> .
>
From: Robby on
"Igor Tandetnik" wrote:

> #define extCrys 8
> #define fpllidiv 2
> #define fpllmul 21
> #define fpllodiv 8
> #define FREQ (((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

"Igor Tandetnik" wrote:

Igor, one thing though, I am trying to create structures that hold only one
type of data which relates to one type of task in my code. Then I would like
to create functions that would manipulate the respective structure
accordingly. So for example, if I am setting up a #define statement to hold
the current system clock... like this:

#define extCrys 8
#define fpllidiv 2
#define fpllmul 21
#define fpllodiv 8
#define
CURR_SYS_OSC(((float)(extCrys/fpllidiv)*(float)(fpllmul/fpllodiv))*1000000)

I would rather create a structure holding this type of data. Then call a
function to manipulate it. I think!!! the way you described it above is sort
of a non OOP approach. Now, now, hold it right there.... don't think I am
saying that you don't know OOP! I know that you and many others here know OOP
and very well too. But what I am trying to reach for here is I would like to
get in the habit of starting to gear my code towards *some* oopness!!!

So what I am saying is, that, isn't there a better and more structured way
of doing... for example my CURR_SYS_OSC calculation.... perhaps creating an
API function which references that #define directive. Mind you, one thing
that doesn't help here is that I am a little confused as what is the
difference between an API call *and* a normal function call *and* when we
create an object and call a function passing a pointer to the object as a
parameter. I know I use them, but again, I am calling these functions without
good "OOP" reasoning.

So for my example, what if I do this, what do you think?
===================================KERNEL.h
#ifndef KERNEL_H
#define KERNEL_H

#define CURR_SYS_OSC (((float)(curr_sys_osc.extCrys/curr_sys_osc.fpllidiv)*
\
(float)(curr_sys_osc.fpllmul/curr_sys_osc.fpllodiv))*1000000)

// Note: OSC_PERIOD is used in other modules too !!!!!!!!
#define OSC_PERIOD (1.0/CURR_SYS_OSC)

typedef struct tag_osc_info
{
float extCrys;
float fpllidiv;
float fpllmul;
float fpllodiv;
}osc_info;

extern osc_info curr_sys_osc;

void compute_curr_sys_osc
(float extCrys, float fpllidiv, float fpllmul, float fpllodiv);

=======================================KERNEL.c
#include "KERNEL.h"
osc_info curr_sys_osc;

// The next line configures the on chip PLL. In anycase this is where I get
the values:
//Externel crystal= 8.0 and the rest: 2.0, 21.0, 8.0
#pragma config FPLLIDIV = DIV_2, FPLLMUL = MUL_21, FPLLODIV = DIV_8

int main(void)
{
compute_curr_sys_osc(8.0, 2.0, 21.0, 8.0);

//.... other code
}


void compute_curr_sys_osc
(float extCrys, float fpllidiv, float fpllmul, float fpllodiv)
{
curr_sys_osc.extCrys = extCrys;
curr_sys_osc.fpllidiv = fpllidiv;
curr_sys_osc.fpllmul = fpllmul;
curr_sys_osc.fpllodiv = fpllodiv;
}
=========================================
And remember I can't make CURR_SYS_OSC a macro, because, OSC_PERIOD needs
CURR_SYS_OSC as a value in its calculation!

Am I getting too complicated for nothing here, or is carrying out any small
calculation or logical process a good habit to do it via a function like I
have done above?

I could just keep on plugging and calling any function and macro anywhere I
can and as long as it compiles I would be able to continue, but I find I am
lacking structure with all of these #defines, #defined macros and functions.
For what reson should each one be specifically used for? For example, why use
defined macros, when we have functions. Inline functions... thats another
one???? Althought, I would like to know when to use what.

PS. I wouldn't want to know how to do everything right away, but what would
be the most appropriate way to do the innitial example of this post?

I sincerely thank you or anyone else for any advice or help in guiding me on
this subject!

Rob