Forum: Mikrocontroller und Digitale Elektronik TWI hängt sich auf CLK Puls geht unter


von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Bin gerade dabei den TWI in einem SAM4e interrupt basiert zu gestalten.
Da ich früher schon bei den ASF-Funktionen schon das Problem hatte, dass 
beim schreiben auf dem Bus sich gelegentlich, nach 5min bis 4 std, der 
Bus aufhängt, habe ich dieses Problem nun erneut.

Jetzt bin ich etwas schlauer geworden. Es schein so als ginge ein CLK 
Puls verloren. Habe mir vor einer Woche ein Picoscope gekauft, das 
kleinste mit 10MHz, hier ist meiner Meinung nach die zu schwache CLK zu 
sehen. Ich habe mal Diagramme angehängt eines mit der einwandfreien 
Übermittlung und die Anderen sind die fehlerhaften Übertragungen wo die 
schwache CLK zu sehen ist.

Weiß einer wie man dem Abhilfe schaffen kann? Pullups verkleinern? Diese 
sind derzeit 4K7. Leitungslänge ca. 20cm auf der Platine zu 6 Slaves.

Wie könnte man die Verklemmung in der SOftware lösen? Die Datenleitung 
(blau) scheint von dem Slave (PCA9555) auf low gehalten zu werden, da 
auch kein Reset der MCU hilft. Ich muss immer erst die PCA9555 resetten 
durch Spannung aus und wieder an.

Ich sende immer das gleiche Paket im 100ms Takt. Der Fehler ist wie auf 
den Diagremmen zu sehen unterschiedlich und kommt teilweise erst nach 
6000 bis 8000 Paketen. Teilweise aber auch schon früher.

von Bernd K. (prof7bit)


Lesenswert?

Michael schrieb:
> Pullups verkleinern? Diese
> sind derzeit 4K7.

Probiers docch mal aus. Schau in die Datenblätter aller Geräte wieviel 
Strom das schwächste davon maximal an seinen I²C-Pins versenken kann und 
rechne Dir entsprechend aus wie klein der Pullup sein darf. Garantiert 
darf er schon noch etwas kleiner als 4.7k sein, so aus dem Bauch raus.

Die Flanken sehen schon arg verschliffen aus auf deinem Oszillogramm 
(aber bedenke: auch der Oszi-Tastkopf hat noch ne nicht zu 
vernachlässigende Kapazität, steht er schon auf 1:10?)

Außerdem finde ich es seltsam daß der Master hier mal zwischenzeitlich 
einen erheblich kürzeren Taktimpuls erzeugt (der ist nicht "schwächer" 
wie Du schreibst, der ist einfach kürzer!), da ist noch irgendwas faul 
an der Implementation des Masters. Machst Du das in Software?

: Bearbeitet durch User
von Michael (Gast)


Lesenswert?

Tastköpfe sind auf 1:1.
Habe auch gerade noch ein altes Tektronix 200Mhz Scope an die SCL 
gehängt. Bei dem Scope geht leider nur noch ein Kanal. Auf jeden Fall 
sind auch hier die Flanken sehr schwach. Ich probiere es mal aus die 
Pullups zu verkleinern. Vll bekomme ich auch die Kapazität der Leitung 
gemessen.

von isidor (Gast)


Lesenswert?

Michael schrieb:
> das
> kleinste mit 10MHz, hier ist meiner Meinung nach die zu schwache CLK zu
> sehen.

Deiner Meinung nach hast du einen "schwachen" Clock.

Meiner Meinung nach hast du mit dieser Messung und Darstellung nur
bewiesen dass du ein Mess-System anwendest das für deinen Zweck
nichts taugt.

Dein Mess-System (Oszilloskop oder Tastkopf oder beides) haben
nicht genug Bandbreite um deine Messaufgabe genau genug zu
erfüllen.

Also: nix "schwache CLK", sondern bandbegrenzendes System das
die die Flanken verschleift und nicht nachvollziehbar macht

von Michael (Gast)


Lesenswert?

