Solved

C Preprocessor Macro not working as expected

Posted on 2008-10-23
4
291 Views
Last Modified: 2011-09-20
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
Comment
Question by:salukibob
  • 3
4 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 22786783
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
 
LVL 53

Accepted Solution

by:
Infinity08 earned 125 total points
ID: 22786890
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
 

Author Comment

by:salukibob
ID: 22787514
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22788233
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now