如何解释以下C(包括位字段和结构)

时间:2012-02-29 17:00:17

标签: c++ c microcontroller pic

以下代码来自PIC单片机头文件,但我认为它是普通的旧C语言。 我知道代码用于访问内存中某个地址的各个位,但作为C新手,我想帮助理解这里发生了什么,以及我如何在我的内容中使用它用于设置或从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;

标记为C和C ++。如果它不是C ++兼容代码,请告诉我,我将删除标记

2 个答案:

答案 0 :(得分:3)

volatile unsigned char ADCON1 @ 0x09F;

这只是声明了ADCON1变量。 volatile表示不应优化访问,因为变量内容可能在执行期间发生变化。 (即硬件更新值。)

我猜测@语法是非标准C;我以前从未见过它。但我认为这意味着该值可以在偏移0x09F找到。

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

这些再次声明变量。据我所知,bit类型也不是标准C,但应该是不言自明的。

此处再次使用@语法来声明位置,但有趣的是,显然偏移量是以类型为增量的,因为ADCON1的地址乘以8(A char的大小是bit的8倍。)

它与您在常规C中索引数组或执行指针算法的情况大致相同,例如:char foo[4]是一个4字节大小的数组,但int bar[4]是一个32字节的数组尺寸。除了这种情况,你的'数组'是处理器的整个地址空间。

基本上,这些变量代表ADCON1的特定位,通过取char地址(&ADCON1),将其转换为位地址(*8),然后解决特定位(+4)。

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

此声明独立于上述内容,但大致相同。

声明一个结构的并集,并且在偏移0x09F声明该类型的变量。您在结构中看到的:4语法表示该成员的位大小。无名结构成员根本无法访问。

工会似乎并没有在这里添加任何东西。您可以访问位ADCON1bits.VCFG0

答案 1 :(得分:1)

据推测,在0x09F处有一个控制ADC的字节寄存器,'bit'是一个布尔类型,可以作为从0开始的位数组寻址(因此为* 8),因此可以通过以下方式访问ADC:例如。 'ADFM = 0'。

并联是使用位域访问ADC控制寄存器的另一种方法(例如,ADCON1bits.VCFG1 = 1)。

整个批次不是标准的C或C ++ - 它是'microController C'