Forum: Mikrocontroller und Digitale Elektronik Problem mit I²C-Device


von IsquareC-Hans (Gast)


Lesenswert?

Guten Morgen Leute!

Ich habe mal eine (weitere) Frage zum I²C. Ich arbeite hier mit dem 
MCP3425 und habe ehrlich gesagt so mittleren Erfolg damit :-\

Erst ging garnichts, dann gings, dann wieder nicht...Wenn ich morgens 
meine Schaltung einschalte, dann liefert der ADC stets richtige 
Ergebniss...im Laufe des Tages kommt dann nurnoch Schrott raus. Dann 
geht's mal wieder, dann wieder nicht.

Das ganze passiert so nach und nach beim Debuggen. Zeitweise zieht der 
ADC SDA permament auf low, sodass der uC nichts mehr senden kann, mal 
kommen nur einsen...:-\

Kann es passieren, dass das Slave-Device in irgendeinem State hängen 
bleibt und nicht zurück in den Ursprungszustand kommt? Bald heul ich 
hier echt - das Ding kostet mich wirklich nerven.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Wie lang ist Dein Bus, wie groß sind die PullUps?

von IsquareC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Wie lang ist Dein Bus, wie groß sind die PullUps?

10cm sind die Kabel lang. Die Frequenz liegt bei etwa 300kHz. Pull-Ups 
sind 10k. Das seltsame ist halt nur, dass es immer erstmal geht am 
Anfang, also wenn alles aus dem Power-Up-Status kommt. Dann debugge ich 
immer weiter und dann geht es irgendwann nicht mehr. Dachte natürlich 
immer, es liegt an meiner falschen State-Machine, aber es geht dann ja 
wieder, ohne dass der Code verändert wurde.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

IsquareC-Hans schrieb:
> Dachte natürlich
> immer, es liegt an meiner falschen State-Machine, aber es geht dann ja
> wieder, ohne dass der Code verändert wurde.

Das heißt erstmal gar nichts, wenn das Timing an irgendeiner Stelle 
kritisch ist, oder Busfehler nicht korrekt behandelt werden.

IsquareC-Hans schrieb:
> 300kHz.

IsquareC-Hans schrieb:
> 10k.

Mach die PullUps mal kleiner, würde 4k7 nehmen.

IsquareC-Hans schrieb:
> 10cm sind die Kabel lang.

Liegen SCL und SDA direkt nebeneinander? Übersprechen? Klingeln?

von TK (Gast)


Lesenswert?

Hallo,
es ist ungewöhnlich, dass der ADC den SDA auf L hält. Eigentlich sollte 
das SLAVE-Device nur den SCL auf L halten (Clock-Stretching). Wie 
steuerst Du den IIC an? Benutzt Du aktive Pegel - also treibst Du die 
SCL und die SDA-Leitung? Das wird ja immer wieder gerne gemacht, und 
meist funktioniert das mit vielen SLAVE Devices, kann aber in anderen 
Fällen ganz böse daneben gehen - daher immer nur zwischen Input und 
Output L umschalten. Ich vermute, dass der ADC einen Clock nicht 
erkennt, und daher den letzten SDA-Pegel (könnte sogar der Acknowledge 
sein - der ist nämlich L) festhält.
Ich hatte mal ein ähnliches Problem mit Spike-Clocks - hat mich ca. 3 
Tage für Suche aufgehalten. Erst mit dem Oszi und Impuls-Triggerung habe 
ich den Fehler einkreisen können.
Zu deinen Pull-Ups, die sind auf jeden Fall zu groß (benutze mal 1k8 - 
so wie ich das aus der Spec von Philips rauslese)

Gruß
TK

von IsquareC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Das heißt erstmal gar nichts, wenn das Timing an irgendeiner Stelle
> kritisch ist, oder Busfehler nicht korrekt behandelt werden.

Ja gut, OK. Wie das Device Übertragungsfehler behandelt, weiß ich 
natürlich nicht. Was immer klappt, ist das ACK vom Device. Ändere ich 
die Adresse im Adressbyte, so gibt es auch kein ACK. Kein-ACK -> SCL 
high, SDA high (STOP). Dann sollte ja eigentlich alles von vorne 
losgehen.

