According to the datasheet for GPINTENA (0x04) and GPINTB (0x05):
"3.5.3 INTERRUPT-ON-CHANGE CONTROL REGISTER:
If a bit is set, the corresponding pin is enabled for interrupt-on-change. The DEFVAL and INTCON registers must also be configured if any pins are enabled for interrupt-on-change".
However, in below program registers 0x04 and 0x05 are not written to, hence default values 0x00 remain in place.
And yet when pushing the buttons, the LED's change state following interrupt detection.
How can this be explained in light of what the datasheet reads?
Source: Leon van der Horst - Microcontrollers
// http://www.leonvanderhorst.nl/MCP23017.htm#Project2
/* --------------------------------------------------------------------------------------------------------------------
* | S.M.G. IJmond - I/O Controller met 8x Output (A) en 8x Input (B) met I2C Communicatie |
* | |
* | LAATSE UPDATE: Zondag 26 feb 2017 |
* | VERSIE: 0.4_Petzorg |
* | |
* | |
* | Aansluitingen MCP23017 |
* | |
* | Pin 9 = Vdd = 5V |
* | Pin 10 = Vss = Gnd |
* | | |
* | Pin 12 = SCL = Arduino A5 (4.7K weerstand naar 5V) |
* | Pin 13 = SDA = Arduino A4 (4.7K weerstand naar 5V) |
* | |
* | Pin 15 = A0 = 0 = Gnd, 1 = 5V |
* | Pin 16 = A1 = 0 = Gnd, 1 = 5V |
* | Pin 17 = A2 = 0 = Gnd, 1 = 5V |
* | |
* | pin 18 = reset = 5V, eventueel via 10k weerstand |
* | |
* | Pin 21 = GPA0 = 1e groep van 8 I/O poorten, bit0 |
* | Pin 22 = GPA1 = 1e groep van 8 I/O poorten, bit1 |
* | Pin 23 = GPA2 = 1e groep van 8 I/O poorten, bit2 |
* | Pin 24 = GPA3 = 1e groep van 8 I/O poorten, bit3 |
* | Pin 25 = GPA4 = 1e groep van 8 I/O poorten, bit4 |
* | Pin 26 = GPA5 = 1e groep van 8 I/O poorten, bit5 |
* | Pin 27 = GPA6 = 1e groep van 8 I/O poorten, bit6 |
* | Pin 28 = GPA7 = 1e groep van 8 I/O poorten, bit7 |
* | |
* | Pin 8 = GPB0 = 2e groep van 8 I/O poorten, bit0 |
* | Pin 7 = GPB1 = 2e groep van 8 I/O poorten, bit1 |
* | Pin 6 = GPB2 = 2e groep van 8 I/O poorten, bit2 |
* | Pin 5 = GPB3 = 2e groep van 8 I/O poorten, bit3 |
* | Pin 4 = GPB4 = 2e groep van 8 I/O poorten, bit4 |
* | Pin 3 = GPB5 = 2e groep van 8 I/O poorten, bit5 |
* | Pin 2 = GPB6 = 2e groep van 8 I/O poorten, bit6 |
* | Pin 1 = GPB7 = 2e groep van 8 I/O poorten, bit7 |
* | |
* | |
* | Decimale, hexadecimale, binaire waarden t.b.v. omrekenen: |
* | --------------------------------------------------------- |
* | Dec Hex Bit |
* | ------ ------ -------- |
* | 0 0 0000 |
* | 1 1 0001 |
* | 2 2 0010 |
* | 3 3 0011 |
* | 4 4 0100 |
* | 5 5 0101 |
* | 6 6 0110 |
* | 7 7 0111 |
* | 8 8 1000 |
* | 9 9 1001 |
* | 10 A 1010 |
* | 11 B 1011 |
* | 12 C 1100 |
* | 13 D 1101 |
* | 14 E 1110 |
* | 15 F 1111 |
* | |
* | Binair lezen van rechts naar links, hexadecimaal van links naar rechts, decimaal van links naar rechts. |
* | |
* | 128 64 32 16 8 4 2 1 |
* | bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 |
* | |
* | A2 A1 A0 |
* | 0 0 1 0 0 X X X = minimaal 32 |
* | 0 0 1 0 0 0 0 0 = 32 = 0x20 = B00100000 |
* | 0 0 1 0 0 0 0 1 = 33 = 0x21 = B00100001 |
* | 0 0 1 0 0 0 1 0 = 34 = 0x22 = B00100010 |
* | 0 0 1 0 0 0 1 1 = 35 = 0x23 = B00100011 |
* | 0 0 1 0 0 1 0 0 = 36 = 0x24 = B00100100 |
* | 0 0 1 0 0 1 0 1 = 37 = 0x25 = B00100101 |
* | 0 0 1 0 0 1 1 0 = 38 = 0x26 = B00100110 |
* | 0 0 1 0 0 1 1 1 = 39 = 0x27 = B00100111 |
* | |
* | 0 1 0 0 0 0 0 0 = 0x40 = 64 (= 4 x 16) |
* | |
* | Rekenvoorbeelden: |
* | 0x2F = 2x16^1 + 15x16^0 |
* | B0100 = 0x2^0 + 0x2^1 + 1x2^2 + 0x2^3 |
* | |
* --------------------------------------------------------------------------------------------------------------------
*/
#include <Wire.h> // Wire library t.b.v. I²C
// MCP23017 registers (everything except direction defaults to 0)
#define IODIRA 0x00 // IO direction (0 = output, 1 = input (Default))
#define IODIRB 0x01
#define IOPOLA 0x02 // IO polarity (0 = normal, 1 = inverse)
#define IOPOLB 0x03
#define GPINTENA 0x04 // Interrupt on change (0 = disable, 1 = enable)
#define GPINTENB 0x05 //
#define DEFVALA 0x06 // Default comparison for interrupt on change (interrupts on opposite)
#define DEFVALB 0x07
#define INTCONA 0x08 // Interrupt control (0 = interrupt on change from previous, 1 = interrupt on change from DEFVAL)
#define INTCONB 0x09
#define IOCON 0x0A // Interne Configuratie: bank/mirror/seqop/disslw/haen/odr/intpol/notimp
// Als bank=0 dan IC in 16 bits mode registers zijn gekoppeld bank=0 dan in 8 bits mode en registers zijn losstaand
// Als mirror =0 dan interupts zijn onafhankelijk van elkaar en anders zijn ze gekoppeld (beide moeten hoog zijn) lees pag 24 apps
// Als seqop = 0 dan geen doortellen van interne adressering
// Als disslw =0 dan functie verandering van de slew rate van de sda pin. Lees functie/moment van sda pin.
// Als haeven =0 dan hardware adres in of uitschakeling. bij nul dan a1 a2 a3 =0 en anders is het adres gelijk aan de pin instelling.
// Als odr =0 dan opendrain geeft de mogelijk uitgangen te koppelen. inpol wordt dan genegeerd.
// Als intpol =0 dan interupt polarity is de instellingen van de interupt pins. 0 of 1.
//#define IOCON 0x0B // same as 0x0A is exact gelijk aan icon 0A en hoeft niet ingesteld te worden, neemt alles over van icon 0A.
#define GPPUA 0x0C // Pull-up resistor (0 = disabled, 1 = enabled)
#define GPPUB 0x0D
#define INFTFA 0x0E // Interrupt flag (read only) : (0 = no interrupt, 1 = pin caused interrupt)
#define INFTFB 0x0F
#define INTCAPA 0x10 // Interrupt capture (read only) : value of GPIO at time of last interrupt
#define INTCAPB 0x11
#define GPIOA 0x12 // Port value. Write to change, read to obtain value
#define GPIOB 0x13
#define OLLATA 0x14 // Output latch. Write to latch output.
#define OLLATB 0x15
#define I2Cadres 0x20 // 8 uitgangen op A en 8 ingangen op B
//--------------------------------------------------------------------- SETUP ---------------------------------------------------------------------------
void setup()
{
Wire.begin(); // start Wire library als master. Volgens de documenten blijkt dat adres 0x00 een z.g. broadcast adres is wat elk ic dan kan ontvangen.
Serial.begin(9600);
Wire.beginTransmission(I2Cadres); // I²C Adres chip
Wire.write(IOCON); // IOCON register
Wire.write(0x20); // Disable sequential addresses
Wire.endTransmission();
// output op A
Wire.beginTransmission(I2Cadres);
Wire.write(IODIRA); // IODIRA register
Wire.write(0x00); // Allemaal 0, allemaal uitgangen
Wire.endTransmission();
// input op B
Wire.beginTransmission(I2Cadres);
Wire.write(IODIRB); // IODIRB register
Wire.write(0xFF); // Allemaal 1, allemaal ingangen
Wire.endTransmission();
Wire.beginTransmission(I2Cadres);
Wire.write(GPPUB); //pull up weerstanden inschakelen
Wire.write(0xFF); // voor alle B ingangen
Wire.endTransmission();
}
//--------------------------------------------------------------------- VOID ---------------------------------------------------------------------------
// Poort A
void turnOnLED()
{
Wire.beginTransmission(I2Cadres);
Wire.write(GPIOA); // GPIOA = 1e groep van 8 I/O poorten.
Wire.write(B00111100);
Wire.endTransmission();
}
void turnOffLED()
{
Wire.beginTransmission(I2Cadres);
Wire.write(GPIOA); // GPIOA = 1e groep van 8 I/O poorten.
Wire.write(B11000011);
Wire.endTransmission();
}
// Poort B
void ontvang()
{
Wire.requestFrom(I2Cadres,GPIOB);
int x = Wire.read(); // ontvang byte als getal
Serial.print("Schakelaar data van MCP23017 is ");
Serial.print(x); // toon de byte
int(y) = x;
// om de bits uit te lezen
Serial.print(" - Byte ");
if (x>=128) {
Serial.print("1");
x=x-128;
}else{
Serial.print("0");
}
if (x>=64) {
Serial.print("1");
x=x-64;
}else{
Serial.print("0");
}
if (x>=32) {
Serial.print("1");
x=x-32;
}else{
Serial.print("0");
}
if (x>=16) {
Serial.print("1");
x=x-16;
}else{
Serial.print("0");
}
if (x>=8) {
Serial.print("1");
x=x-8;
}else{
Serial.print("0");
}
if (x>=4) {
Serial.print("1");
x=x-4;
}else{
Serial.print("0");
}
if (x>=2) {
Serial.print("1");
x=x-2;
}else{
Serial.print("0");
}
if (x>=1) {
Serial.println("1");
x=x-1;
}else{
Serial.println("0");
}
// einde bits tonen in Y moet het getal staan
}
//--------------------------------------------------------------------- VOID LOOP ---------------------------------------------------------------------------
void loop()
{
turnOnLED();
// turnOnLEDB();
ontvang();
delay(100); // tijdsduur leds aan
// turnOffLEDB();
delay(100);
// turnOnLEDB();
delay(100);
turnOffLED();
// turnOffLEDB();
ontvang();
delay(100); // tijdsduur leds uit
delay(100); // tijdsduur leds aan
// turnOnLEDB();
delay(100);
// turnOffLEDB();
delay(100);
}