Forum: Mikrocontroller und Digitale Elektronik MCP23017 - gemischter Betrieb von LEDs und Taster


von Fragender (Gast)


Lesenswert?

Hallo
in meiner letzten Frage ging es um den MCP23017 und der Ansteuerung von 
LEDs und die Auswertung von Tastern. Dabei hatte ich alle Pins eines 
Ports auf Eingang oder Ausgang geschaltet. Also ein kompletter Port für 
LEDs und der andere komplette Port für die Taster.

Es ist auch ein "gemischter" Betrieb möglich. Meine damit, das von einem 
Port aus je 4 LEDs und 4 Taster angesteuert werden können.
1
// Abfrage der Taster
2
    i2c_start(MCP23017_ADDR);    // Adresse
3
    i2c_write(MCP23017_GPIOB);
4
    i2c_stop();
5
    
6
    i2c_start(MCP23017_ADDR +1);    // Read-Adresse, mit Fehlerüberprüfung, falls das die Lib so macht!
7
    Data = i2c_readNak();      // liest Ausgänge ein
8
    i2c_stop();
9
    
10
    if (!(Data & 0x05))          // Auswahl der Taster
11
      {
12
      i2c_start(MCP23017_ADDR);    // Adresse
13
      i2c_write(MCP23017_OLATA);
14
      i2c_write(0x20);        // schalte Ausgänge ein  Grün
15
      i2c_stop();
16
      }
17
    else
18
      {
19
      i2c_start(MCP23017_ADDR);    // Adresse
20
      i2c_write(MCP23017_OLATA);
21
      i2c_write(0x02);        // schalte Ausgänge ein  Rot
22
      i2c_stop();
23
      }
24
    
25
    // schreiben der Register für LEDs  
26
    i2c_start(MCP23017_ADDR);    // Adresse
27
    i2c_write(MCP23017_OLATA);                                  
28
    i2c_write(0x04);        // schalte Ausgänge ein
29
    i2c_stop();
30
    
31
    _delay_ms(1500);
32
    
33
    i2c_start(MCP23017_ADDR);    // Adresse
34
    i2c_write(MCP23017_OLATA);                                  
35
    i2c_write(0x40);        // schalte Ausgänge aus
36
    i2c_stop();
37
    
38
    _delay_ms(1500);
Ansonsten verwende ich die gleicn Einstellung wie in dem andere Teil 
bereits angegeben.
Kann mir jemand weiterhelfen?

LG F.

von Irgendwer (Gast)


Lesenswert?

Fragender schrieb:
> Kann mir jemand weiterhelfen?

Gibt es die Frage auch in Vollständig?

von Wolfgang (Gast)


Lesenswert?

Fragender schrieb:
> Kann mir jemand weiterhelfen?

Lerne deine Frage vernünftig zu formulieren.
Als Satzzeichen empfiehlt sich am Ende der Frage ein Fragezeichen, damit 
sie als solche leichter zu erkennen ist.

> in meiner letzten Frage
Sehe ich nicht. Link?

Was ist dein Problem?

von Fragender (Gast)


Lesenswert?

Die Frage ist ganz einfach. Wie kann ich das machen? Als Beispiel für 
meinen bisherigen Code habe das eingetragen.

Beitrag "MCP23017 - Abfrage Taster"

In diesem Link steht einiges.

von Sven S. (boldie)


Lesenswert?

Klar kann man das machen. Hast du dich mit dem Datenblatt auf Seite 9 
und 11 beschäftigt? Dort sind die Register, da kann man bitweise die Ein 
und Ausgänge und ihre Eigenschaften setzen. -> Erst aufschreiben, 
welcher Port welche Eigenschaft haben soll und dann kann man sich die 
Werte für das Register zusammensuchen.

Und dann kann man das so umsetzen:

      i2c_start(MCP23017_ADDR);   <- Spricht das Device an
      i2c_write(MCP23017_OLATA); <- Setzt, welches Register gemeint ist, 
MCP23017_OLATA ist eine Zahl wie im Datenblatt in der Tabelle 1-3 OLATA 
0x0A
      i2c_write(0x02);        // -> setzt den Registerinhalt, Port 1; 
Dort kann man auch mehrere andere Ports setzen.

Nach diesem Schema funktioniert es.

Wenn du mehrere Eigenschaften machen möchtest, macht es unter Umständen 
den Sinn, sich den Registerinhalt im Controller zu merken und immernur 
das entsprechende Bit zu manipulieren, etwa so:

static uint8 contentOLATA = 0; // <- irgendwo als globale variable

... <- hier läuft alles mögliche im Programm, z.B. setzt es Port 4 und 5 
o.ä.

contentOLATA |= 0x02; <- setzt nur bit 2