Knut Ballhause schrieb:
> Mach die PullUps mal kleiner, würde 4k7 nehmen.

Habe ich auch schon probiert, ändert nichts. Davon mal abgesehen, 
verwendet TI in seinen Code-Beispielen ja sogar die internen Pull-Ups 
des uC...und die liegen ja so bei mehren 10k. Trotzdem - habe ich 
bereits probiert.

Knut Ballhause schrieb:
> Liegen SCL und SDA direkt nebeneinander? Übersprechen? Klingeln?

Nee, nicht wirklich. Ich habe noch ein Oszi dran, dachte erst, 
vielleicht ist die Eingangskapazität schon ein Problem, aber ändert auch 
nichts. Es ist sogar so, dass ich manchmal am Punkt der STOP-Bedingung 
bin (schon ausgeführt) und SDA noch auf low ist. Ziehe ich SDA vom MCP 
ab, dann geht es auf high. Der MCP zieht den also runter. Ich habe aber 
auch nirgends im Code stellen, wo z.B. zu wenig Bytes gesendet werden 
o.ä.

Es geht ja auch...theoretisch - nur nicht zuverlässig. Irgendwann kommt 
IMMER folgendes (M)aster / (S)LAVE: (M)START (M)11010001 (S)ACK 
(S)00000001 (M)ACK (S)11111111 (M)ACK (S)11111111 (M)ACK (M)STOP

Gesendet werden soll ja: Adresse, Datenbyte 1, Datenbyte 2, Config-Byte 
mit Status.

Aber es läuft immer auf dieses Muster hinaus.

von IsquareC-Hans (Gast)


Lesenswert?

TK schrieb:
> Wie
> steuerst Du den IIC an? Benutzt Du aktive Pegel - also treibst Du die
> SCL und die SDA-Leitung? Das wird ja immer wieder gerne gemacht, und
> meist funktioniert das mit vielen SLAVE Devices, kann aber in anderen
> Fällen ganz böse daneben gehen - daher immer nur zwischen Input und
> Output L umschalten.

Ich schalte um. Benutze das uC-interne I²C-Feature.

TK schrieb:
> Ich vermute, dass der ADC einen Clock nicht
> erkennt, und daher den letzten SDA-Pegel (könnte sogar der Acknowledge
> sein - der ist nämlich L) festhält.

Aber sein ACK kommt ja nach dem Senden des Adressbytes vom Master. Und 
das letzte Bit ist da High wegen Lesen. Dann kommt ein CLK-Puls und der 
Slave zieht den SDA ordnungsgemäß auf low für das ACK.

TK schrieb:
> Ich hatte mal ein ähnliches Problem mit Spike-Clocks - hat mich ca. 3
> Tage für Suche aufgehalten. Erst mit dem Oszi und Impuls-Triggerung habe
> ich den Fehler einkreisen können.

Da bin ich mittlerweile auch angekommen :-\ Sitze hier auch vorm Oszi 
fest.

TK schrieb:
> benutze mal 1k8

Noch kleiner als 4k7? Bei der niedrigen Frequenz? Ich werds probieren.

von TK (Gast)


Lesenswert?

Bist Du sicher, dass der Master nach dem letzten Byte ein ACK senden 
muss?
Bei EEPROMs muss hier nämlich ein NACK gesendet werden, damit das Device 
das Ende der Übertragung erkennt. Und dann kommt ein Stopp.

Gruß
TK

von IsquareC-Hans (Gast)


Lesenswert?

TK schrieb:
> Bist Du sicher, dass der Master nach dem letzten Byte ein ACK senden
> muss?

Auch da hab ich leider schon alles ausprobiert :-\ Momentan sende ich 
ein NACK, dann STOP. Obwohl ein STOP nach einem NACK ja eigentlich eh 
praktisch nicht geht, da SDA ja schon auf high ist und somit kein 
Wechsel von low auf high bei bereits high-stehender SCL-Leitung möglich 
ist.