Das mag sein. Deshalb erwähte ich auch die 10MHz. Habe deshlab gerade 
nocheinmal mit dem Tektronix verglichen. Bin jetzt mit dem Bustakt auf 
50kHz zurückgegangen um Messfehler auszuschließen. Beide Tastköpfe (von 
PicoScope 10MHz und Tektronix) zeigen einen ordentlichen Rechteck am 
Calibrator pin (100kH Signal).

Dennoch glaube ich das es an der "schwachen" Clock liegt. Es wäre schon 
purer Zufall, dass immer wenn die Übertragung funktioniert, das Scope 
die Clk Pulse "sauber" erfasst und nur bei Fehlerhafter Übertragung die 
Bandbreite mal gerade nicht reichte um die Clock wie sonst darzustellen.

von isidor (Gast)


Lesenswert?

Michael schrieb:
> Dennoch glaube ich das es an der "schwachen" Clock liegt.

Welche Fakten bringen dich denn dazu von "schwach" zu sprechen.

Stelle mal dein physikalisches Übretragungssystem (Sender bis
Empfänger) für uns nachvollziehbar dar, dann reden wir über
"schwach"

von Klaus (Gast)


Lesenswert?

Bernd K. schrieb:
> Probiers docch mal aus. Schau in die Datenblätter aller Geräte wieviel
> Strom das schwächste davon maximal an seinen I²C-Pins versenken kann und
> rechne Dir entsprechend aus wie klein der Pullup sein darf.

Da braucht man nicht schauen, ein standardkonformer I2C Treiber muß 3mA 
und 400 pF schaffen.

MfG Klaus

von Joachim B. (jar)


Lesenswert?

Michael schrieb:
> Weiß einer wie man dem Abhilfe schaffen kann? Pullups verkleinern? Diese
> sind derzeit 4K7.

bei um 3V 4,7k?

ich würde an Hand der Datenblätter aller Beteiligten den sink Strom 
prüfen und mindestens auf 1mA gehen, also 3,3k bis runter je nach Chip 
auf 1,1k ist halt ne Frage der kapazitiven Lasten.

sitzen die beiden (SDA SCL) I2C pullup Rs wirklich am Ende der Leitung 
alleine !

nicht das irgendwelche I2C Chips eigene am I2C Slave haben.
Gerne werden auch pullup Rs auch schon mal am Master bestückt -> 
raspberry Pi z.B. das ist eher kontraproduktiv.

von Peter D. (peda)


Lesenswert?

Michael schrieb:
> Wie könnte man die Verklemmung in der SOftware lösen?

I2C-Controller haben oft kein Bus-Reset, d.h. man muß es in SW machen.
Der Master muß dazu sein I2C disablen und SCL als open-drain händisch 
takten (max 100kHz), bis SDA wieder high ist. Das kann maximal 9 
SCL-Takte dauern.

von Klaus (Gast)


Lesenswert?

Ich glaube aber nicht, daß es wirklich ein HW Problem ist. Wenn man sich 
die Fehlerbilder genau ansieht (ist bei der Auflösung nicht leicht) 
erkennt man CLK-Signale, die extrem niedrig sind. Gleichzeitig sind sie 
aber auch kürzer als die anderen. Da Slaves nur verlangsamen können, 
muß da ein Timing-Problem beim Master sein. Da das nicht immer auftritt, 
könnte ich mir eine Störung durch einen Interrupt oder ein ähnliches 
asynchrones Ereigniss vorstellen.

MfG Klaus

von Bernd K. (prof7bit)


Lesenswert?

isidor schrieb:
> Dein Mess-System (Oszilloskop oder Tastkopf oder beides) haben
> nicht genug Bandbreite um deine Messaufgabe genau genug zu
> erfüllen.

Nein, das hat mit der Bandbreite des Messwerkzeugs nichts zu tun. Das 
hier zu sehende Bild ist typisch für einen I²C-Bus der knapp am Limit 
dessen vorbeischrammt wo ich schon längst sagen würde mir persönlich wär 
das schon zu heikel für ein zuverlässiges System. Auch wenns scheinbar 
gerade so eben noch funktioniert.

