Seid gegruesst werte Mitbastler!
Habe gestern einen Beschleunigungssensor von ST (LIS302DLH)per i2c an
meinen Mikrocontroller angeschlossen (tiny2313).
Das Folgende ist alles auf Software basierend aufgebaut, keine
TWI-Hardware benutzt.
1. Habe die Addresse gesendet und ein "Write" am Ende angehaengt (8bit
alles zusammen) und ein acknowledge zurueckerhalten.
2. Dann die Sub-Addresse (Registerauswahl) geschickt und wiederum ein
Acknowledge erhalten.
3. Daraufhin habe ich wieder die Addresse geschickt diesmal mit einem
"Read" im Anhang (8Bit alles zusammen) und noch ein Acknoledge erhalten.
Laut Datenblatt sollte nun der Controller anfangen, den Registerinhalt
auf der SDA Leitung mit jedem Taktsignal hinaus zu "shiften", bekomme
aber nur Einsen zurueck und keine Informtionen, obwohl ich das Who_am_I
Register auslese, welches nicht leer sein sollte.
Bzgl. meiner Vorgehensweise:
Da ich hier kein Oszi zur Verfuegung habe, benutze ich momentan den
Dragon zum Debuggen.
Sprich ich gehe Schritt fuer Schritt durch den Code und schaue mir an,
was die Pins sagen. Konnte da bis jetzt auch noch keinen Fehler
feststellen.
Noch eine Verstaendnissfrage:
1. Waehrend die Clock low ist, kann ich doch auf der SDA Leitung machen
was ich will, dass sollte den Slave eigentlich nicht kuemmern oder?
2. Bedingt durch den Debugmodus des AVRDragons betreibe ich den Chip
momentan mit einer Clockfrequency von rd. 1Hz ist das evtl. zu wenig?
Konnte dazu keine Angaben im Datenblatt finden.
Einzig die Slave Datahold Time koennte damit was zu tun haben, die
besagt, dass die Daten nach der fallenden Flanke des ClockSignals noch 4
Microsekunden anliegen. Da ich jedoch noch waehrend der High periode
auslese sollte das keine Probleme geben.
Fuer eure Tips, Anregungen und Erfahrungen bin ich euch dankbar. Ich
hoffe, dass ich mit eurer Unterstuetzung das Teil zur Kommunikation
bekommen werde.
Achso nochwas:
1. Programmiere in ASM
2. der Chip antwortet nur, wenn ich die korrekte Addresse schicke. Auf
die Falsche Addresse scheint er nicht zu reagieren.
Zumindest dieser Teil geht also schonmal wuerde ich sagen.
Gruesse Tueftler
>1. Waehrend die Clock low ist, kann ich doch auf der SDA Leitung machen>was ich will, dass sollte den Slave eigentlich nicht kuemmern oder?
Und was machst du da?
Durch die Pullups kann es passieren, dass die Leitung auf high geht,
z.B. wenn ich den SDA-Port im Muc von Ausgang auf Eingang umschalte,
beim Umschalten von Senden zu Empfangen bzw bei der Auswertung des
Acknowledge.
Hallo,
die Bedingungen bei I2C werden so signalisiert (Start, Stop), ich habe
kein Diagramm hier zur Hand um nachzuschauen, es ist auf jeden Fall
ungünstig.
I2C ist prinzipiell ein Bus, an dem die Leitungen OpenDrain sind und ihr
H über die PullUps erhalten. Auch CLK darf z.B. kein PushPull-Ausgang
sein, weil ein Slve mit Clock-Stretching CLK auf L halten darf, wenn er
mehr Zeit braucht. Das finden dann beide bei AVR mit aktiv H auf CLK
nicht so lustig.
Für Software I2C als: externe PullUp, PORT auf L und DDR als Eingang
ergibt den Eingang für SDA/SCL und Ausgang als H durch externen PullUp.
Für Ausgang L jetzt nur DDR auf Ausgang und aktiv L liegt an.
So ist man normgerecht und vermeidet unangenehme Überraschungen,
spätestens, wenn man ein anderes I2C mit seinen Routinen benutzt, das
diese Bedingungen auch ausnutzt.
Selbst die uralte AVR-Appnote für TWI hat z.B. Clock-Stretching nicht
berücksichtigt, womit ich promt bei einem MAS3507D tagelang nach dem
Fehler gesucht habe...
Gruß aus Berlin
Michael
Vielleicht solltest Du auch START/STOP senden.
Es ist im allgemeinen recht unnütz, zu beschreiben, was man meint, in
der SW programmiert zu haben.
Der kommentierte Quelltext (als Dateianhang!) ist deutlich informativer.
Einen praktischen I2C-Sniffer kann man sich schnell basteln:
Beitrag "I2C (TWI) Sniffer mit AVR"
Peter
Hallo vielen Dank erstmal fuer Eure Beitraege.
Werde den Quellcode heute Abend mal posten.
Hab auch an Start+Stop im Quellcode gedacht, nur vergessen hier zu
erwaehnen.
@Michael: Hab ich Dich nun richtig verstanden:
1. Fuer die Highpase: Clockpin im MuC als Eingang definieren
(externe Pullups heben dann die Spannung an)
DDR= 0 und PORT = 0
2. Fuer die Lowphase: Clockpin als Ausgang, mit
DDR= 1 und PORT = 0.
Ja scheint eine gute Idee zu sein.
Gleiches Prinzip geht ja auch mit der Datenleitung wenn ich jetzt nicht
irgendwas grob uebersehen habe oder?
Werde mal meinen Code dieser Idee anpassen und dann hier posten.
@Peter:
Ja ist mir dann auch bewusst geworden, habe aber leider keinen Quellcode
zur Hand gehabt (Mittagspause, war auf Arbeit).
Aber ich entnehme euren Beitraegen dass es erstmal nicht an einer zu
langsamen Clock-Taktung liegen sollte, da man auch eine sehr langsame
Clock benutzen koennen sollte?
Vielen Dank erstmal, bis bald.
Tueftler
Hallo,
Tueftler86 schrieb:
> @Michael: Hab ich Dich nun richtig verstanden:>> 1. Fuer die Highpase: Clockpin im MuC als Eingang definieren> (externe Pullups heben dann die Spannung an)> DDR= 0 und PORT = 0>> 2. Fuer die Lowphase: Clockpin als Ausgang, mit> DDR= 1 und PORT = 0.>> Ja scheint eine gute Idee zu sein.>> Gleiches Prinzip geht ja auch mit der Datenleitung wenn ich jetzt nicht> irgendwas grob uebersehen habe oder?> Werde mal meinen Code dieser Idee anpassen und dann hier posten.
Ja. Port bleibt so immer auf 0, Geschaltet wird nur mit DDR und man kann
jederzeit den tatsächlichen Zustand des Pins lesen.
CLK als H gesetzt und L zurückgelesen würde dann eben zum Warten
zwingen, bis der Slave CLK wieder freigibt (Clock-Stretching eben).
Gilt für beide Leitungen, dann ist zumindest die Hardware mit allen
I2C-ICs kompatibel.
Zum Takt: mir ist nicht aufgefallen, ob ein Hersteller inen minimalen
Takt angibt, allerdings habe ich auch nicht so darauf geachtet.
Gruß aus Berlin
Michael
So ich bins nochmal,
Hab jetzt den Code auf den "Pull-up"-Betrieb umgeschrieben.
Und siehe da, nun sagt mir der Sensor wenigstens wie er heisst.
Hängt vermutlich auch damit zusammen, dass ich den ganzen Code nochmal
detailliert durchgegangen bin.
Dabei sind mir noch ein par Fehler aufgefallen.
Hab den Code mal angehängt.
Muss nur noch die Wartezeiten anpassen, da ich bis jetzt nur per Dragon
debuggt habe, wobei das Timing unkritisch, da sowieso viel zu langsam,
ist.
Bei weiteren Fragen komme ich nochmal auf euch zurueck.
Mit Grüßen,
Tueftler
Und hier noch ein Bild vom Sensor,
Per Dead-Bug aufgelötet.
Das geht erstaunlich gut schnell und einfach und ist selbst bei
kleineren Pinabständen noch möglich (mit normalem Lötkolben und
ausreichend Flussmittel wohlgemerkt)