We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I want to create a fctn which can set or clear a bit based on the value of a variable. I attempted to incorporate the provided macro fctns; it didn't work. It compiled, but didn't change port state. However, I don't understand the syntax of the macro. Q: why doesn't my fctn work? Q: how can the macro fctn work: using a keyword 'bit' for a variable name, and not defining a variable 'var'? Example code snippets below: ... in includes.h #define setbit(var,bit) (var |= (0x01 << (bit))) #define clrbit(var,bit) (var &= (~(0x01 << (bit)))) ... in main.c void changebit( UINT16 var, UINT8 bitn, bit bitstate) { if (bitstate) setbit(var,bitn); else clrbit(var,bitn); } ... in main() changebit(P7,4,bitstate); Thank you. David
how can the macro fctn work: using a keyword 'bit' for a variable name, and not defining a variable 'var'? The preprocessor runs before the text is submitted to the C compiler. (In theory; in practice, the two programs are usually combined, but the effect is the same.) "Bit" is not a keyword to the preprocessor. It will happily replace all occurrences in the macro with the actual parameter ("bitn") before compilation. The compiler sees: if (bitstate) (var |= (0x01 << (bitn))) else (var &= (~(0x01 << (bit)))); "var" is a parameter to the function changebit, so that identifier is valid; "bitn" is also a parameter, and not a keyword, so it is valid, too. Q: why doesn't my fctn work?</I. changebit() is a C function. When you change "var", you are changing the local copy of the parameter var passed in to the routine. This will not affect the actual parameter P7. (C always passes parameters by value.) Changebit() sets a bit in a local parameter and then discards the value. If you really want to reuse this snippet of code with different ports, make changebit() a macro as well. Or, give it a return value: P7 = changebit (P7, 4, bitstate); I'd suggest just writing out the bit operations inline. The intent of "or equal" and "and equal not" is easily readable to an embedded programmer. As long as I'm making suggestions, I'd also suggest that you always use {} in your if (and other) statements, even if you only have one line there and technically don't need them. It's a habit that will save a lot of headache when you go back and insert another line, or just hack in a bit of debug code. On the other hand, I'd probably #define a constant for the bit "4", so we know what it does. Which is more obvious: P7 |= 1 << 4; or #define NuclearMissileLaunchControl 0x10 ... P7 |= NuclearMissileLaunchControl; // oops, I meant bit 3! Sorry for the typo.
Thanks... I was thinking the same thing; avoid the macro and just write the C. However, the following generates syntax errors beginning with '|=' . I'm missing something.
void changebit( UINT16 *var, UINT8 bitnum, bit bitstate) { if (bitstate) { *var |= (0x01 << bitnum); // set } else { *var &= ~(0x01 << bitnum); // clr } } ... in main() changebit(&P7, RED_LED, 1); // LED OFF
Reading your msg more carefully,
//--- A --- UINT16 changebit( UINT16 var, UINT8 bitnum, bit bitstate) { if (bitstate) { var = var |(0x01 << bitnum); } else { var &= ~(0x01 << bitnum); } return(var); } P7 = changebit(P7,RED_LED,1); // LED OFF
//--- B --- void changebit( UINT16 *var, UINT8 bitnum, bit bitstate) { if (bitstate) { *var |= (0x01 << bitnum); // set } else { *var &= ~(0x01 << bitnum); // clr } } changebit(&P7, RED_LED, 1); // LED OFF