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
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.
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.
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.
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ß
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 |
>( 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
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 ...
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.
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ß
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.