i2c_start(MCP23017_ADDR);
i2c_write(MCP23017_OLATA);
i2c_write(contentOLATA);

: Bearbeitet durch User
von Karl M. (Gast)


Lesenswert?

Hallo Fragender,

ich schrieb ja schon im anderen Thread, Modularisierung ist das Ziel.

Beitrag "Re: MCP23017 - Abfrage Taster"

Also zu Deiner Frage,

<hier mit Pseudocode>
lese den Zustand über I2C des Registers des MCP23017 zurück verknüpfe 
mit der neuen Bit-Maske und schreibe das Register wieder in den 
MCP23017.

a) setzen von Bits : neuer-Zustand = alter-Zustand OR Bit-Maske

b) löschen von Bits: neuer-Zustand = alter-Zustand AND not(Bit-Maske)

In der Bit-Maske sind die Bits gesetzt, die verändert werden sollen.

von Fragender (Gast)


Lesenswert?

Karl, du hast ganz recht. Werde verschiedene Sachen auslagern und in 
entsprechende Module ablegen. Gerade der Aufruf der Register lohnt sich 
da für. Bevor ich das mache, soll es erst mal funktionieren.
Hatte nicht an die Bitmaske gedacht. Damit sollte es möglich sein. 
Benutze es auch in anderen Projekten.

von Jobst Q. (joquis)


Lesenswert?

Fragender schrieb:
> Es ist auch ein "gemischter" Betrieb möglich. Meine damit, das von einem
> Port aus je 4 LEDs und 4 Taster angesteuert werden können.

Einfacher geht das mit einem PCF8574. Die LEDs gegen VDD und die Taster 
gegen GND. Die LED-Bits nach Wahl invertiert (0 leuchtet) ansteuern,die 
Tasterbits auf 1 setzen. Beim Lesen sind die gedrückten Taster auf 0.

von Fragender (Gast)


Lesenswert?

Das mit dem PCF8574 stimmt genau. Benutze ihn auch für verschiedene 
Anwendungen. Es wird aber langsam Zeit sich neuen ICs zu widmen. Im 
Moment sieht es zwar nicht so aus, als ob er bald ausstirbt. Es kann 
aber nicht schaden nach etwas moderneren zu schauen. Als Bastle gefällt 
mir auf Grund seiner Bauart der MCP32017 im DIP Gehäuse sehr gut. Er 
lässt sich einfach besser verarbeiten.
Leider scheint es recht wenig Beispiele oder Anwendungen zu geben. Ist 
eigentlich schade um den IC das er so Schattendasein führt.
Vielleicht können wir das zusammen ändern.
Kann nur alle auffordern mitzumachen.

LG F.

von Philipp K. (philipp_k59)


Lesenswert?

Fragender schrieb:
> Leider scheint es recht wenig Beispiele oder Anwendungen zu geben. Ist
> eigentlich schade um den IC das er so Schattendasein führt.

Das erscheint nur so weil der so Einfach ist das es keinen Interessiert.

Es gibt 3 richtig Gute deutsche Tutorials in denen alles gesagt wird.

Die Konfiguration ist kurz, gut und schank gehalten.

von Fragender (Gast)


Lesenswert?

Könntest du die Tuts angeben? (Link)

Beitrag #5371473 wurde vom Autor gelöscht.
von Fragender (Gast)


Lesenswert?

Das mit dem Interrupt stimmt genau. Das währe mein nächstes Thema 
geworden.
Das mit dem "einfachen" Schaltkreis stimmt wohl nicht ganz so. Es sind 
doch relativ viele Einstellungen möglich. Da gibt es noch viel zu 
fragen.

LG F.

von Philipp K. (philipp_k59)


Lesenswert?

Die Tuts gebe ich nicht an.. kann jeder selbst suchen

Fragender schrieb:
> Das mit dem "einfachen" Schaltkreis stimmt wohl nicht ganz so.

DOCH..

Bis auf das IOCON Register das geshared wird, hat jedes Register eine 
eigene  Funktion die Bit->Pin gemapped wird.

Jedes der Pinbasierten Register bis auf natürlich mal wieder das 
"eingemachte, wers braucht" Zeugs kann man mit einem Einzeiler erklären.

Ein Tutorial wo jedes Register mit nem Einzeiler beschrieben wird ist 
zum Beispiel das Datenblatt. Hehe

von Fragender (Gast)


Lesenswert?

Das ist eine Quelle. Du gibst 3 an in deutsch.
Da fehlen noch ein paar.

Das mit einfach ist relativ zu sehen. Ein Neuling (wie ich) braucht 
länger zum verstehen.
Für Informatiker oder Fachmann oder einer der sich mehr damit 
beschäftigt hat, ist es kein Problem.

von Gerhard O. (gerhard_)


Lesenswert?

Seh Dir mal diesen Link von Microchip an:

Beitrag "Re: MCP23017 - Abfrage Taster"

Da wird das sehr ausführlich beschrieben.

Am leichtesten wird es sein wenn Du zuerst den uC so programmierst, dass 
er auf den externen INT0/1 anspricht. Ich nehme es ist ein AVR. Verwende 
nach Möglichkeit nicht die PinChangeInterrupts weil die nicht direkt 
ausgewertet werden können und etwas komplizierter im Gebrauch sind.

Dann programmiere die entsprechenden Register im MCP23017 wie in der 
Appnote gezeigt. Auch nicht vergessen den Tasterpin auf Input mit Pullup 
einzustellen.

Schließe auch einen Pullup am Interruptausgang an. Nicht vergessen das 
Register für die Interrupt Konfigurierung einstellen.

Wenn Du jetzt nach der Initialisierung den Taster drückst müßte jetzt 
der INT Ausgang des zugehörigen Ports auf LOW gehen bis der Interrupt 
vom uC gelesen wird.

Damit das mit dem uC richtig wie gewünscht mußt Du nun aus dem Interrupt 
eine Flag setzen und dann im Main Code am besten mit einer State 
Maschine den MCP23017 auslesen um heraus zu finden welcher Pin für den 
Interrupt verantwortlich war.(Siehe App Note)
Das Lesen der entsprechenden Register bewirkt, daß die Interrupt Flag im 
MCP zurück gesetzt wird und der MCP wieder auf den nächsten Interrupt 
reagieren kann. Nun hat der uC den Port Wert mit dem gesetzten Datenbit, 
daß Du nun in Deinem Program auswerten kannst. Erst dann darf man diese 
Flag wieder zurücksetzen.

So sollte der Ablauf prinzipiell, wie ich es der Dokumentation nach 
verstehe, funktionieren. Ich habe das zwar selber noch nicht mit dem 
MCP23017 gemacht, bilde mir aber ein, daß es so etwa funktionieren 
müßte. Wer da bessere praktische Erfahrungen hat, soll jetzt seinen Senf 
dazudrücken:-)

In Deinem Anwendungsprogram verwendest Du am Besten eine State Maschine 
um das logische Zwischenspiel und Ablauf der Mensch und 
Maschinenschnittstelle sicherzustellen.

Vielleicht kann das jemand anderer an meiner Stelle es besser erklären 
oder Fehler berichtigen. Aber vielleicht hilft es trotzdem.

: Bearbeitet durch User
von Fragender (Gast)


Lesenswert?

Für mich ist das sehr gut. Werde s genau ansehen und umsetzen.
Dake für deine Erklärung

LG F.

von Philipp K. (philipp_k59)


Lesenswert?

Ich habe mal die Miniabsätze aus dem Datasheet übertragen weil ich auch 
immer selbst gucken muss.. können Fehler drin sein, hab den MCP noch 
nicht mit Interrupts benutzt.

MCP 23017 Kurz und Bündig.

Allgemeine Register

IODIR
Direction Register, bestimmt ob ein Pin Input oder Output ist.
1=Input, 0=Output

IPOL
Polaritätsregister, bestimmt die Polarität/Invertierung eines Pins
1=Invertiert, 0=nicht Invertiert

GPIO
InputOutput Register,
LESEN: Eingänge einlesen.
SCHREIBEN: wird ans OLAT Output Register weitergeleitet.
0=LOW, 1=HIGH

OLAT
Output Latch Register,
SCHREIBEN: Setzt die Ausgänge der als Ausgang definierten Pins.
LESEN: Gibt den zuletzt gesetzten Wert zurück.
0=LOW, 1=HIGH

GPPU
Pullup Register, aktiviert den Pullup am Pin.
1=HIGH, 0=LOW


Interrupt Register Konfiguration

Kleine Falle:
Die Interruptverwendung beinhaltet 3 Register. GPINTVEN, DEFVAL, INTCON 
welche alle 3 gesetzt werden müssen.
Wenn der Interrupt für einen Pin mit GPINTVEN aktiviert wird, 
entscheidet INTCON die Datenquelle des Signalvergleichs.
Wenn INTCON 0 ist, wird der Pin mit dem in DEFVAL gesetzten Signal 0/1 
verglichen, sollte INTCON 1 sein wird auf den letzten Pin Status 
verglichen.

INTERRUPT LOGIK

Wenn ein Interrupt generiert wird werden die aktuellen Pin Werte in das 
INTCAP Register gesichert.
Der Interrupt wird gelöscht wenn das LSB Byte beim Lesen der Register 
GPIO oder INTCAP übertragen wurde.


GPINTEN
InterruptOnChange Event  Register, Aktiviert den Interrupt für einen 
Pin.
1=Aktiv, 0=Inaktiv

