如何解决像这些寄存器这样的结构中的所有字段?

时间:2013-03-18 00:24:40

标签: c struct microcontroller pic mplab

如果你编写了一个微控制器,你可能熟悉操纵给定寄存器的选择位,或者写一个字节到整个事物。例如,在使用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。如何更改它以使其有效?我试图复制的那个只能工作,因为它是一个特殊的微控制器寄存器吗?

感谢您的帮助

2 个答案:

答案 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;