如果你编写了一个微控制器,你可能熟悉操纵给定寄存器的选择位,或者写一个字节到整个事物。例如,在使用C的PIC上,我可以将整个字节写入PORTA以设置所有位,或者我可以简单地将PORTAbits.RA#设置为单个位。我试图模仿这些结构/联合的定义方式,所以我可以用我的程序中的变量做同样的事情。具体来说,当微控制器开启时,我希望能够重置我自己定义的寄存器,如
REGISTER = 0;
与
REGISTERbits.BIT0 = 0;
REGISTERbits.BIT1 = 0;
...
//or
REGISTERbits = (0,0,0,0,0,0,0,0);
等。
显然,前者更优雅,节省了大量的线条空间。微控制器的头文件是这样的:#ifndef __18F2550_H
#define __18F2550_H
....
extern volatile near unsigned char LATA;
extern volatile near struct {
unsigned LATA0:1;
unsigned LATA1:1;
unsigned LATA2:1;
unsigned LATA3:1;
unsigned LATA4:1;
unsigned LATA5:1;
unsigned LATA6:1;
} LATAbits;
...对于每个寄存器,以及具有多个字节的寄存器使用结构的联合作为其寄存器位。由于我的初始化/声明是在主源文件而不是标题中,所以我放弃了extern并且离我很近:
volatile unsigned char InReg;
volatile struct{
unsigned NSENS:1; //One magnetic sensor per direction
unsigned SSENS:1;
unsigned ESENS:1;
unsigned WSENS:1;
unsigned YBTN:1; //One crosswalk button input per axis
unsigned XBTN:1; //(4 buttons tied together each)
unsigned :2;
} InRegbits;
...但是在编译时,InReg和InRegbits被定义为内存中的两个独立位置,这意味着我无法写入InReg来更改InRegbits。如何更改它以使其有效?我试图复制的那个只能工作,因为它是一个特殊的微控制器寄存器吗?
感谢您的帮助
答案 0 :(得分:3)
volatile union InReg {
unsigned char InRegAll;
struct near {
unsigned NSENS:1; //One magnetic sensor per direction
unsigned SSENS:1;
unsigned ESENS:1;
unsigned WSENS:1;
unsigned YBTN:1; //One crosswalk button input per axis
unsigned XBTN:1; //(4 buttons tied together each)
unsigned :2;
} InRegbits;
}
请注意,此代码可能无法移植。
答案 1 :(得分:2)
为了保证相同的结果,你需要在一个联合中有两个结构。标准说如果联合的成员是结构,第一个结构成员类型是兼容的(并且与相同的位宽相关),你可以对它们中的任何一个进行操作。否则,通过另一个联盟成员访问任何联盟成员是未定义的行为。
e.g。
volatile union {
volatile struct {
unsigned int InReg;
} InReg;
volatile struct {
unsigned NSENS:1; //One magnetic sensor per direction
unsigned SSENS:1;
unsigned ESENS:1;
unsigned WSENS:1;
unsigned YBTN:1; //One crosswalk button input per axis
unsigned XBTN:1; //(4 buttons tied together each)
unsigned:2;
} InRegbits;
} Reg_s;