[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] What Happened to the sbi() and cbi() Macros????
From: |
Arthur Goldhammer |
Subject: |
Re: [avr-gcc-list] What Happened to the sbi() and cbi() Macros???? |
Date: |
Fri, 4 Feb 2005 10:08:54 -0500 |
I have to marvel at how long this rather futile debate has raged on. The
issue involves two one-line macros, after all. Those who wish to pursue C
expertise beyond the (hardly arcane) &=~ and |= constructs might want to
consider how the job is done outside the world of AVRs. I also work with the
Renesas M16C series of microcontrollers. Here's an excerpt from the standard
header file provided with the free toolchain supplied by Renesas. Bit fields
and unions are used to provide access to single bits in special function
registers. To the objection that it's inefficient to set/clear
non-contiguous bits by this method, the response, as Ned Konz noted in
describing his rather similar code, is that byte access is also provided by
the use of a union. I have no trouble adapting to this style when I program
the M16C, and no trouble switching back to |= when programming the AVR.
Here's the Renesas code (excerpted to show just one of many SFRs and one set
of mnemonic bit names):
#pragma ADDRESS p0_addr 03e0H /* Port P0 register */
....
/********************************************************
* declare SFR bit *
********************************************************/
struct bit_def {
char b0:1;
char b1:1;
char b2:1;
char b3:1;
char b4:1;
char b5:1;
char b6:1;
char b7:1;
};
union byte_def{
struct bit_def bit;
char byte;
};
......
/*------------------------------------------------------
Port P0 register
------------------------------------------------------*/
union byte_def p0_addr;
#define p0 p0_addr.byte
#define p0_0 p0_addr.bit.b0 /* Port P0_0 register */
#define p0_1 p0_addr.bit.b1 /* Port P0_1 register */
#define p0_2 p0_addr.bit.b2 /* Port P0_2 register */
#define p0_3 p0_addr.bit.b3 /* Port P0_3 register */
#define p0_4 p0_addr.bit.b4 /* Port P0_4 register */
#define p0_5 p0_addr.bit.b5 /* Port P0_5 register */
#define p0_6 p0_addr.bit.b6 /* Port P0_6 register */
#define p0_7 p0_addr.bit.b7 /* Port P0_7 register */
/*------------------------------------------------------
So, if you want to set bit 7 of port 0, it's
p0_7 = 1;
Makes for easy reading. Whether the compiler can generate efficient code for
this depends on the compiler, I suppose.
Art