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
Hi >Kann ich nicht die Internen Pull Ups verwenden? Die sind zu groß. Lies mal https://www.nxp.com/documents/user_manual/UM10204.pdf MfG Spess
> 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."
Der Link oben gibt die Antwort auf Deine Frage in Kapitel 3.1.1 und Kapitel 7
S. Landolt schrieb: > werden Signale geschwächt Da hat mal jemand oszillographiert: Beitrag "Re: Leonardo Pro Micro mit OLED" :-) LG old.
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.
Ich habe keinen Oszi, wie kann ich mit einem Handmultimeter oder mit paar elektronischen Bauelementen gucken, ob die I2C Schnittstelle funktioniert?
"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
Es ist ein Arduino Board, aber programmiert wird über das Atmel Studio.
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!
Ähh eben nicht. Ich greife nicht auf die Arduino Libs sondern programmiere zu Fuß wie ich nur den Avr Chip habe.
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.
Ich hänge hier noch die If Abfrage ein. Dieser steht in der I2C_Senden Funktion: if((TWSR & 0xF8)!=0x18) { PORTB=0x01; }
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
1 | 0x40 = 0x20 << 1 | RW |
.
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).
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
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.
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
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.
Beitrag #5087467 wurde vom Autor gelöscht.
Hallo anbei ein Codeschnipsel. Vielleicht wird die Ansteuerung klarer. MfG
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.
> Bitte sehr.
Danke schön.
Was passiert, wenn Sie in main statt
I2C_Senden(IOCON);
I2C_Senden(IODIRA);
schreiben?
Ich habe ehrlich gesagt keine Ahnung warum da IOCON steht, da sollte IODIRA stehen. Mit IODIRA klappts auch nicht.
> Mit IODIRA klappts auch nicht
Schade.
Und das Vereinzeln hatten Sie ja auch schon probiert!? Vielleicht noch
mal versuchen?
PS: denn ich kann in Fig. 1-1 bei write keine Möglichkeit zum Hintereinanderschachteln erkennen.
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.
S. Landolt schrieb: > Tja, jetzt bin ich am Ende. Sorry. Schade. Es gibt sicher andere Experten hier, aber sie halten sich im Hintergrund. Schade.
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.
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. http://www.ebay.com/itm/131752135890
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
Teddy schrieb: > Habe leider kein LA oder Oszi. > Wieder Geld ausgeben? >.< Teddy schrieb: > 7€? Wie zuverlässig ist das Ding? Ich gebe gerne bis 50€ aus. Such Dir einen aus: http://sigrok.org/wiki/Supported_hardware#Logic_analyzers
Ich habe es jetzt geschafft. Die ANsteuerung der Ausgänge erfolgt über GPIOA/B und nihct über OLATA/B.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.