我正在尝试使用 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);
}
}