Man sieht ganz deutlich (wenn man sich mal vor Augen führt wie I²C 
funktioniert) bei den aufsteigenden Flanken wie die Leitungskapazität 
von den Pullups langsam (zu langsam!) geladen wird, immerhin wird bei 
I²C ja nicht aktiv high getrieben sondern der Ausgangstreiber lässt 
einfach los und der Pullup muss die Leitung wieder hoch ziehen.

Also eins der folgenden würd ich tun:

* kürzere Leitung (wahrscheinlich nicht möglich)
* kleinere Pullups
* niedrigere Taktfrequenz.

Und zusätzlich und vor allem:

* Rausfinden was es mit diesem einen seltsam kurzen Takt auf sich hat 
der da alle Naselang mal auftritt. Er ist so kurz daß in der kurzen Zeit 
der Pullup die Leitung nicht mehr auf high gezogen bekommt. Erzeugt der 
Master so einen kurzen Takt (warum in aller Welt?) oder ist das ein 
Slave der Clock-Stretching versucht mit nem ziemlich unglücklichen 
Timing? Der Master scheint ihn mit zu zählen und kommt auf 9, der Slave 
mit dem er gerade spricht zählt nur 8 und bleibt dann im ACK hängen.

: Bearbeitet durch User
von isidor (Gast)


Lesenswert?

Bernd K. schrieb:
> Nein, das hat mit der Bandbreite des Messwerkzeugs nichts zu tun.

Jetzt wo ich mir es nochmal anschaue muss ich dir Recht geben.
Es sind ja hochfrequente Spikes zu sehen.

Die Pullups sind auf jeden Fall zu schwach, bzw die Clockrate zu hoch.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Die Signale sind grenzwertig, sollten aber funktionieren. Es gibt eine 
saubere fallende Flanke.

Das Problem ist eindeutig und ausschließlich der zu kurze Clk-Puls.

ich würd aber trotzdem auch an den Pullups drehen...

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

isidor schrieb:
> Die Pullups sind auf jeden Fall zu schwach, bzw die Clockrate zu hoch.

Grundsätzlich würde ich auch kleinere Pullups nehmen, bei 3.3V so 2k2.
Aber hier sind beliebig viele Takte fast (wären ganz, wenn Pullup 
kleiner) korrekt im Pegel und einzelne dann wieder nicht. Die Pullups 
ändern sich zwischendurch nicht!
Das Timing kann man nicht genau ausmachen, die 'langsame' Anstiegszeit 
ist aber typisch - eben wegen des Pullups.
Bei dem Problempunkt schient mir die Periodendauer einmal zu klein zu 
sein.

Ich tippe auf ein Problem im Master - Software.

Übrigens, die Bandbreite des Skopes ist für diesen Zweck ok, denn sonst 
würden die fallenden Flanken nicht so steil dargestellt.

