Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 334
  • Last Modified:

C Preprocessor Macro not working as expected

Hi There,

In my code below, i'm trying to write a few macros that will automatically calculate a timer value for using in a PIC microcontroller project. Basically, you just set the oscillator frequency, and the macro should calculate the value to load into the timer for a 10us delay. I have defined 6 macros for this: FOSC, FCY, F_10us, DELAY_10us_0, ROUND_FIX_10us and DELAY_10us. The value for DELAY_10us_0 is rounded down, so I calculate whether the real divide would be closer to a round-up, and if so, add 1 to the delay value. This gives the nearest approximation to 10us delay.

This all works fine, and as expected, except for the last macro.  When I add DELAY_10us_0 to ROUND_FIX_10us, the answer is always just ROUND_FIX_10us (either 0 or 1). No addition takes place as far as I can see. I believe I am probably missing something in how the preprocessor is actually calculating these values, so any clarification would be very helpful.

Thanks for any help
Rob Smith
/*****************************/
/* define the clock settings */
/*****************************/
#define FOSC	1600000L		// Oscillator Frequency
#define FCY	FOSC/4		// Instruction Clock Frequency
 
 
/**********************/
/* Delay calculations */
/**********************/
// 10us
#define F_10us		100000L		// For 10us, freq will be 100KHz
#define DELAY_10us_0	FCY/F_10us	// The number of instructions that go into 10us (Rounded-Down)
#define ROUND_FIX_10us	(FCY - (DELAY_10us_0 * F_10us)) > (F_10us/2) ? 1:0
#define DELAY_10us 	DELAY_10us_0 + ROUND_FIX_10us

Open in new window

0
salukibob
Asked:
salukibob
  • 3
1 Solution
 
Infinity08Commented:
First of all, you need to add a lot more ()'s. Macro's are expanded in-line, and that might change the meaning due to operator precedence.
/*****************************/
/* define the clock settings */
/*****************************/
#define FOSC    1600000L                // Oscillator Frequency
#define FCY     (FOSC / 4)          // Instruction Clock Frequency
 
 
/**********************/
/* Delay calculations */
/**********************/
// 10us
#define F_10us          100000L         // For 10us, freq will be 100KHz
#define DELAY_10us_0    (FCY / F_10us)      // The number of instructions that go into 10us (Rounded-Down)
#define ROUND_FIX_10us  (((FCY - (DELAY_10us_0 * F_10us)) > (F_10us / 2)) ? 1 : 0)
#define DELAY_10us      (DELAY_10us_0 + ROUND_FIX_10us)

Open in new window

0
 
Infinity08Commented:
With these added ()'s, your DELAY_10us is expanded like this :

        (((1600000L / 4) / 100000L) + ((((1600000L / 4) - (((1600000L / 4) / 100000L) * 100000L)) > (100000L / 2)) ? 1 : 0))

which is equal to :

        4

instead of what your code expanded to :

        1600000L/4/100000L + (1600000L/4 - (1600000L/4/100000L * 100000L)) > (100000L/2) ? 1:0

which is equal to :

        1
0
 
salukibobAuthor Commented:
Ok, thanks very much for the advice. I was aware you had to do that when passing in variables to macros, but not when using other macros. I suppose its the same though when expanded out as you've pointed out.

Thanks very much
Rob Smith
0
 
Infinity08Commented:
Yes, in this specific case, the + has higher precedence than the >, so :

        a + b > c ? d : e

is the same as :

        ((a + b) > c) ? d : e

not the intended :

        a + ((b > c) ? d : e)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now