2

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

Greg Woods
  • 2,697
  • 2
  • 26
  • 18
  • 1
    The definition of `@` and `bit` is missing. – Gunther Piez Feb 29 '12 at 17:12
  • 2
    This is neither plain old C nor plain old C++. There's no `@` symbol in either (except in strings). It is probably a vendor-specific thing. You need to consult the compiler's documentation. I guess it specifies the absolute address of the variable, but don't quote me on that. – n. m. could be an AI Feb 29 '12 at 17:37

2 Answers2

3
volatile unsigned char ADCON1 @ 0x09F;

This simply declares the ADCON1 variable. volatile means 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 offset 0x09F.

volatile bit VCFG0 @ ((unsigned)&ADCON1*8)+4;
volatile bit VCFG1 @ ((unsigned)&ADCON1*8)+5;
volatile bit ADFM  @ ((unsigned)&ADCON1*8)+7;

These again declare variables. The bit type 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 of ADCON1 is multiplied by 8. (A char is 8 times the size of a bit.)

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, but int 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).

volatile union {
    struct {
        unsigned          : 4;
        unsigned    VCFG0 : 1;
        unsigned    VCFG1 : 1;
        unsigned          : 1;
        unsigned    ADFM  : 1;
    };
} ADCON1bits @ 0x09F;

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 :4 syntax 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.

Stéphan Kochen
  • 19,513
  • 9
  • 61
  • 50
  • Thanks for the comprehensive answer, especially the addressing of the bit fields being related to the type. It's a weird concept for me. The clarification that the two blocks of code are unrelated was a surprise, but makes sense now. – Greg Woods Feb 29 '12 at 21:18
1

Presumably, there is a byte register at 0x09F that controls the ADC, 'bit' is a boolean type that can be addressed as a bit array starting at 0, (hence the *8), so the ADC is accessed by, eg. 'ADFM=0'.

The union is an alternative means to access the ADC control register using bit fields, (eg. ADCON1bits.VCFG1=1).

The whole lot is not really standard C or C++ - it's 'microController C'

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • The bit array concept was the strangest to me. It sort of makes sense now, but regardless, I can now use it! – Greg Woods Feb 29 '12 at 21:21