von isidor (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Das Problem ist eindeutig und ausschließlich der zu kurze Clk-Puls.

.... der aber nicht durch die Prozessor-Hardware verusacht sein muss.

Mir machen die starken Spikes zu denken. Es gibt starke
"undershoots" aber auch Überschwinger, die können das Bussystem
durecheinander bringen. Es kann natürlich eine Fehlmessung
des Oszilloskops sein, oder ein magelhafter Massebezug.

Wichtig ist es die Bus-Topologie geradlinig auszuführen und
keine wilden Stern-Anordnungen zu wählen. Niederohmige Pullups
vermindern auch die Über-/Unterschwinger. Aber auch eine
"innige" Masseverbindung unter allen Busteilnehmern ist wichtig.

Haben wir schon über ausreichend Abblock-Kondensatoren gesprochen?

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

isidor schrieb:
> Es kann natürlich eine Fehlmessung
> des Oszilloskops sein, oder ein magelhafter Massebezug.

Von zweiterem gehe ich auch aus. Und/oder von einem Schaltnetzteil in 
der Nähe (sieht bei mir genauso aus, wenn ich den Notebook eingesteckt 
habe. Notebook ausstecken => Signal sauber)

Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann 
sind die Flanken vermutlich auch wesentlich sauberer.

Der zu kurze Clk-Puls ist mit an Sicherheit grenzender 
Wahrscheinlichkeit ein Software-Problem am Master.

von isidor (Gast)


Lesenswert?

Michael Reinelt schrieb:
> Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann
> sind die Flanken vermutlich auch wesentlich sauberer.

Das eben nicht. Denn ein 1:1 Tastkopf würde die scharfen Spikes
glattbügeln. Die Spikes sind wesentlich steiler als die
Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem.

von HildeK (Gast)


Lesenswert?

isidor schrieb:
> Die Spikes sind wesentlich steiler als die
> Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem.

Oder die Spikes werden direkt in den Tastkopf eingestreut und haben gar 
nichts mit der Schaltung zu tun. Solange der Tastkopf mit den unsäglich 
langen Masseclips irgendwo an GND geklemmt wird, solange glaube ich 
nicht, dass die Spikes auf dem Bus vorhanden sind.
Schließe mal deinen 10:1-Tastkopf mit dem Massclip kurz und halte das 
Gebilde über einen Schaltregler ...

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

isidor schrieb:
> Michael Reinelt schrieb:
>> Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann
>> sind die Flanken vermutlich auch wesentlich sauberer.
>
> Das eben nicht. Denn ein 1:1 Tastkopf würde die scharfen Spikes
> glattbügeln. Die Spikes sind wesentlich steiler als die
> Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem.

Das eben schon. I2c ist sehr empfindlich auf Leitungskapazitäten, und 
mit einem 1:1 taskopf fügst du erhebliche Kapazität hinzu, mit 1:10 
entsprechend weniger.

Seeing is believing.

von isidor (Gast)


Lesenswert?

HildeK schrieb:
> Oder die Spikes werden direkt in den Tastkopf eingestreut und haben gar
> nichts mit der Schaltung zu tun.

Da hast du allerdings auch wieder Recht. Dann gilt wieder mein
Eingangs erwähntes Bandbreite-Problem ..... dagegen spricht aber
dass das Oszilloskop nur 10 Mhz Bandbreite hat, solche Spikes
sind dafür gefühlsmässig schon zu hochfrequent, könnten also
bei der Bandbreite gar nicht in Erscheinung treten

..... und es gilt: wer misst, misst Mist.

Also eigentlich müssten wir alle selbst dabei sein .....

von Michael (Gast)


Lesenswert?

Danke erstmal für die zahlreichen Tips.
Nachdem ich den I2C nun mit 50 kHz betreibe sehen die Flanken schon 
deutlich besser aus. Zusätzlich habe ich die Pullups noch verringert 
(jeweils 2k35). Noch schönere Flanken. Bis gerade eben funktionierte 
auch alles ganz gut. Nach 5h 12min ist er dann doch wieder hängen 
geblieben. Diesmal aber mit korrekter Übertragung auf dem Scope. Das Ack 
kam noch, dann wurde Stop gesendet und dann war es vorbei. 8022146 
Pakete hat er geschafft. Danach verbleibt die Datenleitung wieder auf 
Low, SCL ist high. Wieviel Zeit dazwischen vergeht kann ich nicht sagen. 
Das habe ich leider nicht mit auf dem Schirm. Ist bloß der Aktelle Pegel 
wenn ich aus dem Single Modus raus gehe.

Muss auch gestehen, dass ich den Debugger zwar angeschlossen hatte aber 
irgendwie nicht gestartet :) Lief quasi stand alone.

Bevor ich irgendwas weiter sage, lasse ich es noch einmal die Nacht über 
laufen. Nicht dass jetzt der deaktivierte Debugger noch irgendwie 
reingespuckt hat, da das AVR Studio auch noch offen war und ich dort 
trocken etwas Code sortiert habe.

Hier auch mal der Code. Wundert euch nicht dass hier noch so viele 
Printfs oder zusätzliche (unnütze) Abfragen drinn sind. Ich war / bin 
ziemlich verzweifelt mit dem twi :/