von IsquareC-Hans (Gast)


Lesenswert?

Jetzt gerade geht's übrigens schon seit ner Stunde...abwarten.

von Ralf (Gast)


Lesenswert?

> Auch da hab ich leider schon alles ausprobiert :-\ Momentan sende ich
> ein NACK, dann STOP. Obwohl ein STOP nach einem NACK ja eigentlich eh
> praktisch nicht geht, da SDA ja schon auf high ist und somit kein
> Wechsel von low auf high bei bereits high-stehender SCL-Leitung möglich
> ist.

Schau dir das I2C Protokoll nochmals genau an. Ein Stop geht
sehr wohl und ist sogar eindeutig. Vieleicht liegt es ja gerade daran.

Ralf

von IsquareC-Hans (Gast)


Lesenswert?

Ralf schrieb:
> Schau dir das I2C Protokoll nochmals genau an. Ein Stop geht
> sehr wohl und ist sogar eindeutig.

Ich habe mir das alles bereits mehrfach angeguckt. Was habe ich denn 
dann genau nicht verstanden?

Wenn ein NACK vom Master kommt, dann ist danach SDA high und SCL auch, 
da IDLE high. Ein STOP ist ein Wechsel von low nach high während SCL 
high ist.

Oder was check ich grad nicht?

P.S.: Noch läufts, hab aber auch noch nicht debugged...:-\

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

Du bist doch der Master, d. h. du steuerst das ACK/NACK
Signal, dann musst du es halt vor der naechsten SCL Flanke
wieder auf low setzen.

von IsquareC-Hans (Gast)


Lesenswert?

OK, aber mein USI-Modul für den I²C belässt den SCL nach dem 8. Bit ja 
auf high. Dann kommt mein NACK/ACK, also geht SCL wieder auf low, setzt 
SDA, dann SCL wieder high um das Bit in den Slave zu takten und dann 
bleibt es wieder im IDLE high. In dem Bild geht SCL erstmal wieder auf 
low und dann wieder auf high, während SDA auf low ist, was einem ACK 
nach einem NACK gleicht. Dann OK, kommt SDA auf high, während SCL schon 
high ist. Das entspricht STOP.

von Ralf (Gast)


Lesenswert?

Ich komme eher aus der FPGA Ecke und meine
I2C Master im FPGA funktionieren alle auf
diese Weise (wie im PDF). Damit hatte ich
noch nie Probleme und die laufen stundenlang.
So ist es uebrigens auch in der I2C Bus
Specification von Philips beschrieben.

von Klaus (Gast)


Lesenswert?

Ich hab öfter erlebt, daß ein I2C Slave hängt. Das passiert z.B. bei 
einem Read, wenn kein Byte gelesen oder das letze nicht mit NACK geholt 
wird. Ein Stop danach löst das Problem nicht. Als Abhilfe takte ich die 
SCL Leitung mindestens 9 mal. Danach geht alles wieder.

MfG Klaus

von IsquareC-Hans (Gast)


Lesenswert?

Ralf schrieb:
> Ich komme eher aus der FPGA Ecke und meine
> I2C Master im FPGA funktionieren alle auf
> diese Weise (wie im PDF). Damit hatte ich
> noch nie Probleme und die laufen stundenlang.
> So ist es uebrigens auch in der I2C Bus
> Specification von Philips beschrieben.

OK. Aber ist verständlich was ich meine? Es ist ja wirklich ein extra 
CLK-Puls. Also ein Bit mehr. :-\

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

Ich versteh nicht so recht was du meinst.
Du hast genau 9 steigenende SCL Flanken
die ersten 8 sind das Byte und der 9. ist
das ACK/NACK. Dananch geht das ACK/NACK
auf low solange SCL noch auf low ist.
Jetzt sind SCL und SDA auf low. Dann
kommt die Stop Sequenz (das waere dann
die 10. steigende SCL Flanke).
Schau mal ins angehaengte PDF FIg. 10
auf Seite 13.

