Hallo,
ich versuche mich zur Zeit mit dem I2C Schnittstelle zu beschäftigen.
Dazu habe ich mehrere IC´s bestellt, die den I2C unterstützen z.B. den
MCP23107.
Darum geht es erstmal nicht.
Im Datenblatt von Atmel steht, dass für den I2C 2 Pull Up Widerstände
gebraucht werden für die SDA und SCL Leitungen.
Kann ich nicht die Internen Pull Ups verwenden?
Der Clock, also SCL könnte ich quasi als Ausgang schalten und dann den
Pull Up aktivieren. Wie mache ich das mit der SDA Leitung? Dort ist der
PIN mal Eingang und Ausgang.
Lg
> Kann ich nicht die Internen Pull Ups verwenden?
Der Pullup-Widerstand bildet zusammen mit den unweigerlich vorhandenen
Kapazitäten ein RC-Glied, hier einen Tiefpass. Wie dieser Begriff
impliziert, werden Signale geschwächt, je höher deren Frequenz ist.
Fazit: Je nach Aufbau und angeschlossenen Einheiten kann es reichen oder
auch nicht. Schreibt ja auch Atmel: "The internal pull-ups can in some
systems eliminate the need for external ones."
Teddy schrieb:> z.B. den MCP23107
Was soll das sein?
> Kann ich nicht die Internen Pull Ups verwenden?
Wenn du Soft-I2C machst und die Pull-Ups deines (unbekannten) µC
ausreichend niederohmig sind, kannst du das machen. Bei Nutzung der
Hardware-Unit für den I2C, wirst du kaum Gelegenheit haben, deinem
Prozessor da rein zu reden.
Wolfgang schrieb:> Bei Nutzung der> Hardware-Unit für den I2C, wirst du kaum Gelegenheit haben, deinem> Prozessor da rein zu reden.
Das verstehe ich nicht. Es geht doch offenbar um einen Atmel-uC, und
selbst der angejahrte ATmega8 hat diese Möglichkeit.
Falls man unbedingt Wert darauf legt, kann man ja die Frequenz
hinreichend absenken.
S. Landolt schrieb:> Das verstehe ich nicht. Es geht doch offenbar um einen Atmel-uC, und> selbst der angejahrte ATmega8 hat diese Möglichkeit.> Falls man unbedingt Wert darauf legt, kann man ja die Frequenz> hinreichend absenken.
20k bis 50k interne Pullup reichen (meist) nicht.
Die vorgeschlagenen 4k7 sind schon mal ein guter Anfang, wenn der Bus
nicht zu lang, oder nicht zu viele Bausteine dran hängen.
Erst ein Oszi schafft Klarheit.
Ein LA ist das falsche Werkzeug, da er die Flanken rechteckig formt, und
einem damit das Wesentliche durch die Lappen gehen kann.
Den LA kann man verwenden, wenn man weiß, dass die Flanken sauber genug
sind.
Bitte die Spezifikation lesen und auch so anwenden.
"Ob die I2C Schnittstelle funktioniert" lässt sich auch mit einem
Oszilloskop nicht feststellen, schließlich geht in die
Funktionsfähigkeit erheblich mehr ein als die elektrischen Verhältnisse
auf dem Bus.
Worin besteht denn das Hindernis, externe Pull-ups zu verwenden?
Teddy schrieb:> wie kann ich ... gucken, ob die I2C Schnittstelle funktioniert?
Du drehst die Frequenz solange höher, bis es nicht mehr funktioniert.
Dann nimmst du sicherheitshalber ein Zehntel davon.
S. Landolt schrieb:> "Ob die I2C Schnittstelle funktioniert" lässt sich auch mit einem> Oszilloskop nicht feststellen, schließlich geht in die> Funktionsfähigkeit erheblich mehr ein als die elektrischen Verhältnisse> auf dem Bus.> Worin besteht denn das Hindernis, externe Pull-ups zu verwenden?
Keine. Werde dies noch machen.
Muss ich die Ports als Ausgänge definieren oder regelt das der I2C
Controller selber?
Teddy schrieb:> Der Clock, also SCL könnte ich quasi als Ausgang schalten und dann den> Pull Up aktivieren. Wie mache ich das mit der SDA Leitung? Dort ist der> PIN mal Eingang und Ausgang.
Unabhängig davon, dass es, wie schon gesagt, mit den internen Pulls
nicht gehen wird:
- Pullups gibts nur, wenn der Pin auf Input steht
- auch ein I2C-Takt darf nicht auf HIGH getrieben werden, der Slave
könnte Clock stretching machen. Das ist zwar bei dem MCP23017 (nicht
23107!) nicht so, aber andere Devices machen das ggf. Man müsste also
beide so bedienen.
Wenn du einen Pinx in einer Funktion wie SDA schalten willst (bei
ATMEL), brauchst du jeweils zwei Befehle:
- HIGH_pulled: DDRx auf Input, PORTx auf '1', aktiviert dann den Pull
- LOW: PORTx auf '0', DDRx auf Output
Mit externen Pullups, die bei I2C notwendig sind, geht das dann so:
- PORTx immer auf '0' lassen
- HIGH: DDRx auf Input
- LOW: DDRx auf Output
> regelt das der I2C Controller selber?
Exemplarisch aus dem Datenblatt des ATmega1284P zu TWCR:
When TWEN is written to one, the TWI takes control over the I/O pins
onnected to the SCL and SDA pins, enabling the slew-rate limiters and
spike filters.
Aber eine Kommunikation im Anderthalbstundenrhythmus liegt mir nicht -
Da sprach der Prinz von Pakistan ...
Was denn nun? Im Datenblatt steht wohl, dass der Controller es
automatisch tut aber Herr HildeK meint, man müsse selber die Ports
definieren.
Was ist mit High und Low gemeint?
Die SDA und SCL Ports liegen im Arduino Boards bei A4 und A5.
Also:
DDRD=0X00
PortD= 0X00 ?
Das müsste HildeK selbst beantworten.
Nach meinem Dafürhalten spricht er von Soft-I2C, dies aber halte ich als
Einstieg für einen Anfänger für wenig geeignet.
Hi
Da es hier, auf ein Mal, um einen Arduino geht - siehe dort bitte in der
entsprechenden Funktion nach, WAS Du beschalten musst.
... gehe davon aus, daß je ein 4K7 als PullUp Verwendung findet ...
Den Rest macht die Lib des Arduino. (also IN/OUT umschalten, Pegel
erfassen und aus dem Müll Bytes raus fischen)
Bei etwas mehr Eigeninteresse hätte Dich wohl eine beliebige
Suchmaschine zu Hintergrundinformationen gebracht - Du hast das Bild der
Arduino-Jünger nicht sonderlich verbessert ...
MfG
Teddy schrieb:> Keine. Werde dies noch machen.> Muss ich die Ports als Ausgänge definieren oder regelt das der I2C> Controller selber?
Genau!
Bau die 4k7 Pullup ein, den Rest macht die Arduino Wire Lib für dich.
Warnung:
Ein paar Arduinos haben die nötigen Pullup schon an Bord.
Prüfe das.
Vorher!
Teddy schrieb:> Was denn nun? Im Datenblatt steht wohl, dass der Controller es> automatisch tut aber Herr HildeK meint, man müsse selber die Ports> definieren.
Ich habe nur exemplarisch aufgezeigt, wie man es machen könnte. Ich habe
nicht den Überblick, ob alle Controler I2C als Hardware unterstützen.
Und du hattest ja bis dahin keinen Controller genannt - oder?
Hi
Welcher µC?
Wenn AVR, die ATtiny können TWI/I²C nicht von Haus aus.
Die ATmega, bei Denen ich bisher rumgeschmökert hatte, wohl schon.
Das Datenblatt des verwendeten µC könnte Klarheit darüber geben, ob die
erforderlichen PullUps in den µC direkt verbaut sind oder ob trotzdem
externe PullUps verwendet werden müssen.
Selber habe ich 'komplett zu Fuß' programmiert mit mäßigem Erfolg (alle
paar tausend Ausgaben macht das Display, was Es will ... oder ich sende
eben Mist).
Umgeschaltet wird hier NUR zwischen IN (ohne PullUp, Der hängt außen
dran) und OUT (dann auf LOW) - da brauchst Du nur für ein HIGH oder das
Einlesen des Pegel den Pin auf IN zu stellen und für ein zu sendendes
LOW den Pin auf OUT umschalten.
Nach der Bitzeit bzw. spätestens nach den Nutzbits wieder auf IN, was
den Bus auf HIGH gehen lässt (wegen der externen PullUp).
Wenn da kein HIGH anliegt, zieht 'wer Anders' am Bus - und dort beginnt
die Kunst, die I²C-Komunikation beschussfest zu machen.
Aktiv können alle Teilnehmer die Drähte bestenfalls auf LOW ziehen.
MfG
Hi
>Selber habe ich 'komplett zu Fuß' programmiert mit mäßigem Erfolg (alle>paar tausend Ausgaben macht das Display, was Es will ... oder ich sende>eben Mist).
Schon mal die Atmel AppNotes versucht?
MfG Spess
Es ist ein Atmega328P. Dieser kann I2C.
Ich habe zur Hand nur 5kOhm Widerstände, diese sollten auch gehen oder?
Ich komme hier eigentlich nicht klar. Ich bin dem Datenblatt und dieser
Seite http://www.embedds.com/programming-avr-i2c-interface/ gefolgt,
jedoch kann ich an einen Pin des MCP23017 nichts schalten.
Es liegt keine Spannung an, mag jemand mal den Code anschauen?
Hi
>Ich bin dem Datenblatt und dieser>Seite http://www.embedds.com/programming-avr-i2c-interface/ gefolgt,>jedoch kann ich an einen Pin des MCP23017 nichts schalten.
Liegt es jetzt an den I2C-Routinen oder am Verständnis des MCP23017? Für
jemand, der noch nie I2C programmiert hat hätte ich etwas einfacheres
empfohlen.
MfG Spess
Hi
>Beides. Ist hart da von Null auf durchzublicken.
Warum fängst du dann mit Secondhand Software an, und nicht mit den Atmel
Appnotes? Irgendwo bei AVR31.. sollte sich etwas finden lassen.
MfG Spess
spess53 schrieb:> Hi>> Beides. Ist hart da von Null auf durchzublicken.>> Warum fängst du dann mit Secondhand Software an, und nicht mit den Atmel> Appnotes? Irgendwo bei AVR31.. sollte sich etwas finden lassen.>> MfG Spess
Da ich aber bereits an der Sache dran bin, würde ich es gerne zu Ende
machen wollen.
Hi
>Da ich aber bereits an der Sache dran bin, würde ich es gerne zu Ende>machen wollen.
Hast du denn schon mal eine funktionierende Verdindung zu I2C-Slave
hergestellt?
MfG Spess
Hi
>Hast du denn schon mal eine funktionierende Verdindung zu I2C-Slave>hergestellt?
Korrektur;
Hast du denn schon mal eine funktionierende Verdindung zu Irgend einem
I2C-Slave hergestellt?
MfG Spess
spess53 schrieb:> Hi>>>Hast du denn schon mal eine funktionierende Verdindung zu I2C-Slave>>hergestellt?>> Korrektur;>> Hast du denn schon mal eine funktionierende Verdindung zu Irgend einem> I2C-Slave hergestellt?>> MfG Spess
Scheint leider nicht zu funktionieren.
Nachdem ich die Adresse 0x20 gesendet habe, wird ja im Status Register
ein Flag gesetzt. Diese überprüfe ich gemäß Datenblatt.
Wird sie erfüllt, ok. Wenn nicht, dann soll bei mir eine LED leuchten.
Und sie leuchtet >.<
ergo, läuft nicht.
Ich habe zu Testzwecken eine fertige Arduino Bibliothek heruntergeladen,
um zu Überprüfen, ob mein Aufbau ersten in Ordnung ist und zweitens, der
Chip funkioniert.
Letzendlich ist beides okay.
Das heißt, der Wurm sitzt irgendwo in meinem Programm Code.
Diese habe ich zuvor hochgeladen.
spess53 schrieb:> Hi>>>Hast du denn schon mal eine funktionierende Verdindung zu I2C-Slave>>hergestellt?>> Korrektur;>> Hast du denn schon mal eine funktionierende Verdindung zu Irgend einem> I2C-Slave hergestellt?>> MfG Spess
Ich glaube, jetzt habe ich die Verbindung zum Slave hergestellt.
Die eingegebene Adresse war anscheinend falsch.
Die Adresse lautet gemäß Seite 8 von dem MCP Manual 0x40, wenn ich A0,
A1 und A2 auf 0 lege.
Oder interpretiere ich das falsch?
Teddy schrieb:> Die Adresse lautet gemäß Seite 8 von dem MCP Manual 0x40, wenn ich A0,> A1 und A2 auf 0 lege.> Oder interpretiere ich das falsch?
0x40 ist der Wert des ersten Bytes bei einem Schreibzugriff.
Die Slave Adresse für A0..2=0 ist immer 0x20 (Datenblatt Fig. 1-2)
Teddy schrieb:> Da steht dann aber> 0100 0000 = 0x40
Eben, das Control Byte ist 0x40 und setzt sich zusammen aus der I2C
Slave Adresse in den ersten 7 Bit (0b0100000) und dem R/W Bit an
unterster Stelle, zusammen
Teddy schrieb:> Da steht dann aber> 0100 0000 = 0x40
Das ist die Slaveadresse incl. R/W-Bit. Oft werden I2C-Adressen auch
ohne R/W-Bit angegeben. Das wäre hier dann 0x20.
Bei I2C heißt es immer Aufpassen, ob 7- oder 8-Bit Adressen gemeint
sind.
Dann stehe ich gerade auf dem Schlauch und komme nicht weiter.
Die Adresse 0x20 wird eingegeben und versendet, aber es taucht immer die
Fehlermeldung auf, dass die Adresse anscheinend nicht stimmt, oder der
ACK Bit vom Slave nicht empfangen werden konnte.
Habe auf die Fehlermeldung 0x18 und 0x20 geprüft (siehe Seite 273 vom
Atmega 328P Datenblatt).
Wolfgang schrieb:> 0x40 ist der Wert des ersten Bytes bei einem Schreibzugriff.> Die Slave Adresse für A0..2=0 ist immer 0x20 (Datenblatt Fig. 1-2)
Auch wenn hier verschiedene widersprüchliche Weisheiten
verbreitet werden ist die Adresse für diesen Baustein
immer noch 0x40 für schreiben und 0x41 für lesen (wenn
A0, A1 und A2 = 0).
Auch nach Datenblatt Fig. 1-2
spess53 schrieb:> Hi>>>Dann stehe ich gerade auf dem Schlauch und komme nicht weiter.>> Dann zeige doch mal deine Routine mit der die Adresse gesendet wird.>> MfG spess
Die C Datei habe ich doch hochgeladen.
Aber ich stelle es gerne erneut hoch.
spess53 schrieb:> Hi>>> void I2C_Adresse(uint8_t Adresse)>>{>> TWDR = Adresse;>> In dem Fall muss Adresse aus 0x40 + RW-Bit bestehen (wenn A0/1/2=0> sind).>> MdG Spess
Also war 0x40 doch richtig?
Für schreiben ist RW-Bit 0, also ist die Adresse 0x40.
Da kommt keine Fehlermeldung. Aber dennoch wird nichts durchgeschaltet,
wenn ich den oben genannten Code durchlaufen lasse.
Bei RW-Bit=1 zum schreiben ist die Adresse 0x41 und da kommt wieder die
Fehlermeldung.
Fana Ticker schrieb:> Auch nach Datenblatt Fig. 1-2
In Fig 1-2 hat die Slave Adresse 7 Bit, wie es der I2C-Spezifikation
(S.15) entsprich und genau den Wert 0x20. Was da an Bits rangepfriemelt
ist, ändert nichts an dem Wert.
http://i2c2p.twibright.com/spec/i2c.pdf
Wolfgang schrieb:> Fana Ticker schrieb:>> Auch nach Datenblatt Fig. 1-2>> In Fig 1-2 hat die Slave Adresse 7 Bit, wie es der I2C-Spezifikation> (S.15) entsprich und genau den Wert 0x20. Was da an Bits rangepfriemelt> ist, ändert nichts an dem Wert.> http://i2c2p.twibright.com/spec/i2c.pdf
Du hängst am Ende sozusagen eine Null dran, richtig?
Dann ist die Adresse 0x20.
Aber ich kann doch nur Byteweise senden, d.h. ich nehme den RW-Bit mit
und sage dem Slave, ob er lesen oder schreiben soll.
Mit 0x40 ist die 7 Bit Adresse + RW-Bit enthalten.
Aber es läuft bei mir sowieso nicht.
Hi
>In Fig 1-2 hat die Slave Adresse 7 Bit, wie es der I2C-Spezifikation>(S.15) entsprich und genau den Wert 0x20. Was da an Bits rangepfriemelt>ist, ändert nichts an dem Wert.>http://i2c2p.twibright.com/spec/i2c.pdf
Solange sich die Hersteller nicht 100%-ig daran halten bleibt das graue
Theorie. Einige Hersteller geben gleich beider Werte (Anhang) an.
MfG Spess
Hallo Jungs,
leider bleibt der Durchbruch aus.
Ich krieg es nicht hin.
Die Sendung der Adresse 0x40 scheint zu funktionieren, es taucht keine
Fehlermeldung auf. Aber wenn ich statt schreiben, lesen will (0x41),
dann kommt wieder die Fehlermeldung auf.
Die Fehlermeldung wird in Form einer LED gekennzeichnet. (siehe oben in
der C-Datei)
In der Main steht folgendes:
int main(void)
{
DDRB=0x01;
PORTB=0x00;
I2C_Init();
I2C_Start();
I2C_Adresse(0x40);
I2C_Senden(IODIRA); //IODIRA = 0x00
I2C_Senden(0x00); //Alle Ports von A auf Ausgang
I2C_Senden(OLATA); //OLATA = 0x14
I2C_Senden(0xFF); //Alle Ports von A auf HIGH
I2C_Stop();
}
Die einzelnen Funktionen sind oben in der Datei beschrieben.
Vielleicht sehe ich den Wald vor lauter Bäumen nicht.
Fana Ticker schrieb:> Auch wenn hier verschiedene widersprüchliche Weisheiten> verbreitet werden ist die Adresse für diesen Baustein> immer noch 0x40 für schreiben und 0x41 für lesen (wenn> A0, A1 und A2 = 0).
Du willst es nicht begreifen.
Die I2C-Spezifikation kennt nur 7-Bit Adressen. Wenn jemand eigene
Bezeichnungen einführt, soll er das nicht als I2C-Adresse bezeichnen.
Irreführende Funktionsnamen für Funktionen, denen das fertig
zusammengebaute Control-Byte übergeben werden muss (
"I2C_Adresse(0x40)", sind da mit eingeschlossen.
Wolfgang schrieb:> Fana Ticker schrieb:>> Auch wenn hier verschiedene widersprüchliche Weisheiten>> verbreitet werden ist die Adresse für diesen Baustein>> immer noch 0x40 für schreiben und 0x41 für lesen (wenn>> A0, A1 und A2 = 0).>> Du willst es nicht begreifen.>> Die I2C-Spezifikation kennt nur 7-Bit Adressen. Wenn jemand eigene> Bezeichnungen einführt, soll er das nicht als I2C-Adresse bezeichnen.> Irreführende Funktionsnamen für Funktionen, denen das fertig> zusammengebaute Control-Byte übergeben werden muss (> "I2C_Adresse(0x40)", sind da mit eingeschlossen.
Da du hier anscheinend besser auskennst.
Weiß du warum es bei mir nicht funktioniert!?
Hi Jungs,
ich komme nicht voran. Ihr müsst mir die Lösung nicht sagen, aber es
würde mir helfen, wenn ihr mir ein Tipp/eine Richtung geben könntet wo
ich weitersuchen kann.
Danke. Der Gewinner bekommt am Ende einen Eis, versprochen.
Teddy,
Jetzt will ich's mal versuchen:
An Deiner Stelle würde ich mich bezüglich der Slave Addresse einzig und
alleine ans Datenblatt halten.
Diese Bezeichnung 7-Bit Slave Adresse ist ganz irreführend weil nämlich
in der Realität dieses sogenannte 7-Bit SA mit dem RW Bit verbunden wird
und besteht letztlich IMMER aus einem 8-Bit Datenwort.
Schau Dir mal das Bild vom Spess53 an. Da werden A6 bis A0 angegeben mit
einem Platzhalter Bit für Write oder Read Operation. Somit ist das der
Funktion zugeleitete SA Byte immer 8-bit. Dem PCF8574 sendest Du als
Schreib Byte also 0b01000000 oder 0x40 und 0x41 zum Lesen. Die Addresse
ist dann nicht A6-A0 "010000" oder "00100000" sondern "0100000x" und das
ist immer 0x40 oder 0x41.
Wenn man unsicher ist, immer das Datenblatt zu Rate ziehen und die meist
angegebenen Beispiele studieren. Anhand dieser Diagramme kann man ohne
Zweifel sehen wie der Hase läuft. Nochmals, das SA Wort wird immer als
8-Bit Byte gesendet. Die reine angegebene 7-bit Addresse muß dann immer
um eine Stelle nach links geshiftet werden und das RW Bit dazu gedacht
werden.
Nur die Arduino Wire Bibliothek macht eine Ausnahme. Bei der darf nur
die 7-bit Addresse des ICs weiter gegeben werden. Bei allen anderen
Bibliotheken die mir bekannt sind muß die erweitete 7-bit Addresse als
8-bit Wort mit angefügtem RW Bit in der üblichen Weise angegeben werden.
Als Pull-Ups verwende ich bei normalen 3.3V/5V Systemen meist 3.9K.
Niedriger ist da wegen der unvermeidlichen Verdrahtungskapazitäten
welche die Pulse abrunden eher besser.
Grüße,
Gerhard
Hi
spess53 schrieb:> Schon mal die Atmel AppNotes versucht?
Habe das I2C-Protokoll per Datenblätter und Logik-Analyser erforscht und
hart in Assembler nachgebaut.
Als Quelle diente ein Arduino, Der I2C von Haus aus kann' - Dem habe ich
quasi 'unter den Rock geschaut'.
Die AppNotes habe ich nur überflogen, bekomme beim USI-Zeug irgendwie
Gehirnfrost - da hat sich noch keine Logik ergeben ... die Datenblätter
der ATtiny gehen Da ja auch etwas drauf ein - wird wohl noch werden.
@Teddy
Wo sitzt die besagte Error-LED?
In Deinem Code sehe ich davon nicht viel, auch scheinst Du nur
schreibend auf den Slave zuzugreifen.
Mir ist aber auch nicht ersichtlich, wo das ACK in Deinem Code empfangen
wird - könnte mit meinen eher nicht vorhandenen C-Kenntnissen zusammen
hängen.
MfG
> Aber wenn ich statt schreiben, lesen will (0x41),> dann kommt wieder die Fehlermeldung auf.
In I2C_Adresse:
> if((TWSR & 0xF8)!=0x18)
Den Statuscode 0x18 finde ich nur bei Master Transmitter Mode, nicht im
Receiver Mode.
@Gerhard. Danke für die AUsführungen.
Langsam dämmerts bei mir im Hirn. Es wird zwar denke ich noch bisschen
dauern, bis ich das kapiert habe, aber bin denke ich auf dem richtigen
Weg,.
> In I2C_Adresse:>> if((TWSR & 0xF8)!=0x18)> Den Statuscode 0x18 finde ich nur bei Master Transmitter Mode, nicht im> Receiver Mode.
In der Tat. Da muss ich echt aufpassen und das Senden und Empfangen
nicht vermischen.
Die Hexazahl für das Empfangen lautet dann 0x40.
GUT! Danke.
> @Teddy> Wo sitzt die besagte Error-LED?> In Deinem Code sehe ich davon nicht viel, auch scheinst Du nur> schreibend auf den Slave zuzugreifen.> Mir ist aber auch nicht ersichtlich, wo das ACK in Deinem Code empfangen> wird - könnte mit meinen eher nicht vorhandenen C-Kenntnissen zusammen> hängen.>> MfG
Die LED sitzt eigentlich an einem beliebigen Port. Hier ist es
PORTB=0x01.
Die LED leuchtet immer, wenn die Transaktionen nicht geklappt haben.
Diese frage ich in den IF ANweisungen ab.
Beim Senden der Adresse (im Schreibmodus) z.B. steht:
if((TWSR & 0xF8)!=0x18)
{
PORTB=0x01;
}
Hier wird der Statusregister abgefragt. Der Statusregister TWSR hat die
Bits bei 0xF8, durch das "verUNDen" werden die gesetzten Bits gefiltert
und mit der 0x18 verglichen. 0x18 sagt aus, dass die Adresse erfolgreich
gesendet und das ACK Bit erfolgreich empfangen worden ist (gemäß
Datenblatt).
Falls nicht, soll die LED leuchten.
Dann mache ich bei der Ansteuerung des MCP23017 falsch. Ich glaube ich
schicke die Datenbytes falsch rüber.
Denn wenn ich folgendes sende:
I2C_Init();
I2C_Start();
I2C_Adresse(0x40);
I2C_Senden(IODIRA); //Register für die Richtung des Ports
I2C_Senden(0x00); //Alle Ports von A auf Ausgang
I2C_Senden(OLATA); //Alle Ports von A auf High
I2C_Senden(0xFF);
I2C_Stop();
Kann ich keine Spannungen bei Port A messen.
Vielleicht vereinzeln, also:
I2C_Init();
I2C_Start();
I2C_Adresse(0x40);
I2C_Senden(IODIRA); //Register für die Richtung des Ports
I2C_Senden(0x00); //Alle Ports von A auf Ausgang
I2C_Stop();
I2C_Start();
I2C_Adresse(0x40);
I2C_Senden(OLATA); //Alle Ports von A auf High
I2C_Senden(0xFF);
I2C_Stop();
S. Landolt schrieb:> Vielleicht vereinzeln, also:>> I2C_Init();>> I2C_Start();> I2C_Adresse(0x40);> I2C_Senden(IODIRA); //Register für die Richtung des Ports> I2C_Senden(0x00); //Alle Ports von A auf Ausgang> I2C_Stop();>> I2C_Start();> I2C_Adresse(0x40);> I2C_Senden(OLATA); //Alle Ports von A auf High> I2C_Senden(0xFF);> I2C_Stop();
Nein, leider auch nicht.
Ich muss mal das Datenblatt nochmal anschauen.
Christian S. schrieb:> Hallo>> anbei ein Codeschnipsel. Vielleicht wird die Ansteuerung klarer.>> MfG
Bin deinen Code durchgegangen.
Ist fast, was "Daten senden" angeht, das gleiche. Habe einiges
übernommen.
Hat leider nichts gebracht.
Falls du den MCP23017 noch hast, kannst du die Ansteuerung mal mit
meinem Code und Bibliothek probieren?
Könnten wir das aktuelle Programm sehen?
Ich habe hier nur einen MCP23S17, also die SPI-Version, aber ein
minimalistisches Programm mit der zweifachen Sequenz
0x40 0x00 0x00
0x40 0x14 0xFF
schaltet hier GPA auf Vdd.
S. Landolt schrieb:> Könnten wir das aktuelle Programm sehen?>> Ich habe hier nur einen MCP23S17, also die SPI-Version, aber ein> minimalistisches Programm mit der zweifachen Sequenz> 0x40 0x00 0x00> 0x40 0x14 0xFF> schaltet hier GPA auf Vdd.
Bitte sehr. Sind im Anhang.
S. Landolt schrieb:>> Mit IODIRA klappts auch nicht> Schade.>> Und das Vereinzeln hatten Sie ja auch schon probiert!? Vielleicht noch> mal versuchen?
Klaro.
I2C_Init();
I2C_Start();
I2C_Adresse(I2C_Slave_Schreiben);
I2C_Senden(IODIRA);
I2C_Senden(0x00);
I2C_Stop();
I2C_Start();
I2C_Adresse(I2C_Slave_Schreiben);
I2C_Senden(OLATA);
I2C_Senden(0xFF);
I2C_Stop();
Geht auch nicht.
Auch wenn ich mich im Hintergrund halte, bin ich vermutlich kein
Experte.
Habe aber schon erfolgreich deine Bausteine getrieben.
Per Arduino IDE und zugehöriger Lib.
Das würde ich, an deiner Stelle, jetzt genau so machen, und das
Ergebnis, mit LA und Oszi, vergleichen.
Dann erscheint der Fehler.
Ich bin mir da sicher.
Arduino F. schrieb:> Auch wenn ich mich im Hintergrund halte, bin ich vermutlich kein> Experte.> Habe aber schon erfolgreich deine Bausteine getrieben.> Per Arduino IDE und zugehöriger Lib.>> Das würde ich, an deiner Stelle, jetzt genau so machen, und das> Ergebnis, mit LA und Oszi, vergleichen.>> Dann erscheint der Fehler.> Ich bin mir da sicher.
Habe leider kein LA oder Oszi.
Ich denke mit einem LA konnte man den Fehler mit Sicherheit finden.
Wieder Geld ausgeben? >.<
Ein LA ist ein überaus nützliches Hilfsmittel beim Debugging rund um
Mikrocontroller, Bussen und Schnittstellen. Einfache, aber dennoch
brauchbare kosten auch kein Vermögen. Such z.B. auf eBay mal nach "Logic
Analyzer Compatible Saleae" - Kosten < 6€
Die Software dazu hat in der Regel auch Protocol-Analyser für die
zumindest gebräuchlichsten Protokolle wie I2C, SPI, UART etc. Damit
sieht man nicht nur die Signale, sondern auch was sie bedeuten. Bei I2C
z.B. die Start- und Stop-Condition, Adressierung, das ACK-Bit usw.
Das erleichtert die Fehlersuche ungemein.
Wolfgang schrieb:> Teddy schrieb:>> Ich denke mit einem LA konnte man den Fehler mit Sicherheit finden.>> Wieder Geld ausgeben? >.<>> An den 7€ kann es doch nicht liegen.> Ebay-Artikel Nr. 131752135890
7€? Wie zuverlässig ist das Ding? Ich gebe gerne bis 50€ aus.
Leider sind die guten anscheinend ab 100€
Teddy schrieb:> 7€? Wie zuverlässig ist das Ding? Ich gebe gerne bis 50€ aus.> Leider sind die guten anscheinend ab 100€
Wieviele Biere bekommst du in deinem Lieblingsbiergarten für 7€? Und wie
schnell ist der eine Teil davon im Kopf und der andere Teil in der
Schüssel?
Kauf 7 Stück a 7€, sind knapp 50. Dann kannst du 6 mal einen fatalen
Fehler beim Benutzen machen und hast noch ein Leben über. Ob die "guten"
so viel besser sind, daß da nie ein Fehler passiert?
Ein Gerät, bei dem die Eingänge unzerstörbar sind bekommt man aber auch
für 100€ nicht.
MfG Klaus
Prinz von Pakistan schrieb:> Nach meinem Dafürhalten spricht er von Soft-I2C, dies aber halte ich als> Einstieg für einen Anfänger für wenig geeignet.
Eher umgekehrt, SW-I2C ist einfach, robust und portabel. Man muß ja nur
die 4 Grundfunktionen (Start, Stop, Byte lesen, Byte schreiben)
implementieren und dann benutzen. Benutzt man nur Slaves mit
SCL-Eingang, kann man den SCL-Pin als Push/Pull programmieren, d.h. den
Pullup sparen.
Insbesondere das HW-I2C der AVRs ist recht zickig, wenn längere
Leitungen dran hängen und Störungen einkoppeln können. Da kann es sich
schonmal komplett aufhängen.
Ich habe es nur mit einem Watchdog zuverlässig zum Laufen gebracht. D.h.
ein Timerinterrupt schlägt zu, wenn es sich zwischen Start und Stop
aufhängt, disabled es, macht bis zu 9 SCL-Takte, bis SDA wieder high ist
und startet den unterbrochenen Transfer neu.
Nur das HW-I2C der original Philips P80C552, P89C668 hat bei mir 100%
zuverlässig funktioniert. Den Watchdog mußte ich erst beim Umstieg auf
Atmel nachträglich einbauen, da ja NXP seine 8051-er eingestampft hat.
S. Landolt schrieb:> Der Pullup-Widerstand bildet zusammen mit den unweigerlich vorhandenen> Kapazitäten ein RC-Glied, hier einen Tiefpass.
Mal langsam, das würde ja bedeutet, dass die Widerstände zu KLEIN wären!
Dem ist aber nicht so! Die internen pullups sind meistens zu GROSS!
Typisch sind 3k3 oder 4k7 für einen Teilnehmer bis hin zu 1,2k für 15
Teilnehmer.
Die Eingangskapazität liegt dann bei etwa einem halben Nanofarad und das
ergibt immer noch eine ausreichend hohe Grenzfrequenz
Gerhard O. schrieb:> Diese Bezeichnung 7-Bit Slave Adresse ist ganz irreführend weil nämlich> in der Realität dieses sogenannte 7-Bit SA mit dem RW Bit verbunden wird> und besteht letztlich IMMER aus einem 8-Bit Datenwort.
Das gilt aber nur für Leute, die ansonsten noch nie ein etwas
aufwändigeres Protokoll gesehen haben. Das sich in einem Oktet mehr als
nur ein Feld befindet, ist da absolut üblich. Schau dir nur mal die
Oktets in einem HDLC Frame an. Und da kommt auch niemand auf die Idee,
N(R), N(S) und Poll-Bit in einen Klump zu hauen, nur weil alle in einem
Oktet liegen. Der Fall von 2 Feldern, Adresse und R/W Bit ist da eher
was ganz simples.
Um das ganze etwas leichter zu machen, wird im Standard von I2C-Adresse
und vom Adress-Byte, gesprochen. Da das bei den Arduino-Leute wohl immer
noch zu Verwechselungen geführt hat (beides fängt mit A an), wird auch
der Begriff Control-Byte für das erste Byte eines I2C-Frames verwendet.
MfG Klaus