Difference between clear/set bit macros

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

What would be the difference between:

#define set_bit(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define clear_bit(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

and

#define set_bit(sfr, bit) ( sfr |= _BV( bit ) )
#define clear_bit(x, bit) ( sfr &= _BV( ~bit  ) )

What does the SFR_BYTE macro do? Anyone know?

Building my dreams!

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

bigpilot wrote:

#define clear_bit(x, bit) ( sfr &= _BV( ~bit ) )

This won't work. _BV(X) is probably implemented as 1<<X and 1<<~X does not make any sense.

The SFR_BYTE macro casts sfr to a volatile uint8_t memory pointer. See ./avr/include/avr/sfr_defs.h

/R

Last Edited: Thu. Jul 23, 2009 - 03:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The definition of _SFR_BYTE() is in sfr_defs.h as:

#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr))

where:

#define _SFR_ADDR(sfr) _SFR_MEM_ADDR(sfr)

and

#define _SFR_MEM_ADDR(sfr) ((uint16_t) &(sfr))

also

#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

If you use -E (possibly "make file.i") on your two examples you see this as for the two definitions of set_bit(PORTB, 3):

 ((*(volatile uint8_t *)(((uint16_t) &((*(volatile uint8_t *)((0x18) + 0x20)))))) |= (1 << (3)));

 ( (*(volatile uint8_t *)((0x18) + 0x20)) |= (1 << (3)) );

Cliff

PS Why you don't just use:

PORTB |= (1<<3);

I don't know? What use is "set_bit()" ?

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

I guess to set a certain bit.

Building my dreams!

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

Quote:

I guess to set a certain bit.

Three years late but an interesting comment none the less ;-)

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

clawson wrote:
Three years late but an interesting comment none the less

It is not a comment.
It is an answer to your question:
clawson on 23 jul 2009 wrote:
I don't know? What use is "set_bit()" ?

:D

No RSTDISBL, no fun!