von IsquareC-Hans (Gast)


Lesenswert?

So, jetzt habe ich wieder das Problem. Flashe ich das Programm während 
des Betriebes neu drauf, dann kommt wieder das bekannte Muster. Ziehe 
ich den Strom ab und stecke ihn wieder dran, dann gehts. Das Ding hängt 
irgendwie.

von IsquareC-Hans (Gast)


Lesenswert?

Ralf schrieb:
> Du hast genau 9 steigenende SCL Flanken
> die ersten 8 sind das Byte und der 9. ist
> das ACK/NACK.

In dem Bild hast du 10 steigende CLK-Flanken. Ich kann in meinem 
USI-Modul garnicht SCL nochmal händisch auf low bringen. Das ist durch 
das Special-Function gesperrt.

von IsquareC-Hans (Gast)


Lesenswert?

OK, ich probiere jetzt mal erst noch ein low nach dem N/ACK und dann 
STOP. Also ein Bit mehr

von IsquareC-Hans (Gast)


Lesenswert?

Ich verstehe die Welt nicht mehr...

Guckt mal bitte der Code hier:
1
switch( mcp3425_control.sm_state )
2
...
3
4
case SM_GENERATE_START_AND_SEND_ADDRESS:
5
{
6
  USISRL = 0x00; // Output latch to 0x00 (SDA), CLK is high -> START
7
  USICTL0 |= USIGE | USIOE; // Enable output and make latch transparent
8
  USICTL0 &=~USIGE; // Latch back to shift clock controlled
9
10
  if( mcp3425_control.flags )
11
  {
12
    if( mcp3425_control.flags & MCP3425_WRITE_CONFIG_FLAG )
13
    {
14
      USISRL = 0x00; // Write operation -> LSB '0'
15
    }
16
  }
17
  else
18
  {
19
    USISRL = 0x01; // Read operation -> LSB '1'
20
  }
21
22
  USISRL |= MCP3425_DEVICE_CODE | MCP3425_ADDRESS;
23
  USICNT |= 8;
24
25
  mcp3425_control.sm_state = SM_RECEIVE_N_ACK;
26
27
  break;
28
}
29
30
...

So...das funktioniert nicht. Wenn ich es reinflashe, dann kommt als 
Antwort wieder nur 00000001 11111111 11111111...und das dauerhaft.

Wenn ich jetzt aber:
1
  if( 0 )
2
  {
3
    if( mcp3425_control.flags & MCP3425_WRITE_CONFIG_FLAG )
4
    {
5
      USISRL = 0x00; // Write operation -> LSB '0'
6
    }
7
  }
8
  else
9
  {
10
    USISRL = 0x01; // Read operation -> LSB '1'
11
  }

...dann geht es nicht direkt, aber wenn ich den Strom neu dranstecke.

Und glaubt mir, .flags ist 0x00. Wenn ich da nen Breakpoint reinsetze, 
wird die Stelle nie erreicht.

Ich habe jetzt übrigens den 10. Clock-Puls drin. Ist wohl besser und 
scheint auch so zu müssen, hab nochmal ins DB geguckt.


ABER: WAS IST HIER LOS?

von IsquareC-Hans (Gast)


Lesenswert?

Also dieses Phänomen ist absolut reproduzierbar!

Bitte Leute, helft mir :-\

von Peter D. (peda)


Lesenswert?

IsquareC-Hans schrieb:
> Wenn ein NACK vom Master kommt, dann ist danach SDA high und SCL auch,
> da IDLE high. Ein STOP ist ein Wechsel von low nach high während SCL
> high ist.

Das ist aber nicht I2C konform.

