PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C Hilfe



surfer
21.07.2005, 17:05
Hallo zusammen

Ich benötige für die Ansteuerung eines Uhren-IC's über I2C Hilfe...
Ich arbeite mit der I2C Bibliothek von Peter Fleury.
Das Programm könnte eigentlich zum laufen kommen, jedoch denke ich, dass ich eine falsche Reihenfolge der Befehle habe.
Wenn ich zum Beispiel ein Register beschreiben will, mache ich folgendes:

I2C_Start (Adresse des IC's+0 am Schluss für "Write")
I2C_Write (Adresse des Registers im IC)
I2C_Write (Wert den ich ins Register schreiben will)
I2C_Stopp()

Wenn ich etwas lesen will mache ich es folgendermassen:

I2C_Start (Adresse des IC's+0 am Schluss für "Write")
I2C_Write (Adresse des Registers im IC)
I2C_Stop()
I2C_Start (Adresse des IC's+1 am Schluss für "Read")
daten = I2C_Read_NAck (Adresse des Registers im IC)
I2C_Stop()


Leider funktioniert beides nicht... Ich denke ich habe einen total falschen Ablauf....
Ich brauche diese Ansteuerung dringend und habe keine Zeit, lange einen Code zu schreiben, darum möchte ich diese Bibliothek verwenden. Ich hoffe jemand kann mir den korrekten Ablauf beschreiben. Ich würde mich freuen. Den Rest kann ich mir dann schon zusammenreimen, wie's weiter geht...

Danke!!

SprinterSB
21.07.2005, 20:46
So ne Bibliothek gibt dir doch nur die Grundbausteine für I2C.
Ob die Steine so sind, wie deine Uhr sie braucht, weiß alleine die Beschreibung zu deiner Uhr...
Freilich sieht's aus wie das Protokoll, das viele I2C Slaves verlangen.

Das byte i2c_readnack() bekommt kein Argument, und vorne fehlt ein i2c_init().

surfer
21.07.2005, 23:09
Das I2C_INIT habe ich nur hier vergessen. Im Code hab ichs schon drin.

Ich verstehe nur nicht ganz wie ich lesen kann...

Welches soll ich nehmen...

readack oder readnack oder was?

Ich probier nochmals ein bisschen rum, jedoch fehlt mir eben schon der Einstieg. Es handelt sich um einen DS1307 Uhren-IC, für die, die das Datenblatt mal anschauen möchten!!! Danke!! Ist wirklich dringen!!

Merci

SprinterSB
22.07.2005, 08:44
Machen die i2c-Routinen überhaupt was?
Wenn ein Slave nicht richtig verdrahtet ist, dann hängen sich Fleurys Routinen chic in ne Endlosschleife...
Check das mal, ob du überhaupt über i2c_start() rüberkommst.

Laut Spez sendet i2c_readNak() kein ACK nache dem letzten Receive. Beim 24C02 sieht ein Sequential Read also so aus:

...
i2c_readAck();
i2c_readAck();
i2c_readNak();
i2c_stop().

surfer
22.07.2005, 16:57
Die Routinen laufen eigentlich schon. Erst wenn ich eine falsche Adresse angegeben wird, bleibt es in einer Endlosschleife hängen...
Wie siehts denn eigentlich mit den Ports aus? Muss ich die zuerst noch als Ein- bzw. Ausgänge definieren?

SprinterSB
22.07.2005, 20:42
Das macht i2c_init(), zumindest für die Softwareversion i2cmaster. Für die Hardwareversion twimaster braucht man die Ports überhaupt nicht anzufassen, das wird von der TWI-Einheit gemanagt, analog zum UART, wo man sich auch um nix kümmern muss.

Ein Blick in die Source von i2cmaster offenbart einen bug bei großen AVRs.
Fleury geht davon aus, daß PINn, DDRn und PORTn aufeinander folgen. Für große ATmegas ist das AFAIK nicht immer so (zB PortE).

Welche Version verwendest du denn?
Sonst alles gecheckt?

#define für CPU-Frequenz (nicht notwendig gleich deiner Quarz-Frequenz)
#defines für Ports (falls Soft-Version)
Pullups an SCL und SDA
Slave-Adresse
Objekte neu generiert nach Anpassung der Makros? Wirklich?
Ist das Slave-Protokoll so wie im Slave-Manual?


Ich hab mir gestern nach deinem Post mal das Fleury-Zeug geholt, weil ich auch noch was via I2C machen werde.
Hab noch ein 24C02 rumfliegen und an nen Mega8 gestöpselt.
Ging alles auf Anhieb so wie man sich das wünscht; allerding mit etwas angestaubtem Compiler (gcc 3.3) und eigenem Makefile. Aber das sollte nix zur Sache tun...

BTW: *Was* funktioniert denn dabei nicht?

surfer
23.07.2005, 17:28
Das komische ist, dass ich mit der genau gleichen Programmabfolge es schon mal zum laufen brachte, jedoch mit DIL-Version auf dem Steckbrett.
Ich könnte mir natürlich auch vorstellen, dass der Baustein kaputt ist, den ich jetzt verwende. Ich habe zusätzlich noch einen Temp- und Feuchtigkeitsmesser über I2C. Ich werde es mal mit dem versuchen...
Werde deine Ratschläge befolgen...

surfer
23.07.2005, 18:00
Note: Was isch komisch finde...
Habe geschaut was die Fleury-Library eigentlich so macht...
Beim I2C Write wird der zu schreibende Wert ins TWDR (oder wie auch immer) geschrieben.
GENAU der gleiche Wert bekomme ich beim I2C Read geliefert....
Könnte es sein, dass der Wert nie "abgeholt" wird???
Warum bleibt dann das Programm nicht hängen?? Das ACK scheint es zu bekommen...!

SprinterSB
24.07.2005, 09:18
Also wenngenau die gleiche Software mit dem gleichen Baustein funktioniert hat, dann hast du deine Antwort...
Entweder ist der neue Baustein gefrittet oder falsch verdratet (kalte Lötstelle, Lötbrücke). Dein Steckbrett hast du bestimmt immer noch, teste mal mit dem gleichen Binary gegen.
Das ACK beim read geht vom Master zu Slave: Im 9ten Buszyklus zieht der Empfänder SDA auf low um dem Empfänger den erfolgreichen Transfer zu signalisieren. Und beim write gibt dir der TWI nen Fehler, denn kein ACK vom Slave kommt. Aufhängen sollte ich da nix.

dark emporer
24.07.2005, 15:20
mit der bibliotek kenne ich mich nicht aus aber nach jedem write musst du auf ack warten ich hofe das write mach das bei dir glich mit sonnst musttu selbst auf ack warten

surfer
25.07.2005, 12:30
Ojeoje.... Ich glaube, ich verzweifle langsam!!!
Ich bring es einfach nicht fertig den Code auszulesen.
Habe es nun mit diesem IC hier versucht: http://www.sensirion.com/images/getFile?id=25 !! Aber isch schaff es einfach nicht... Ich werde nochmal den Uhren-ic versuchen!! Aber ich habe nicht die grösste Hoffnung!! Habe alle deine Tipps nochmals probiert aber es will und will nicht (und ich muss endlich mein Projekt beenden!!!)
Beim Datenblatt oben... Könntest du mir mal einen Code schicken, der für diesen Baustein funktionier "sollte"? Das wäre super!!! Hoffentlich klappts irgendwie noch!!!!

SprinterSB
25.07.2005, 12:41
Sorry babe:

2.2 Serial Interface (Bidirectional 2-wire) The serial interface of the SHTxx is optimized for sensor readout and power consumption and is not compatible with I2C interfaces, see FAQ for details.

Schon START ist nicht I2C: Sieht aus als kämst du nicht umhin selber mit den Pins rumzuwackeln. Also alles in die Tonne kloppen und bei Null anfangen mit einem Fuckin-SHTxx-Braindead-Protocol.

Gruß an den Projektleiter.

surfer
25.07.2005, 13:00
Hoppla... Genau... Oje...
Könntest du vielleicht auch mal einen Blick hierrein werfen? Wäre toll!
Das ist der Uhren-IC...
http://pdfserv.maxim-ic.com/en/ds/DS1307.pdf

SprinterSB
25.07.2005, 13:49
Was Note 6 auf Seite 3/15 sagt ist mir net ganz klar.
Scheint aber ein normaler I2C-Sklave mit max 100kHz zu sein.
Ob das TWI der AVRs ein pulldown von SCL korrekt handhabt weiß ich net, aber ich geh mal davon aus.
Teste mal mit kleiner TWI-Frequenz, 50kHz zB.


Nach power up ist's immer ratsam was zu warten, mintestens 10ms, um die Slaves hochkommen zu lassen.

Und spendier mal Kondensatoren zum Entkoppeln: 100nF Keramik für jeden IC.

In twimaster.c:


#define F_CPU ...
#define SCL_CLOCK ...



#define ADDR_DS1307 0xd0

unsigned char reg_addr;
unsigned char data[n];
...

i2c_init();

// dummy write to set address
i2c_start (ADDR_DS1307 | I2C_WRITE);
i2c_write (reg_addr);
i2c_stop();

// read
i2c_start (ADDR_DS1307 | I2C_READ);
data[0] = i2c_readAck ();
data[1] = i2c_readAck ();
...
data[n-2] = i2c_readAck ();
data[n-1] = i2c_readNak ();
i2c_stop();


Mag sein, daß es in einem einzigen Transfer zu machen ist, da ist das Sheet irgendwie unklar.



i2c_start (ADDR_DS1307 | I2C_READ);
i2c_write (reg_addr);
data[0] = i2c_readAck ();
data[1] = i2c_readAck ();
...
data[n-2] = i2c_readAck ();
data[n-1] = i2c_readNak ();
i2c_stop();

surfer
25.07.2005, 15:11
Also... Ich hab jetzt alles nochmals durchgeschaut... UND den I2C Takt runtergesetzt!

UND: ES LÄUFT!!!!!
Danke vielmals!!!! Ohne Dich wäre ich aufgeschmissen!!!
Jetzt läufts.... Juhui.... Mercimerci!!!!!!