Forum: Mikrocontroller und Digitale Elektronik I2C Slave zu langsam


von Joschka T. (p1ngp0ng)


Lesenswert?

Hallo Zusammen,

ich stehe zur Zeit vor einem I2C Mysterium, welches ich mir nicht 
erklären kann. Vill kann der eine oder andere Licht ins Dunkle bringen.


Ich betreibe ein Olimex A20 als I2C-Master. Die I2C Clock beträgt genau 
100kHz (mit Oszi gemessen).

Zusätzlich betreibe ich ein Attiny44 als Slave mit einer Internen Clock 
von 1Mhz. Soweit so gut.

Ich verwende diese USI I2C lib 
(http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html) 
welche in der Funktionalität auch das macht was ich will.

Nun zum Problem:

Wenn ich den Attiny mit 1MHz betreibe, habe empfange ich keine 
Nachrichten bzw nur zufällig. Nach langer Fehlersuche habe ich 
festgestellt das der Attiny zu langsam ist um irgendwelche Nachrichten 
zu empfangen. Nach dem ich die Interne Clock des Tinys auf 8Mhz 
hochgesetzt habe, lief alles wie gewollt.

Im Datenblatt des Tinys steht das die Clock mindestens doppelt so hoch 
wie die I2C-Geschwindigkeit sein muss (welches bei uns aufjedenfall 
gegeben ist) stelle ich mir nun die Frage: Warum?

Hat jemand eine Idee warum dieses Phänomen auftritt und wie es zu lösen 
ist?


Joschka

von Pandur S. (jetztnicht)


Lesenswert?

Weshalb muss der I2C mit 100kHz laufen wenn zB auch 10kHz gehen ? Wenn 
man den I2C im main context, und nicht im Interrupt laufen laesst geht 
auch beliebig langsam.

von Einer K. (Gast)


Lesenswert?

Mich plagten ähnliche Probleme mit einem Raspberry.
Viel andere I2C Dinge funktionierten problemlos.
Aber langsam laufende AVRs, No. (bei mir ein ATMega328P)

Ich habe damals das Clock Stretching als Fehlerquelle ausfindig gemacht. 
Besser, das fehlende Clock Stretching Vermögen des ARM. Der langsam 
laufende AVR zieht den Takt auch innerhalb eines Bytes lang. Zwischen 
den Bytes, war für den ARM kein Problem, aber innerhalb des Bytes sehr 
wohl.

Ob das beim A20 auch so ist... KA.

von Joschka T. (p1ngp0ng)


Lesenswert?

Oh D. schrieb:
> Weshalb muss der I2C mit 100kHz laufen wenn zB auch 10kHz gehen ?
> Wenn
> man den I2C im main context, und nicht im Interrupt laufen laesst geht
> auch beliebig langsam.

weil weitere Teilnehmer an diesem Bus hänge und ich dadrüber keine 
Ahnung habe ob diese mit 10Khz laufen. Außerdem würde ich sehr ungern 
auf dieser Seite etwas ändern.

von Fred R. (fredylich)


Lesenswert?

Hallo Joschka,

Zitat:
Die I2C Clock beträgt genau 100kHz.
Zitat Ende

Okay ist optimal. Schau mal mit Oszi auf SCL und SDA dann wirst du 
sehen, dass µC einen 8 mal hören Systemtakt benötigen.
Somit liegst du mit 1MHz im Grenzbereich. Richtig schwammig wird es wenn 
du viele I2C Teilnehmer am Bus „nagelst“ und ein Teilnehmer nicht 
unverzüglich nach Übertragung den Bus freigibt.
Teilnehmer muss erst angesprochen werden dann schickt er eine Meldung 
„ich bin es“ .Master sagt OK dann werden Daten übertragen. Sind Daten 
da, kommt noch eine Entscheidung ins Spiel Ask oder Nack (Software 
abhängig).
Bitte daran denken die µC haben auch noch etwas anderes zu „takten“ als 
nur I2C Abfrage.

Das DatBlabla ist schon mal verwirrend.

Gruß

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Joschka T. schrieb:
> Hat jemand eine Idee warum dieses Phänomen auftritt und wie es zu lösen
> ist?

 Probiere es mal anstatt:
1
    USICR =
2
...
3
    ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |          // Set USI in Two-wire mode, hold SCL low on USI Counter overflow
 mit:
1
    USICR =
2
...
3
    ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |          // Set USI in Two-wire mode, no USI Counter overflow hold

von stromtuner (Gast)


Lesenswert?

>( 0 << USIWM0 )
'ne NUll schieben? Du willst das Bit (wenn gesetzt) dann löschen, aber 
keine NULL durch die gegend schieben ;)
Bits löschen geht über das komplement und dann nich verodern, sondern 
verUNDen

von Lothar (Gast)


Lesenswert?

U. F. schrieb:
> Ich habe damals das Clock Stretching als Fehlerquelle ausfindig gemacht.
> Besser, das fehlende Clock Stretching Vermögen des ARM

Unter Linux Soft-I2C nutzen:

http://abyz.co.uk/rpi/pigpio/

Oder anderes Betriebssystem nehmen, wo das I2C Master Timing 
konfigurierbar ist:

https://www.riscosopen.org/wiki/documentation/show/iic_transfer

Oder Bare-Metal ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

stromtuner schrieb:
> Bits löschen geht über das komplement und dann nich verodern, sondern
> verUNDen
Das solltest du dir nochmal ansehen.  Hier soll nur verdeutlicht werden, 
dass das USIWM0 nicht vergessen wurde, sondern eben eine 0 sein soll.

von Fred R. (fredylich)


Lesenswert?

Hallo Marc Vesely,

na gut.( 0 << USIWM0 ) ist eine Option. Kann mir aber Vorstellen, wenn 
ein I2C Teilnehmer „stink Lahm ist“, dass dies das komplette System 
ausbremst. Null Infos hin und her schieben, ist wohl nicht das gelbe vom 
Ei.

Gruß

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

stromtuner schrieb:
> 'ne NUll schieben? Du willst das Bit (wenn gesetzt) dann löschen, aber
> keine NULL durch die gegend schieben ;)
> Bits löschen geht über das komplement und dann nich verodern, sondern
> verUNDen

 Hier wird der Wert zugewiesen, nicht verändert und im übrigen
 gilt das, was der Lothar M. geschrieben hat

Fred R. schrieb:
> na gut.( 0 << USIWM0 ) ist eine Option. Kann mir aber Vorstellen, wenn
> ein I2C Teilnehmer „stink Lahm ist“, dass dies das komplette System
> ausbremst. Null Infos hin und her schieben, ist wohl nicht das gelbe vom
> Ei.

 Eben nicht.
 Hier wird gerade verhindert, dass ein Teilnehmer (in diesem Fall
 Tiny44) die Kontrolle über den Bus übernimmt und die anderen mit
 clock stretching bremst. Und wenn Clock vorher nicht geprüft wird,
 geht sowohl START als auch STOP in die Hose...

: Bearbeitet durch User
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.