MCP23017 LED und Taster auf einem Port

achim S.

Mitglied
16. Jan. 2010
704
13
18
Berlin Biesdorf
Sprachen
  1. ANSI C
Hallo
Für ein neues Projekt versuche ich bei einem MCP23017 auf einem Port 2xTaster und 4xLED gleichzeitig zu betreiben. Wenn ich jeden taster einzeln betreibe gibt es keine Probleme. Wenn ich beide Taster nutzen will leuchten alle Taster und werden bei Betätigung nur etwas dunkler.


CodeBox C
 
// setzt Port B alle R mit GPPUB als Eingang
    i2c_start(MCP23017_ADDR);                // Angabe Adresse
    i2c_write(MCP23017_GPPUB);                // aktivierung der internen Pullups Widerstände
    i2c_write(0b00001100);                        // schalte alle Eingänge auf 5V
    i2c_stop();
    
    // Alle Eingänge Port B invertieren
    i2c_start(MCP23017_ADDR);                // Angabe Adresse
    i2c_write(MCP23017_IPOLB);                // Taster schalten Masse (active-low)
    i2c_write(0x00);                        // alle Eingänge invertieren
    i2c_stop();

Noch die Abfrage für die beiden Taster. Wenn ich einen Taster auskommentiere funktioniert der andere korrekt.


CodeBox C
 
// Abfrage der Eingänge am MCP
        i2c_start(MCP23017_ADDR);            // Angabe Adresse
        i2c_write(MCP23017_GPIOB);
        i2c_stop();
        
        i2c_start(MCP23017_ADDR+1 );        // Auslesen Adresse + 1
        Data = i2c_readNak();                // liest Eingänge ein
        i2c_stop();
        
        // Abfrage Taster    
        if (!(Data & 0b00000100))                    // Abfrage DATA, welcher Taster 0c beide, T1-4, T2-8 0x04
          {                                    // Angabe Taster mit 0x05
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Ausgang A
            i2c_write(MCP23017_OLATB);        // Schalte Ausgang B
            i2c_write(0x30);                // Auswahl der LED
            i2c_stop();
          }
        else
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Ausgang A
            i2c_write(MCP23017_OLATB);        // Schalte Ausgang B
            i2c_write(0x03);                // Auswahl der LED
            i2c_stop();
          }
        
        if (!(Data & 0b00001000))                    // Abfrage DATA, welcher Taster 0c beide, T1-4, T2-8 0x0
          {                                    // Angabe Taster mit 0x05
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Ausgang A
            i2c_write(MCP23017_OLATB);        // Schalte Ausgang B
            i2c_write(0xc0);                // Auswahl der LED
            i2c_stop();
          }
        else
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Ausgang A
            i2c_write(MCP23017_OLATB);        // Schalte Ausgang B
            i2c_write(0x0c);                // Auswahl der LED
            i2c_stop();
          }

Hat jemand eine Idee dazu?
achim
 
Hallo Achim,

ich vermute die zweite if-Abfrage "überschreibt" immer sofort die übertragene Einstellung von der ersten Abfrage.

Probiere es einmal mit allen möglichen Tasterzuständen.

Zum Beispiel inetwa so ...



CodeBox C
Data = (Data & 0b00001100)>>2;
if (Data == 0)                   
{

} else if (Data == 1)

{               
} else if (Data == 2)               

{
} else {

}


Ein gutes neues Jahr
Dirk :ciao:
 
Hallo Dirk
Habe dein Programm eingebaut. Die beiden Taster funktionieren. Es sieht jetzt so aus:


CodeBox C
i2c_start(MCP23017_ADDR+1 );        // Auslesen Adresse + 1
        Data = i2c_readNak();                // liest Eingänge ein
        Data = (Data & 0b00001100)>>2;       
        i2c_stop();
       
        // Abfrage Taster   
        if (Data == 0)
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse 1
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0x00);                // Auswahl der LED
            i2c_stop();
          }
         else if (Data == 1)       
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse 1
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0x30);                // Auswahl der LED 2 und 4
            i2c_stop();
          }
        else if (Data == 2) 
          {                                    // Angabe Taster 2
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0xc0);                // Auswahl der LED 3 und 5
            i2c_stop();
          }

Beim betätigen der taster werdn die LED umgeschaltet. Es bleibt immer eine LED an. Auch wenn ich keinen Taster betätige.

Was nicht funktioniert ist das:


CodeBox C
if (Data == 0)
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse 1
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0x00);                // Auswahl der LED
            i2c_stop();
          }

achim
 
Hi Achim,

schaue mal meinen Beitrag oben.
Den letzten else-Block hast du nicht verwendet, das ist ja wahrscheinlich wichtig.

Das IC habe ich mir jetzt nicht näher angeschaut, es kann also sein dass hier noch ein Fehler vorhanden ist.

Allgemein solltest du nur in gewissen Zeitabständen die Tasten pollen und dann auch nur die LEDs setzen, wenn dies notwendig ist. Hierfür kannst du dir ja eine Variable in deinem Programm anlegen. Dadurch ist der I2C Bus nicht so aktiv.

Dirk :ciao:
 
Habe mein C Buch noch mal gelesen und nehme jetzt das folgende Programm:


CodeBox C
i2c_start(MCP23017_ADDR+1 );        // Auslesen Adresse + 1
        Data = i2c_readNak();                // liest Eingänge ein
        Data = (Data & 0x0c);    
        i2c_stop();
        
        // Abfrage Taster    
        if (Data == 4)        
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse 1
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0x30);                // Auswahl der LED 2 und 4
            i2c_stop();
          }
        else if (Data == 8)  
          {                                    // Angabe Taster 2
            i2c_start(MCP23017_ADDR);        // Angabe Adresse
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0xc0);                // Auswahl der LED 3 und 5
            i2c_stop();
          } 
        else
          {
            i2c_start(MCP23017_ADDR);        // Angabe Adresse 1
            //i2c_write(MCP23017_OLATA);    // Schalte Port A
            i2c_write(MCP23017_OLATB);        // Schalte Port B
            i2c_write(0xff);                // Auswahl der LED
            i2c_stop();
          }

Funktion:
Drücke Taster 1, es leuchten 2 LEDs, lasse Taster 1 los, alle LEDs aus
Drücke Taster 2 es leuchten 2 andere LEDs, lasse Taster 2 los, alle LEDs aus
Drücke beide Taster gleichzeitig, keine LED leuchtet, drücke keinen Taster. keine LED leuchtet
Habe den Port A noch drin gelassen, aber auskommentiert
Falls es jemand braucht.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)