I was wondering what the "best" way to set a bit in a variable declared in the bit addressable area. Originally I declared each bit as an sbit and therefore can set and clear them as follows
uint8_t bdata status ; sbit enable = staus ^ 0 ; enable = 1 ; enable = 0 ;
#define ENABLE 0x01 uint8_t bdata status ; status |= ENABLE ; status &= ~ENABLE ;
"I was wondering what other people do and if there is a standard method for doing this?" The #define and masking is the conventional way when using a compiler without specific bit-addressing extensions (and for non bit-addressable data with Keil). Although you seem to have found a (the?) case where the Keil compiler is smart enough to replace a simple mask with a bit-set operation, the only way to guarantee it would be to use the bit-addressing extensions. And the current score is 2:1 that the bit-addressing is clearer! ;-)
The compiler does not generate the same code!
----- FUNCTION main (BEGIN) ----- FILE: 'main.c' 9: void main( void ) 10: { 11: enable = 1; 12: enable = 0; 00000F D200 SETB enable 13: 000011 C200 CLR enable 14: status |= ENABLE; 000013 432001 ORL status,#01H 15: status &= ~ENABLE; 000016 5320FE ANL status,#0FEH 16: } 000019 22 RET ----- FUNCTION main (END) -------
It looks like mine does. Maybe it has something to do with the way i have defined the variable.
$NOMACRO $SEGMENTED CASE MOD167 ; ; 'main.SRC' GENERATED FROM INPUT FILE 'main.c' ; COMPILER INVOKED BY: ; C:\Keil\C166\BIN\C166.EXE main.c BROWSE MOD167 DEBUG ; $MODINF (43) NAME MAIN NCODE CGROUP ?PR?MAIN SDATA DGROUP ?BD0?MAIN,SYSTEM ASSUME DPP3 : SDATA ?BD0?MAIN SECTION DATA BITADDRESSABLE 'BDATA0' status DSB 1 PUBLIC status ?BD0?MAIN ENDS EXTRN ?C_STARTUP : NEAR enable BIT status.0 PUBLIC enable REGDEF R0 - R15 ?PR?MAIN SECTION CODE WORD 'NCODE' ; line 1: #include "types.h" ; line 2: ; line 3: #define ENABLE 0x01 ; line 4: ; line 5: uint8_t bdata status ; ; line 6: ; line 7: sbit enable = status ^ 0 ; ; line 8: ; line 9: #pragma SRC ; line 10: ; line 11: void main ( void ) main PROC NEAR GLOBAL main ; FUNCTION main (BEGIN RMASK = @0x8000) ; line 12: { ; line 13: ; line 14: ; line 15: ; line 16: enable = 1 ; BSET enable ; line 17: enable = 0 ; BCLR enable ; line 18: ; line 19: status |= ENABLE ; BSET (status).0 ; line 20: status &= ~ENABLE ; BCLR (status).0 ; line 21: ; line 22: while(1) ; line 23: { ; line 24: ; line 25: } ?C0001: JMP cc_UC,?C0001 ; FUNCTION main (END RMASK = @0x8000) main ENDP ?PR?MAIN ENDS ; line 26: ; line 27: } END
"Maybe it has something to do with the way i have defined the variable." Or because you are using a C166 compiler as opposed to the (apparent) use of C51 by other posters. In fairness to everyone, your posts did not specify a product and I would hazard a guess that when none is specified, C51 is assumed.
"Or because you are using a C166 compiler as opposed to the (apparent) use of C51 by other posters." Which does, of course, beg the question: If C166 can do it, why can't (or doesn't) C51?
A: Because the C167 has a different output structure.