INTCON
Interrupt Control Register, bestimmt die Quelle der Interrupt On Change 
Quelle
1= Vergleich auf das DEFVAL Register,0= Letzten Status des Pins

DEFVAL
Default Value Register, bestimmt den Standard Vergleichswert des Pins 
wenn INTCON=1
1= HIGH, 0=LOW


*Interrupt Register Status/Information*

INTF
Interrupt Flag Register, beinhaltet den Status der Interruptauslösung.
1=Interrupt ausgelöst, 0=Kein Interrupt vorhanden

INTCAP
Interrupt Capt Register, Speichert den Wert des letzten Pin Status bei 
Interrupt Auslösung.
1=HIGH, 0=LOW



Allgemeine Konfiguration

IOCON
Zwischen Port A und B geteiltes Konfigurationsregister
Bit7: BANK, entscheidet die Sortierung der IO Register,
1=Zuerst alle A Register, danach alle B register
0= Beispiel, GPIOA,GPIOB,IPOLA,IPOLB

Bit6: MIRROR,
1=A und B teilen sich beide Interrupt Pins INTA und INTB
0=INTA ist für A und INTB für B

Bit5: SEQOP, Sequentielles Lesen/Schreiben
1= Deaktiviert
0=Aktiviert

Bit4: DISSLW, i2C Slew Rate Clock Stretching Ein/Ausschalten
1=Deaktiviert
0=Aktiviert

Bit3: HAEN: Address Pins aktivieren/Deaktivieren
1=Aktiviert0=Deaktiviert

Bit2: ODR Konfiguration INTA, INTB Open-Drain Option
1=Open-Drain
0=Aktiver Treiber

Bit1: INTPOL Interrupt PIN Polarität, Invertiert die Interrupt Pins.

Bit0: Nicht benutzt.

: Bearbeitet durch User
von Fragender (Gast)


Lesenswert?

Hallo Philipp
danke für deine Arbeit.
Hatte auch angefangen es so zu machen. Leider kommt durch Google nicht 
die beste übersetzung. Zum ersten Verständnis hat es gereicht. Leider 
gabe es danach mehr Fragen als Antworten. Besonders interessant finde 
ich deine Hinweise auf Fallen und anderes dazu. Wirklich ganz toll. 
Danke noch mal.

Auch für andere. Ein paar Problem sind damit lösbar. Es gibt aber noch 
viel zu tun

LG F.

PS,:  schöne Ostern an alle Neugierigen und Leser

von Wolfgang R. (wolfgang_r)


Lesenswert?

Fragender schrieb:
> Hatte auch angefangen es so zu machen. Leider kommt durch Google nicht
> die beste übersetzung.

www.deepl.com ist als Übersetzer für ganze Sätze deutlich besser als 
Google. Die Ergebnisse sind (in beide Richtungen) besser formuliert und 
besser verständlich als Google.

Auch ich empfinde den MCP23017 als einen eher einfachen Baustein und man 
kann ausreichend viele Beispiele ergoogeln. Allerdings merke ich nicht 
mal bewusst, ob diese in deutsch oder englisch sind. So gefühlte 80-90% 
sind in englisch. Versuche dich mit "englisch lesen" anzufreunden.

Ich meine, noch das Schwierigste am MCP23017 ist die Interrupt 
Konfiguration. Daher würde ich empfehlen, dass du zunächst beim zyklisch 
Abfragen (Polling) bleibst und wenn du mit dem MCP warm geworden bist 
und er dir "gehorcht" (und du auch weißt warum) - dann würde ich mit den 
Interrupts anfangen (falls überhaupt in der Anwendung nötig).

von Philipp K. (philipp_k59)


Lesenswert?

Fragender.

Du fragst Dich zuviel.

Das ist alles was an Infos im Datasheet steckt.

Es gibt halt noch einige wenige Punkte die ich nicht erwähnt habe.

Die Fragt sich aber bestimmt niemand der noch am Anfang steht und 
nichtmal die Basics ausprobiert hat.

P.S.: Das Datasheet besteht zu Hälfte aus großen Texten, mehrere Seiten 
haben keinen wirklichen Inhalt.

Im Endeffekt ist nur eine Seite über die Interrupts voll beschrieben. 
Also im Prinzip was man sich Fragen kann, wird auf nur einer Textseite 
im datasheet erklärt.

: Bearbeitet durch User
von Fragender (Gast)


Lesenswert?

Danke für eure Info und Hinweise. Bin dabei mich mit MCP auseiender 
zusetzen. Das mit dem englisch geht schon so. Leider gibt es dabei immer 
wieder Probleme mit dem Verstehen dazu.
Werde deine Seite gleich aufsuchen. Wenn sie wirklich besser istwird sie 
zu meinem Standart
Danke

LG F.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.