// 16 tlacitek na expanderu MCP23017 // Arduino odchytava preruseni pri zmene stavu tlacitek #include // knihovna pro praci s I2C volatile boolean bylo_preruseni = false; // znacka, jestli behem posledni smycky doslo k preruseni byte GPIOA; // aktualni hodnota portu GPA na expanderu byte GPIOB; // aktualni hodnota portu GPB na expanderu //----------------------------------------------------------------------------------------------- // podprogram pro zapis hodnot do prislusnych registru expanderu MCP23017 void i2c_zapis(byte registr, byte data) { Wire.beginTransmission(0x20); // adresa expanderu pri vsech trech adresovacich vstupech v LOW Wire.write(registr); // registr Wire.write(data); // data Wire.endTransmission(); } //----------------------------------------------------------------------------------------------- // podprogram pro cteni hodnot z prislusnych registru expanderu MCP23017 byte i2c_cteni(byte registr) { Wire.beginTransmission(0x20); // adresa expanderu pri vsech trech adresovacich vstupech v LOW Wire.write(registr); // vyber registru Wire.endTransmission(); Wire.requestFrom(0x20, 1); // z expanderu se precte obsah jednoho registru byte data = Wire.read(); // data return data; } //----------------------------------------------------------------------------------------------- void setup(void) { Serial.begin(9600); Wire.begin(); pinMode(2,INPUT_PULLUP); // pin D2 se pouzije pro odchytavani preruseni // konfigurace MCP23017 pro testovani zmeny na vsech pinech obou portu a generovani INT signalu i2c_zapis(0x00,0xFF); // (registr IODIRA) - smer celeho portu GPA jako VSTUP i2c_zapis(0x01,0xFF); // (registr IODIRB) - smer celeho portu GPB jako VSTUP i2c_zapis(0x0C,0xFF); // (registr GPPUA) - na cely port GPA pripojit Pull-Upy i2c_zapis(0x0D,0xFF); // (registr GPPUB) - na cely port GPB pripojit Pull-Upy i2c_zapis(0x04,0xFF); // (registr GPINTENA) - vsechny piny na GPA mohou vyvolat preruseni i2c_zapis(0x05,0xFF); // (registr GPINTENB) - vsechny piny na GPB mohou vyvolat preruseni i2c_zapis(0x0A,0x40); // (registr IOCON) - vnitrni "propojeni" (zrcadleni) obou pinu INTA a INTB, pri zmene na GPA nebo GBP padaji do LOW i2c_zapis(0x08,0x00); // (registr INTCONA) - Pin INTA (i INTB) se nastavi pri kazde zmene portu GPA (i pri rozepnuti tlacitka) i2c_zapis(0x09,0x00); // (registr INTCONB) - Pin INTA (i INTB) se nastavi pri kazde zmene portu GPB (i pri rozepnuti tlacitka) attachInterrupt(0, preruseni, FALLING); // MCP23017 je nakonfigurovany tak, ze pri preruseni posila na pinech INTA a INTB sestupnou hranu } //----------------------------------------------------------------------------------------------- void loop(void) { if (bylo_preruseni == true) { // POZOR: LOW stav na pinech INTA a INTB na expanderu se zrusi az prectenim obsahu registru GPIOA a GPIOB // Do doby, nez se oba tyto registry prectou, se zadne dalsi preruseni neobjevi. GPIOA = i2c_cteni(0x12); // cteni aktualniho stavu portu GPA (registr GPIOA) GPIOB = i2c_cteni(0x13); // cteni aktualniho stavu portu GPB (registr GPIOB) Serial.println("Stav obou portu expanderu pri preruseni:"); Serial.println(GPIOA); Serial.println(GPIOB); bylo_preruseni = false; } // pokud z nejakeho duvodu zustalo preruseni na pinech INTA a INTB aktivni (LOW), // prectou se kvuli jeho deaktivaci v pristi smycce oba porty jeste jednou if ( digitalRead(2) == LOW ) { bylo_preruseni = true; } delay(200); } //----------------------------------------------------------------------------------------------- void preruseni() { bylo_preruseni = true; }