Bit fiddling in ICCV7
Q*bert
Posts: 59
I have been writing some stuff in Imagecraft C lately and found myself fumbling around when
doing all the bit fiddling required when programming a microcontroller.
I remembered some macros I had found when i was doing AVR C programming, so I blew the
dust off of them and here they are!
// macros for bit fiddling in C (from AVR tech notes and AVRfreaks.com forum discussions)
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define SETBITMASK(x,y) (x |= (y))
#define CLEARBITMASK(x,y) (x &= (~y))
#define FLIPBITMASK(x,y) (x ^= (y))
#define CHECKBITMASK(x,y) (x & (y))
#define VARFROMCOMB(x, y) x
#define BITFROMCOMB(x, y) y
#define C_SETBIT(comb) SETBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CLEARBIT(comb) CLEARBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_FLIPBIT(comb) FLIPBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CHECKBIT(comb) CHECKBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
These can be really handy as you don't need to recall the bit logic over and over again.
The last four macros deserve an example to show how they can be used:
/******* C_ macros usage example *********/
#define Status_LED OUTA, 3
C_SETBIT(Status_LED);
C_CLEARBIT(Status_LED);
I hope these help someone simplify their C programming. I know my aging mind appreciates
the help!
BTW, I am really enjoying the Imagecraft compiler. Watch for some new libraries soon!
doing all the bit fiddling required when programming a microcontroller.
I remembered some macros I had found when i was doing AVR C programming, so I blew the
dust off of them and here they are!
// macros for bit fiddling in C (from AVR tech notes and AVRfreaks.com forum discussions)
#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define FLIPBIT(ADDRESS,BIT) (ADDRESS ^= (1<<BIT))
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))
#define SETBITMASK(x,y) (x |= (y))
#define CLEARBITMASK(x,y) (x &= (~y))
#define FLIPBITMASK(x,y) (x ^= (y))
#define CHECKBITMASK(x,y) (x & (y))
#define VARFROMCOMB(x, y) x
#define BITFROMCOMB(x, y) y
#define C_SETBIT(comb) SETBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CLEARBIT(comb) CLEARBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_FLIPBIT(comb) FLIPBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
#define C_CHECKBIT(comb) CHECKBIT(VARFROMCOMB(comb), BITFROMCOMB(comb))
These can be really handy as you don't need to recall the bit logic over and over again.
The last four macros deserve an example to show how they can be used:
/******* C_ macros usage example *********/
#define Status_LED OUTA, 3
C_SETBIT(Status_LED);
C_CLEARBIT(Status_LED);
I hope these help someone simplify their C programming. I know my aging mind appreciates
the help!
BTW, I am really enjoying the Imagecraft compiler. Watch for some new libraries soon!
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
Thanks jazzed. I didn't notice the bit macros in there.
Below are some of the same macros I showed earlier. Any idea why they surround them in a do {} while(0) loop?
/**
* Clear a bit in val
* @param val variable where bit will be cleared
* @param bit is bit number to clear.
*/
#define CLR(val,bit) do { (val) &= ~(1 << (bit)); } while (0)
/**
* Set a bit in val
* @param val variable where bit will be set
* @param bit is bit number to set.
*/
#define SET(val,bit) do { (val) |= (1 << (bit)); } while (0)
/**
* Flip a bit in val
* @param val variable where bit will be toggled
* @param bit is bit number to toggle.
*/
#define FLIP(val,bit) do { (val) ^= (1 << (bit)); } while (0)
SET, CLR, FLIP work well for all the outbound stuff, but no way in read the input pins for the predefined macro's.
This one has been the handiest one Ive got so far. Thanks Forum peeps.
#define PinState(pin) ( (INA >> pin) & 1) )// pin >= 0 and pin <= 31
TJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
Yes, you're right I forgot "GET". Maybe Richard can fix that for the next release.
(warning: untested generic GET macro)
/**
·* Get a bit from a val
·* @param val variable where bit will be fetched.
·* @param bit is bit number to get.
·* @return binary value (1 or 0) of the selected bit.
·*/
#define GET(val,bit) ( ((val) & (1 << (bit))) >> bit )
Being picky to avoid corner case problems, one should always surround the incoming parameter symbol(s) for a macro with parenthesis. In yours and some other macros "pin" is "expanded" as part of the statement.
For example, this does not do what you might think because of C order of operation rules (which are different from spin ... what a pain):
#define PinState(pin) ((INA >> pin) & 1))
int foo(void)
{
· int a,b,c;
· a = 7;
· b = 2;
· c = PinState(a & b);
· return c;
}
Here PinState is translated as:
(INA >> a & b) & 1 --> ((INA >> 7) & 2) & 1
Using (pin) instead
#define PinState(pin) ((INA >> (pin)) & 1))
(INA >> (a & b)) & 1 --> (INA >> 2) & 1
BTW: do { ...; ...; } while(0) is not needed here because the macro definition is a single self contained expression.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230