Ist eine Aktion abgeschlossen, wird das Interruptflag gesetzt und SCL 
auf low gehalten.
Dann kannst Du das Ereignis behandeln und die nächste Aktion 
vorbereiten. Und erst ganz zum Schluß mußt Du das Interruptflag löschen. 
Damit wird gleichzeitig die nächste Aktion gestartet. Löcht man das 
Interruptflag vorzeitig, gibts natürlich Chaos.
Daß SCL auf low bleibt, solange der Interrupt nicht abgearbeitet ist, 
ist auch wichtig für Slave-I2C. Damit signalisiert der Slave dem Master, 
daß er noch warten muß.
Einzige Ausnahme ist das STOP, danach wird kein Interrupt ausgelöst und 
somit SCL auch nicht auf low gehalten.

Das ist zumindest das Verhalten des original Philips HW-I2C.
Kann sein, daß andere Hersteller sich nicht daran halten und dadurch 
Ärger machen.


Peter

von IsquareC-Hans (Gast)


Lesenswert?

Also bei mir bleibt SCL nach jedem fertigen Byte, oder auch nach einem 
ACK auf high. Egal, ob Interrupt-Flag vor oder nach Operation gelöscht.

Dann brauche ich wohl den letzten zusätzlichen Takt nach dem Stop-Bit 
auf jeden Fall. Also nach dem NACK noch ein zusätzliches low, danach ist 
SCL auf high und das zu der Zeit "lowe" SDA ziehe ich dann auf high.

Sehe ich das richtig?

von Peter D. (peda)


Lesenswert?

IsquareC-Hans schrieb:
> Also bei mir bleibt SCL nach jedem fertigen Byte, oder auch nach einem
> ACK auf high.

Das ist trotzdem falsch.

Dann wärs vielleicht endlich mal an der Zeit, uns das aller wichtigste 
mitzuteilen.

Was für ein MC?
Deinen I2C-Code dazu.

Ansonsten könnte man noch viele Jahre weiter im Nebel stochern.


Peter

von IsquareC-Hans (Gast)


Angehängte Dateien:

Lesenswert?

So, jetzt melde ich mich mal zurück.

Peter Dannegger schrieb:
> Was für ein MC?

Ein MCP430G2402. Ich benutze das integrierte USI-Modul, welches ein 
bisschen Unterstützung für I²C mitbringt, aber nicht den vollen Umfang, 
wie die großen USCI-Module hat.

Hauptaugenmerk meines Interesses liegt momentan an dem Von Peter 
angesprochenen Differenz zwischen Spezifikation und Realität hier beim 
USI-Modul.

Meinen Quelltext werde ich gleich mal anhängen. Vorab habe ich aber 
erstmal das Senden eines Config-Bytes an den ADC mit dem Oszi 
aufgefangen. Die Pegel, bzw. der gesamte Datenstrom für das Senden ist 
jetzt ersichtlich und gleicht auch exakt dem, wie er im DB vom MCP3425 
vorgesehen ist.

Es sind insgesamt 19 steigende Flanken vom CLK-Signal, ein Bit musste 
ich dafür aber zusätzlich einfügen, da es vom USI-Modul her nicht von 
alleine kommt. Wie gesagt, SCL bleibt nach der letzten steigenden Flanke 
high und geht nicht, wie von Peter angemerkt, auf low zurück, solange 
das IFG nicht gelöscht ist.

Bei der Configuration des USI-Moduls habe ich folgende Einstellungen:

- SF-Register für SCL/SDA
- uC ist Master
- I²C-Mode
- Interrupts enabled (Interrupt tritt ein, wenn das Schiebe-Register 
leer getaktet ist)
- Clock Divider 32 (8MHz Systemtakt)
- SMCLK als Quelle
- Clockphase: Datenwechsel bei erster, Übernahme bei zweiter Flanke
- Clock-Idle-Polarität: HIGH

Der Idle-State 'high' ist doch richtig, oder? So ist es zumindest auch 
im DB beschrieben. Die Pull-Ups ziehen die Leitung ja auch hoch.


Nochmal zur Info wie es hier abläuft:

Ich gehe in die State-Machine, setze SDA auf Ausgang und erzeuge die 
START-Bedingung, indem ich SDA auf 'low' ziehe (ohne CLK), während SCL 
noch 'high' ist.

