The following code is from a PIC microcontroller header file, but I assume it’s plain old C.
I understand that the code is to be used for accessing individual bits at an address in memory, but as a C novice, I’d like some help in understanding what is going on here, and how I’d go about using it in my code to set or get bits from ADCON1.
volatile unsigned char ADCON1 @ 0x09F;
volatile bit VCFG0 @ ((unsigned)&ADCON1*8)+4;
volatile bit VCFG1 @ ((unsigned)&ADCON1*8)+5;
volatile bit ADFM @ ((unsigned)&ADCON1*8)+7;
volatile union {
struct {
unsigned : 4;
unsigned VCFG0 : 1;
unsigned VCFG1 : 1;
unsigned : 1;
unsigned ADFM : 1;
};
} ADCON1bits @ 0x09F;
tagged to C and C++. Let me know if it’s not C++ compatible code, and I’ll remove the tag
This simply declares the
ADCON1variable.volatilemeans accesses should not be optimized out, because the variable contents may change during execution. (ie. the hardware updates the value.)I’m guessing the
@syntax is non-standard C; I’ve never seen it before. But I figure it means the value is to be found at offset0x09F.These again declare variables. The
bittype is also not standard C, as far as I know, but should be self-explanatory.The
@syntax is again used here to declare the location, but the interesting thing is that apparently the offset is in type-increments, because the address ofADCON1is multiplied by 8. (Acharis 8 times the size of abit.)It’s much the same as you’d index an array or do pointer arithmetic in regular C, for example:
char foo[4]is an array 4 bytes in size, butint bar[4]is an array 32 bytes in size. Except in this case, your ‘array’ is the processor’s entire address space.So basically, these variables represent specific bits of
ADCON1, by taking the char-address (&ADCON1), converting it to a bit-address (*8), then addressing the specific bit (+4).This declaration is independent from the above, but achieves about the same.
A union of one struct is declared, and a variable of that type is declared at offset
0x09F. The:4syntax you see in the struct indicates a bit-size of the member. Nameless struct members are simply inaccessible.The union doesn’t seem to really add anything here. You’d access bits as
ADCON1bits.VCFG0.