--_002_kohc3bx0tln2skaterswarbrick_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Dwayne Reid writes: > This has been an informative thread for me. I'm a diehard assembler=20 > programmer and my brain simply refuses to grok "C". But I keep=20 > poking at it, hoping that the AH HA moment will occur. > > One of the many things I learned from PIC assembler guru Andrew=20 > Warren was to define all of my bit fields with names that are used=20 > later in my program. Your example above would be done as: > > #define LCDisBusy LCDstatus,1 > where LCDstatus has previously been defined in exactly the same=20 > way. In use, I simply reference the defined name: > btfsc LCDisBusy > do something > > One of the things that really bugs me about C programs is that there=20 > didn't appear to be any easy way to do this simple function. This=20 > thread has shown me that there is something relatively close. You can do other preprocessor tricks in C to hide more convoluted logic. For example[*]: #define HEN_HOUSE_OPEN_PIN 3 #define FOX_SEEN_PIN 5 #define BIT(n) 1 << (n) #define FOX_WARNING_MASK BIT(HEN_HOUSE_OPEN_PIN) | BIT(FOX_SEEN_PIN) #define FOX_WARNING(status) (((status) & FOX_WARNING_MASK) =3D=3D FOX_WARNI= NG_MASK) .... if (FOX_WARNING (status)) { ... } or whatever. I haven't tried compiling this with XC16 to see whether it does a decent job with the resulting code. The advantage of this over using a different bit field struct for each hunk of logic is that you don't need to cast stuff between types as much. I'd also consider writing FOX_WARNING above as static inline int fox_warning (int status) { return (status & FOX_WARNING_MASK) =3D=3D FOX_WARNING_MASK; } The main advantage is that it's a lot easier to get the parentheses right. With a decent compiler, the effect will be exactly the same as the macro. The disadvantage is that really rubbish compilers might not inline it, so you end up with an unnecessary function call. At the moment, I'm mostly writing for a beefy DSP (well, beefy compared to a PIC anyway). The compiler there is gcc with a custom back end, so target-independent optimisations like this work brilliantly. I haven't tried with XC16 or similar. Rupert [*] This won't matter on a PIC, I don't think, but be careful with the "BIT" macro I wrote if you need bits that aren't in the standard integer type. For example, if you're on a 64-bit target with a 32-bit int type then uint64_t x =3D 1 << 32; sets x to zero because 1 is a 32 bit integer and has been shifted off to oblivion (Technically I think the result is undefined in the C standard because the "1" is a signed int, but whatever). The standard work-around is something like uint64_t x =3D (uint64_t)1 << 32; --_002_kohc3bx0tln2skaterswarbrick_ Content-Type: text/plain; name="ATT00001.txt" Content-Description: ATT00001.txt Content-Disposition: attachment; filename="ATT00001.txt"; size=224; creation-date="Fri, 02 May 2014 13:26:01 GMT"; modification-date="Fri, 02 May 2014 13:26:01 GMT" Content-Transfer-Encoding: base64 LS0gDQpodHRwOi8vd3d3LnBpY2xpc3QuY29tL3RlY2hyZWYvcGljbGlzdCBQSUMvU1ggRkFRICYg bGlzdCBhcmNoaXZlDQpWaWV3L2NoYW5nZSB5b3VyIG1lbWJlcnNoaXAgb3B0aW9ucyBhdA0KaHR0 cDovL21haWxtYW4ubWl0LmVkdS9tYWlsbWFuL2xpc3RpbmZvL3BpY2xpc3QNCg== --_002_kohc3bx0tln2skaterswarbrick_-- .