Dann schreibe ich 8Bit in den Puffer (Adresse) und starte das Austakten 
der Bits. In der Zeit wird ins Hauptprogramm zurückgekehrt. Ist der 
Puffer leer, so kommt der Interrupt und die Statemachine wird wieder 
aufgerufen.
SCL ist in diesem Moment 'high', es hat seinen letzten Pegel, also die 
steigende Flanke für das Übernehmen des letzten Bits übernommen.

Es kommt der nächste State, indem das ACK des Slave analysiert werden 
soll. Also setze ich SDA auf Input und takte ein Bit raus.

Interrupt -> In der Statemachine wird das LSB des Empfangspuffers 
geprüft. Es liegt ein ACK (also 'low') vor. Device hat geantwortet. Ich 
schreibe das Config-Byte in den Puffer, setze SDA auf Ausgang und takte 
8 Bits raus. In der Zeit wieder in die main().

Interrupt -> Wieder ACK abfragen, also SDA auf Eingang, 1 Bit raus.

Interrupt -> ACK vorhanden. SCL ist wieder 'high'.

JETZT KOMMT DER INTERESSANTE PUNKT: SCL ist in diesem Moment 'high', SDA 
ist wegen dem ACK 'low'. Theoretisch müsste ich jetzt nurnoch SDA auf 
'high' ziehen und hätte die STOP-Bedingung. Aber im DB ist halt noch ein 
Takt mehr drin, insgesamt 19 steigende Flanken.

Also sende ich noch 1 Bit und dann STOP. So habe ich es gleich wie im 
DB.


Soweit erstmal. Alles OK? Trotzdem dieses "SCL sollte 'low' 
sein"-Problematik. Wieso das eine extra Bit? Mal angenommen, es wäre ein 
NACK gewesen, dann wäre SCL 'high' und SDA 'high'. Hier müsste auf jeden 
Fall erst SDA wieder auf 'low', dann wieder auf 'high' gehen, damit die 
STOP Bedingung erfüllt ist.

Was sagt ihr bis dahin dazu?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

IsquareC-Hans schrieb:
>> Was für ein MC?
>
> Ein MCP430G2402.

MSP430G2402 vielleicht? ;-)

Dein Oszillogramm sieht ziemlich abenteuerlich aus. Zum Einen erreichen 
die Clocks bei schnellen Wechseln nie wirklich den HIGH-Pegel. Zum 
Anderen wechseln die Datenpegel unmittelbar vor oder genau mit den 
Clocks, was nicht so sein sollte. Idealerweise sollten die Daten eine 
halbe Bitzeit vor den Clocks wechseln. Das fällt mir spontan ein.

Edit:

Abgesehen davon ist Dein "zusätzliches Bit" die nötige Stop-Kondition! 
Achte mal ganz genau auf die HIGH und LOW-Pegel der Clocks im 
Datenblatt.

von IsquareC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> MSP430G2402 vielleicht? ;-)

Ja, klar!

Knut Ballhause schrieb:
> Dein Oszillogramm sieht ziemlich abenteuerlich aus.

Ja, die Rs sind wohl noch zu groß, aber es funktioniert. Dennoch liegt 
mein Hauptaugenmerk jetzt gerade auf der Diskussion mit der SCL-Leitung. 
Habe mir die Spec jetzt auch mal durchgelesen, da steht es ja ganz klar 
drin. Aber hier bei mir bleibt SCL IMMER nach der letzten steigenden 
Flanke auf 'high'.

von IsquareC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Abgesehen davon ist Dein "zusätzliches Bit" die nötige Stop-Kondition!
> Achte mal ganz genau auf die HIGH und LOW-Pegel der Clocks im
> Datenblatt.

Nee, genau hingesehen nicht. Wenn SCL low bleiben würde nach dem letzten 
Bit, dann wäre der CLK-Puls nicht nötig. Bei einem vorherigen ACK ist es 
auch OK, Dann folgt eine low-high-Flanke. Aber was ist nach einem NACK? 
Dann ist bei mir SCL auf high und SDA auf high. Dann müsste doch SDA 
erst wieder low, dann wieder high.

