0

我正在尝试使用 pigpio 从 MCP23017 板上读取中断更改,但我没有收到任何通知……我似乎不知道我需要做的初始化程序(查看文档http:// ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf看来我没有使用正确的值...)。

我将 B 端用于输入,将 A 端用于输出:

i2cWriteByteData(i2cHandle, IODIRB, 0xFF); // inputs
i2cWriteByteData(i2cHandle, IODIRA, 0x00); // outputs

然后我尝试设置中断状态(这似乎是错误的),但我是从http://abyz.me.uk/rpi/pigpio/examples.html的“I2C 声纳”示例中复制的

i2cWriteByteData(i2cHandle, GPINTENB, 0x00); // Disable.
i2cWriteByteData(i2cHandle, DEFVALB, 0x00) ; // N/A.
i2cWriteByteData(i2cHandle, INTCONB, 0x00) ; // On change.

然后注册处理程序以读取更改:

gpioSetMode(ALERTPIN, PI_INPUT); /* start capacitor recharge */
gpioSetISRFuncEx(ALERTPIN, EITHER_EDGE, 0, alert, nullptr); /* call alert when state changes */

所以我的问题是我错过了什么,当状态改变时我的警报函数永远不会被调用(奇怪的是,当我在控制台上进行转储时它被调用(sudo i2cdump -y 1 0x20

另一个问题是我的定义是否正确?为什么有两组值(地址 IOCON.BANK = 1 和 0)?MCP23017 的地址是什么?(我正在使用地址 IOCON.BANK = 0):

#define IODIRA    0x00
#define IODIRB    0x01
#define IPOLA     0x02
#define IPOLB     0x03
#define GPINTENA  0x04
#define GPINTENB  0x05
#define DEFVALA   0x06
#define DEFVALB   0x07
#define INTCONA   0x08
#define INTCONB   0x09
#define IOCONA    0x0A
#define IOCONB    0x0B
#define GPPUA     0x0C
#define GPPUB     0x0D
#define INTFA     0x0E
#define INTFB     0x0F
#define INTCAPA   0x10
#define INTCAPB   0x11
#define GPIOA     0x12
#define GPIOB     0x13
#define OLATA     0x14
#define OLATB     0x15

#define ALERTPIN 26

更新

接下来我展示了我执行的所有代码,在阅读了文档之后,我认为我做的一切都是正确的,但似乎我缺少一些初始化......奇怪的是,当按下连接到 GPA0 的输入按钮时读取 GPIOA值是 255 (0xff),如果不是按下则为 0... 奇怪的是按下时它应该是 1 对吗?

void estimulateMCP23017(unsigned i2cAddr=0x20,unsigned i2cBus=1){
    //open i2c MCP23017
    int i2cHandle = i2cOpen(i2cBus, i2cAddr, 0);
    //open is with success if is >=0
    if(i2cHandle>=0){
        //IODIR: I/O DIRECTION REGISTER (ADDR 0x00)
        //1 = Pin is configured as an input.
        //0 = Pin is configured as an output
        //we can set each separately if we want
        //set side A as output (0)
        i2cWriteByteData(i2cHandle, IODIRA, 0xFF); // A is inputs
        //set side B as input (1)
        i2cWriteByteData(i2cHandle, IODIRB, 0x00); // B is outputs

        //turn all outputs to on (pins 0 to 7 is the bit high in 0x00-0xFF)
        i2cWriteByteData(i2cHandle, OLATA, 0x00);
        i2cWriteByteData(i2cHandle, OLATB, 0xFF);

        //now listen for changes on side (B)
        // General purpose I/O interrupt-on-change bits <7:0>
        //1 = Enables GPIO input pin for interrupt-on-change event.
        //0 = Disables GPIO input pin for interrupt-on-change event.
        i2cWriteByteData(i2cHandle, GPINTENA, 0xFF); // Enable all
        i2cWriteByteData(i2cHandle, GPINTENB, 0x00); // disable
        //Sets the compare value for pins configured for interrupt-on-change from defaults <7:0>
        //If the associated pin level is the opposite from the register bit, an interrupt occurs
        i2cWriteByteData(i2cHandle, DEFVALA, 0x00); // does not matter
        i2cWriteByteData(i2cHandle, DEFVALB, 0x00); // does not matter
        // Controls how the associated pin value is compared for interrupt-on-change <7:0>
        //1 = Pin value is compared against the associated bit in the DEFVAL register.
        //0 = Pin value is compared against the previous pin value.
        i2cWriteByteData(i2cHandle, INTCONA, 0x00) ; // On change.
        i2cWriteByteData(i2cHandle, INTCONB, 0x00) ; // does not matter.

        cout << "waiting for changes...(input value: "<<i2cReadByteData(i2cHandle, GPIOA)<<")\n";

        gpioSetMode(ALERTPIN, PI_INPUT); /* set alert pin as input */
        gpioSetISRFuncEx(ALERTPIN, EITHER_EDGE, 0, alert, nullptr); /* call alert when state changes */

        cin.get();
        i2cClose(i2cHandle);
    }
}
4

1 回答 1

0

由于银行 A 是您的输入,因此您应该使用:

i2cWriteByteData(i2cHandle, GPINTENA, 0xFF); // Enable.
i2cWriteByteData(i2cHandle, INTCONA, 0x00) ; // On change.

您的定义看起来正确。MCP23017 有两种不同的寄存器寻址模式。使用 IOCON.BANK 标志设置模式。只是永远不要碰那一点,没有理由这样做。

于 2020-06-29T20:45:49.053 回答