Im prinziep, startet das Ganze sobald was im Puffer steht 
(SlaveAdresse,SlaveInternAdresse,Datenbyteanzahl,Byte1,Byte2) über die 
Funktion Twi_Tx_TriggerNextTransfer(). Danach ist der Handler dran.
1
void Twi_Tx_TriggerNextTransfer(Twi *p_twi){  
2
  uint8_t buffer_out = 0; 
3
  gl_twi0_state = TWI0TX_BUSY;
4
  /* Set write mode, slave address and 3 internal address byte lengths */
5
  p_twi->TWI_MMR = 0;
6
  if (TWI0->TWI_SR & TWI_SR_TXRDY){
7
    if (Twi0_TxBufferOut(&buffer_out)){  
8
      p_twi->TWI_MMR = TWI_MMR_DADR(buffer_out)| ((1 << TWI_MMR_IADRSZ_Pos) & TWI_MMR_IADRSZ_Msk);
9
      if (Twi0_TxBufferOut(&buffer_out)){
10
        // Set internal address
11
        p_twi->TWI_IADR = 0;
12
        p_twi->TWI_IADR = buffer_out;
13
      }
14
    }
15
    //Enable Interrupt -> interrupt will occur immediately because the TXCOMP and TXRDY Flag is set
16
    TWI0->TWI_IER =  TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_NACK;
17
  }
18
}
19
20
enum {TX_BEGIN,TX_DATA,TX_END,TX_STOP};
21
22
void TWI0_Handler (void){
23
  static uint32_t status = TX_BEGIN;
24
  static uint32_t cnt;
25
  uint32_t twi_status;
26
  uint8_t buffer_out;
27
  
28
  if (status == TX_BEGIN){
29
    // Load count of Databytes
30
    if(Twi0_TxBufferOut(&buffer_out)){
31
      cnt = buffer_out;
32
      if (cnt == 0){
33
        //ERROR
34
      }
35
      status = TX_DATA;
36
    }
37
  }
38
  
39
  if (status == TX_DATA){
40
    twi_status = TWI0->TWI_SR;
41
    if (twi_status & TWI_SR_NACK) {
42
      printf("ED");
43
    }
44
    else if (twi_status & TWI_SR_TXRDY) {
45
      if(Twi0_TxBufferOut(&buffer_out)){
46
        TWI0->TWI_THR = buffer_out;
47
        cnt--;
48
      }
49
      else {
50
        Twi0_TxBufferClear();
51
        status = TX_BEGIN;
52
      }
53
    }
54
    
55
    if (cnt == 0){
56
      //all bytes send, wait for TXRDY to send STOP
57
      status = TX_END;
58
    }    
59
  }
60
  
61
  else if (status == TX_END){
62
    twi_status = TWI0->TWI_SR;
63
    if (twi_status & TWI_SR_NACK) {
64
      printf("EE"); //bus läuft nach diesem Fehler weiter -> da nur das letzte Byte nicht verstanden wurde
65
    }
66
    else if (twi_status & TWI_SR_TXRDY) {
67
      TWI0->TWI_CR = TWI_CR_STOP;  
68
      status = TX_STOP;
69
      TWI0->TWI_IDR =   TWI_IDR_TXRDY;
70
    }
71
  }
72
  
73
  else if (status == TX_STOP){
74
    twi_status = TWI0->TWI_SR;
75
    if (twi_status & TWI_SR_NACK) {
76
      printf("ES");
77
    }
78
    if (twi_status & TWI_SR_TXCOMP) {
79
      status = TX_BEGIN;
80
      printf("t");
81
      //DISABLE INTERRUPT
82
      TWI0->TWI_IDR =   TWI_IDR_TXCOMP | TWI_IDR_TXRDY | TWI_IDR_NACK;
83
      gl_twi0_state = TWI0TX_CMPL;
84
    }
85
    else if (twi_status & TWI_SR_TXRDY) {
86
      status = TX_BEGIN;
87
      printf("X");
88
      //DISABLE INTERRUPT
89
      TWI0->TWI_IDR =   TWI_IDR_TXCOMP | TWI_IDR_TXRDY | TWI_IDR_NACK;
90
    }
91
    
92
  }
93
}

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.