von Klaus (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Zum Einen erreichen
> die Clocks bei schnellen Wechseln nie wirklich den HIGH-Pegel

Das sieht bei Open-Collector Signalen nun mal so aus. High heißt nicht 
der höchste Pegel sondern nur oberhalb der Schaltschwelle. Man hat sich 
nur bei CMOS Logic angewöhnt, daß High gleich Versorgung ist. Da der 
Slave ein ACK bei seiner Adresse erzeugt, hat er alles verstanden, die 
Pegel sind also ok.

MfG Klaus

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

IsquareC-Hans schrieb:
> Wenn SCL low bleiben würde nach dem letzten
> Bit, dann wäre der CLK-Puls nicht nötig.

Aber bestimmst nicht Du, respektive Dein Programm/der Controller den 
Zustand von SCL?

IsquareC-Hans schrieb:
> Bei einem vorherigen ACK ist es
> auch OK, Dann folgt eine low-high-Flanke.

Die Daten erscheinen bei einer High/Low-Flanke an SCL und sind aber erst 
gültig bei Low->High. Das sieht man eindeutig an der blauen Datenlinie, 
die für den Zeitraum des ACK noch etwas mehr auf Masse geht, als davor.

von IsquareC-Hans (Gast)


Lesenswert?

Also ich habe mir jetzt nochmal einen Brekapoint in die ISR gesetzt.

Diese ist so:
1
USI_ISR()
2
{
3
  rufe state machine auf();
4
  BREAKPOINT
5
  loesche Flag;
6
}

Das Flag wird also gesetzt, die ISR wird aufgerufen, die statemachine 
durchlaufen. Dann der Breakpoint. Flag ist noch gesetzt.

UND: SCL is 'high'. Also definitiv

von IsquareC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Aber bestimmst nicht Du, respektive Dein Programm/der Controller den
> Zustand von SCL?

Quasi. Dadurch, dass das USI-Modul den Zugriff auf die Pins hat, steuert 
es diese auch komplett. Eine Manipulation ist auch nicht möglich durch 
eine Pegelzuweisung.

Der geht halt in die Registereinstellung "IDLE-HIGH" zurück. Würde wohl 
nur durch ständiges Umschalten gehen, aber das ist doch nicht Sinn der 
Sache.

Knut Ballhause schrieb:
> Die Daten erscheinen bei einer High/Low-Flanke an SCL und sind aber erst
> gültig bei Low->High.

Das ist mir klar. Hier ging es mir ja auch nur um die Bedingung, dass 
SDA nach SCL auf high geht.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Klaus schrieb:
> Das sieht bei Open-Collector Signalen nun mal so aus.

Schon klar.

Klaus schrieb:
> High heißt nicht
> der höchste Pegel sondern nur oberhalb der Schaltschwelle.

Die bei für sichere Funktion bei 0.75*Vcc liegt. Das wird laut 
Oszillogramm knapp.

Klaus schrieb:
> Da der
> Slave ein ACK bei seiner Adresse erzeugt, hat er alles verstanden, die
> Pegel sind also ok.

Sind sie nicht, da kleinste Abweichungen im Timing oder Störungen, die 
die Signale verrauschen, zum Verlust der Funktion führen.

von Peter D. (peda)


Lesenswert?

Manual:
1
"14.3.4 USICNT, USI Bit Counter Register
2
3
USISCLREL Bit 7 SCL release. The SCL line is released from low to idle. USISCLREL is cleared if a START condition is
4
detected.
5
0 SCL line is held low if USIIFG is set
6
1 SCL line is release

D.h. USISCLREL muß 0 sein, dann bleibt SCL solange low, bis USIIFG 
gelöscht wird.


Peter

von IsquareC-Hans (Gast)


Lesenswert?

Peter Dannegger schrieb:
> D.h. USISCLREL muß 0 sein, dann bleibt SCL solange low, bis USIIFG
> gelöscht wird.

Hi Peter!

Das Bit ist bei mir nicht gesetzt! Ist es sogar per default nicht. Egal, 
ob gesetzt oder nicht. SCL bleibt high, auch mit gesetztem IFG.

Das Bit schient keine Wirkung zu haben.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

IsquareC-Hans schrieb:
> Das Bit schient keine Wirkung zu haben.

Das wäre dumm für die Entwickler des MSP430.

Oder das Problem liegt woanders.

von IsquareC-Hans (Gast)


Angehängte Dateien:

Lesenswert?

Anbei mein Screenshot. Breakpoint gerade in der ISR (Daten wurden 
Übertragen).

IFG ist gesetzt, USISCLREL ist gelöscht.

Auf dem Oszi: SCL ist gelb, SDA blau

von IsquareC-Hans (Gast)


Lesenswert?

Im Errata ist auch nichts drin.

von IsquareC-Hans (Gast)


Angehängte Dateien:

Lesenswert?

OK, hier steht wie es läuft.

Widerspricht das jetzt also den Spezifikationen?

von IsquareC-Hans (Gast)


Lesenswert?

Das gilt also nur für den SLAVE-Betrieb.

von Peter D. (peda)


Lesenswert?

Es scheint, daß der MSP als Master immer einen halben Takt früher stoppt 
und daher ist SCL noch high und wird dann erst in der nächsten Aktion 
auf low gezogen. D.h. er bleibt mitten im ACK/NACK-Bit stehen. Das ist 
zwar ungewöhnlich, aber auch o.k. Man muß dann natürlich absichern, daß 
SDA solange stabil bleibt.
Es wird also durch das STOP kein überzähliger 10. Takt erzeugt, sondern 
nur der 9. beendet.


Peter

von Thosch (Gast)


Lesenswert?

IsquareC-Hans schrieb:
> Knut Ballhause schrieb:
>> Dein Oszillogramm sieht ziemlich abenteuerlich aus.
>
> Ja, die Rs sind wohl noch zu groß, aber es funktioniert.

Das sieht nicht nur abenteuerlich aus, sondern verletzt
deutlich die Timing-Specs des MCP3425:
In den I2C-Specs des Datenblattes steht ganz klar für SDA und SCL,
daß im fast-I2C-mode die maximale rise time bei 300ns liegt!

da liegst Du satt drüber, wenn ich mir das Oszillogramm so ansehe...

Setup- und Hold-Zeiten sind auch noch ein Thema.


Fazit: bei dem Oszillogramm wundert mich gar nix.
(höchstens, daß es überhaupt mal funktioniert)

Gruß,
Thosch

von IsquareC-Hans (Gast)


Lesenswert?

So, es funktioniert jetzt alles!

Ist irgendwer interessiert an der State-Machine für die MSPs mit USI 
(nicht USCI)-Module (kleinere Derivate) zur Kommunikation mit dem 
MCP3425?

Dann würde ich die hier rein stellen.


Auf jeden Fall danke ich euch für eure Hilfe!

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

IsquareC-Hans schrieb:
> So, es funktioniert jetzt alles!
>
> Ist irgendwer interessiert an der State-Machine für die MSPs mit USI
> (nicht USCI)-Module (kleinere Derivate) zur Kommunikation mit dem
> MCP3425?
>
> Dann würde ich die hier rein stellen.


Was genau hast Du geändert?


> Auf jeden Fall danke ich euch für eure Hilfe!

:-)

von IsqureC-Hans (Gast)


Lesenswert?

Knut Ballhause schrieb:
> Was genau hast Du geändert?

Es lag an nicht immer korrekten STOPs. Irgendwie hat sich die 
Kommunikation dann manchmal verhaspelt.

Auf jeden Fall ist es jetzt alles korrekt und funktioniert einwandfrei.

Thosch schrieb:
> In den I2C-Specs des Datenblattes steht ganz klar für SDA und SCL,
> daß im fast-I2C-mode die maximale rise time bei 300ns liegt!

Da hast du recht. Hab aber auch noch die 10k Widerstände drin. Mit 
weniger sieht es schon ganz anders aus.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Gut der Mann! ;-)

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