以下代码来自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 ++兼容代码,请告诉我,我将删除标记 p>
答案 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'