I2C - Pull Up Widerstände

Gast #5086223
Lesenswert?

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
Gast #5086251
Lesenswert?

> 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."
Gast #5086266
Lesenswert?

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.
Gast #5086273
Lesenswert?

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.
Gast #5086290
Lesenswert?

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.
Gast #5086310
Lesenswert?

"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?
Gast #5086380
Lesenswert?

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?
Gast #5086385
Lesenswert?

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
Gast #5086388
Lesenswert?

> 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 ...
Gast #5086394
Lesenswert?

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  ?
#5086412
Lesenswert?

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
Gast #5086424
Lesenswert?

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!
Gast #5086451
Lesenswert?

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?
#5086468
Lesenswert?

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
Gast #5086499
Lesenswert?

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
Gast #5086500
Lesenswert?

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?
Angehängte Dateien:
Gast #5086569
Lesenswert?

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
Gast #5086579
Lesenswert?

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.
Gast #5086597
Lesenswert?

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
Gast #5086708
Lesenswert?

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.
Gast #5086795
Lesenswert?

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?
Gast #5086806
Lesenswert?

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)
Gast #5086854
Lesenswert?

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).
Gast #5086878
Lesenswert?

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
Gast #5086980
Lesenswert?

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.
Gast #5087033
Lesenswert?

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.
Gast #5087049
Lesenswert?

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
Angehängte Dateien:
Gast #5087095
Lesenswert?

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.
Gast #5087131
Lesenswert?

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.
Gast #5087156
Lesenswert?

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!?
Gast #5087222
Lesenswert?

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.
#5087253
Lesenswert?

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
#5087272
Lesenswert?

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
Gast #5087305
Lesenswert?

> 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.
Gast #5087355
Lesenswert?

@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.
Gast #5087400
Lesenswert?

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();
Gast #5087434
Lesenswert?

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 von einem Moderator gelöscht.
Gast #5089730
Lesenswert?

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?
Gast #5089954
Lesenswert?

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.
Gast #5089995
Lesenswert?

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.
Gast #5090010
Lesenswert?

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? >.<
#5090054
Lesenswert?

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.
Gast #5090335
Lesenswert?

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€
Gast #5090391
Lesenswert?

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
#5100629
Lesenswert?

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.
Gast #5100687
Lesenswert?

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
Gast #5100754
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren