2

在微芯片 C30 编译器中,我可以通过这种方式使用 LAT 寄存器设置引脚 i/o 值:

LATBbits.LATB10=1;

LATBbits 定义为:

typedef struct tagLATBBITS {
  unsigned LATB0:1;
  unsigned LATB1:1;
  unsigned LATB2:1;
  unsigned LATB3:1;
  unsigned LATB4:1;
  unsigned LATB5:1;
  unsigned LATB6:1;
  unsigned LATB7:1;
  unsigned LATB8:1;
  unsigned LATB9:1;
  unsigned LATB10:1;
  unsigned LATB11:1;
  unsigned LATB12:1;
  unsigned LATB13:1;
  unsigned LATB14:1;
  unsigned LATB15:1;
} LATBBITS;
extern volatile LATBBITS LATBbits __attribute__((__sfr__));

我的目标是编写一个可以使用 LAT 寄存器作为参数设置 i/o 值的函数,用伪代码:

void setPin(unsigned int* latReg, unsigned int value){
  (*latReg)=value;
}

setPin(&LATBbits.LATB10, 1);

不幸的是,此代码无法编译,因为“无法获取位域 'LATB10' 的地址”。

我需要它是因为我想实现一个可以处理端口扩展器的类似类库。每个端口扩展器可以有不同的引脚,所以我需要配置它,我想这样做:

typedef struct sPortExpander{
  unsigned int* CS;
  unsigned int* SPBUFF;
  ecc...
} PortExpander

void PortExpander_setOutput(PortExpander p, unsigned char value){
  (*p.CS)=0;
  // Send SPI data
  (*p.CS=1);
}

这样我可以管理多个端口扩展器。

那么,有一种方法可以做我尝试做的事情吗?

谢谢。

4

1 回答 1

1

将结构声明为__attribute__((packed)),然后使用:

void function setPin(struct LATBBITS *reg, unsigned int fieldno, unsigned int value){
    if (value)
        *(uint16_t *)reg |= (1 << fieldno);
    else
        *(uint16_t *)reg &= ~(1 << fieldno);
}
于 2012-08-12T12:48:27.477 回答