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.
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?
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.
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);
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.
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.
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.
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.
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.
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.
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
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.
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.
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 RegisterIODIR
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 KonfigurationIOCON
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.
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
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).
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.
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.