problem with simple macro

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I have defined the following macro:

#define ADC_REF_AVCC() \
ADMUX &= ~(1 << REFS1); \
ADMUX |= (1 << REFS0) //Analogue Vcc as ref

ADC_REF_AVCC();

When I call this it sets both the bits (REFS1 & 0).

ADMUX &= ~(1 << REFS1);
ADMUX |= (1 << REFS0);

However, if I include the 2 lines directly in my code (like the above) it clears the REFS1 bit and set the REFS0 bit like it should.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you've got trouble with the preprocessor, it's usually best
to manually review the preprocessed source code. The
conventional filename suffix for it is .i, and in the most recent
WinAVR Makefile template, there's a generic transition rule
to produ

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

try putting the macro between { } just like you do in normal functions

Experience is what causes people to make new mistakes instead of old ones...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

johannkok wrote:
Hi,
I have defined the following macro:

#define ADC_REF_AVCC() \
ADMUX &= ~(1 << REFS1); \
ADMUX |= (1 << REFS0) //Analogue Vcc as ref

ADC_REF_AVCC();

When I call this it sets both the bits (REFS1 & 0).

ADMUX &= ~(1 << REFS1);
ADMUX |= (1 << REFS0);

However, if I include the 2 lines directly in my code (like the above) it clears the REFS1 bit and set the REFS0 bit like it should.

Another way to do it, is to combine them in one line of C:

ADMUX = (ADMUX & ~(1 << REFS1)) | (1 << REFS0);

You can then create a macro the expands to the line above.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did try the one-line thing but that made no difference. I will try the braces thing and will let you know.

Jorg, I think the last part of you're text was cut off. I see no .i files, but I must say that I'm still using the previous winavr. After my VERY bad experiences with Atmel's upgrades (even SP2) I'm afraid to upgrade anything! I know winavr is different and there's some quality control.

regards

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

johannkok wrote:
I did try the one-line thing but that made no difference.

I have doubts. Can you show how you implemented it and the compiled assembly?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

johannkok wrote:
I did try the one-line thing but that made no difference

Hi

It's strange.
I simply copied your code ( atmega8) and got

 ADC_REF_AVCC();
  f6:	3f 98       	cbi	0x07, 7	; 7
  f8:	3e 9a       	sbi	0x07, 6	; 7

BTW there's a trick which allows not to remember
about last semicolon ( from preprocessor manual )

#define  MYMACRO \
 do \
  { \
  command1; \
  command2; \
  ...
  commandN; \
  } \
 while(0)

Then every commandX line ends with ; as usual
but it's also always safe to write MYMACRO; (with ; )

Best regards Jurek S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi people, sorry for taking so long before getting back to this post - had to do hardware design for the past 2 weeks.

Just to close the matter - I solved my problem by putting the macro contents in braces { }. I didn't inspect the preprocessor output because I see no .i files and I'm so pressed for time at the moment.

Thanks for everyone's help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> I didn't inspect the preprocessor output because I see no .i files
> and I'm so pressed for time at the moment.

You need to generate them manually. I think the latest WinAVR has an
inference rule for it, so for file "foo.c", you can type "make foo.i"
to get it.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JerzySzczesiul wrote:

BTW there's a trick which allows not to remember
about last semicolon ( from preprocessor manual )

#define  MYMACRO \
 do \
  { \
  ...
  } \
 while(0)


IMHO this trick has also another very important advantage.
If you try to use macro in wrong place then it will cause compiler errors.
E.g. it didn't allow to use macro with assignement or comparison operators.

Another gain is possible when you must be conforming to MISRA rules but it is OT.

Regards,