I2C Bus wird nicht freigegeben nach i2c_start()

Gast #2365861
Lesenswert?

Hallo Zusammen.

Ich arbeite mit einem ATMega324 @ 16MHz und der I2C Lib von Peter 
Fleury.
Mein Board läuft mit 3,3V, Pullups mit 4k7 sind auf SDA und SCL 
vorhanden.

Die Lib verwende ich folgendermaßen:
1
     i2c_init();                             // initialize I2C library
2

3
     // write 0x75 to EEPROM address 5 (Byte Write) 
4
     i2c_start(MMA7455_SLAVE_ADDRESS+I2C_WRITE);     // set device address and write mode
5
     i2c_write(reg);                        // write address = 5
6
     i2c_write(data);                        // write value 0x75 to EEPROM
7
     i2c_stop();                             // set stop conditon = release bus

i2c_start() funktioniert noch, d.h. die Start Condition und die Slave 
Adresse werden erfolgreich ausgegeben.
Mein Problem ist nun dass der Bus nach i2c_start() (oder alternativ 
i2c_start_wait()) nicht mehr freigegeben wird, d.h. SCL bleibt auf Low 
Pegel.
Dadurch wird in i2c_write() nie das TWINT Bit gesetzt, wodurch die Lib 
in der while schleife hängen bleibt:
1
unsigned char i2c_write( unsigned char data )
2
{  
3
    uint8_t   twst;
4
  // send data to the previously addressed device
5
  TWDR = data;
6
  TWCR = (1<<TWINT) | (1<<TWEN);
7

8
  // wait until transmission completed
9
  while(!(TWCR & (1<<TWINT)));

Auf dem Bus ist nach i2c_start() keinerlei Aktivität mehr zu sehen.
Um den Slave als Fehlerquelle auszuschließen ist dieser momentan nicht 
angeschlossen, er kann also nicht SCL auf Low ziehen.

Ich hoffe ihr könnt mir helfen.
Grüße, Alex
Gast #2366022
Lesenswert?

Ich arbeite nicht mit einem ATMEGA, sondern programmiere eher PICs. Mein 
erster Tip ohne mich jetzt näher mit der Software zu beschäftigen wäre, 
die Pullups auf 2,2k zu verkleinern. Bei 3,3V erscheinen sie mir zu 
groß, da schon ein gewisser Strom fließen muss.

gruß~
#2366145
Lesenswert?

jo das ACK vom slave fehlt, beim 9ten clockbit müsste auf der SDA 
leitung ein low pegel zu sehen sein.
wenn der slave kein ack sendet ist das was du siehst das normale 
verhalten. in diesem fall wird vom TWI modul eigtl auch ein fehlerflag 
gesetzt, dass deine lib aber nicht auszuwerten scheint
Gast #2366209
Lesenswert?

Hallo,

danke für den Tip, dann sollte ich doch den Slave anschliessen :)
Nachdem ich die Slave Adresse nun korregiert habe, kommt ein ack und das 
Schreiben klappt.

Nun habe ich allerdings dasselbe Problem beim Lesen vom I2C:
1
     i2c_init();                             // initialize I2C library
2
     i2c_start(MMA7455_SLAVE_ADDRESS+I2C_WRITE);     // set device address and write mode
3

4
     i2c_write(reg);                        // write address = 5
5
     i2c_rep_start(MMA7455_SLAVE_ADDRESS+I2C_READ);       // set device address and read mode
6

7
     *data = i2c_readNak();                    // read one byte from EEPROM
8
     i2c_stop();

nach i2c_rep_start() bleibt SCL wieder auf Low und i2c_readNak() bleibt 
wieder in der Schleife hängen.
1
unsigned char i2c_readNak(void)
2
{
3
  TWCR = (1<<TWINT) | (1<<TWEN);
4
  while(!(TWCR & (1<<TWINT)));
5
  
6
    return TWDR;
7

8
}/* i2c_readNak */

Die Slaveadresse stimmt nun aber.
Gast #2366695
Lesenswert?

Ich habe nun noch einen anderen I2C Slave (Tempsensor statt 
Beschleunigungssenor) mit der Lib unter den selben Bedingungen getestet.
Dieser antwortet sofort und korrekt.

Also hat wohl der Beschleunigungssensor noch irgendein Problem.
Gast #2366738
Lesenswert?

Nur ein Schnellschuss: Prüfe die Initialisierung des 
Beschleunigungssenors.

Beim MMA7455L: ±2g/±4g/±8g Three Axis Low-g Digital Output Accelerometer 
(#1) muss zuerst vom voreingestellten 4-Wire SPI Interface auf das 
3-Wire SPI Interface umgestellt werden. Dafür gibt es das Mode Control 
Register ($16). In Verbindung mit einer fest verdrahteten CS Leitung 
kann man anschliessend eine I2C Verbindung benutzen.

#1 
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA745xL
Gast #2366755
Lesenswert?

:) genau diesen Beschleunigungssensor habe ich.
Und im Moment initialisiere ich ihn auch auf 4wire SPI, da ich dachte 
dass dies keine Auswirkung auf den I2C Betrieb hat.

Ich schreibe in das MCTL Register nun 0x25, also 3wire SPI, 2g Mode, 
Measurement Mode.

Allerdings bleibt das Problem bestehen.
Gast #2366813
Lesenswert?

Ich habe den nackten Sensor auf nem selbstgeätzten Board um ihn 
Steckbrett kompatibel zu machen. Genau dieses Board habe ich schon für 
ein altes Projekt benutzt mit SPI Interface.
Im aktuellen Aufbau habe ich CS direkt (ohne Pullup) auf High gelegt, 
wie im Datenblatt angegeben
Gast #2367131
Lesenswert?

Alex schrieb:
> Hier noch die Scopescreens:
> DS0002.png Aktivität von i2c_start
> DS0003.png Aktivität von i2c_write
> DS0004.png Aktivität von i2c_rep_start
> DS0005.png Pegel nach i2c_rep_start

Mir fällt auf, du schreibst von i2c_start, i2c_write, i2c_rep_start aber 
nichts von i2c_stop. Ich kenne deine Funktionen nicht, aber wenns ein 
i2c_start gibt, sollte es auch ein i2c_stop geben.

MfG Klaus
Gast #2367267
Lesenswert?

die Signale auf den Bildern DS0002, DS0003 und DS0004 erfüllen meiner 
Meinung nach alle nicht die Voraussetzung eines ACKs. Bei einem ACK muss 
der Slave die Datenleitung auf low ziehen BEVOR der Clock das neunte Mal 
auf High geht. In allen drei Fällen liegt die Datenleitung aber auf 
High, wenn der Clock das neunte Mal auf High geht, das sollte der Master 
als NACK interpretieren.

Warum immer ein NACK kommt weiß ich nicht, da ich den 
Beschleunigungssensor nicht kenne.
Gast #2367270
Lesenswert?

Aber mal zurück zum Anfang:

Wenn nur der Master auf dem Bus ist, Pullups natürlich auch, muß eine 
Sequenz von

i2c_start
i2c_write(irgendwas)
i2c_stop

den Bus nach 9 Takten wieder zur Ruhe (alles high) bringen. Der Status 
von write muß NACK liefern. Bevor das nicht erreicht ist, würde ich es 
mit einem Slave nicht versuchen.

MfG Klaus
Gast #2367284
Lesenswert?

Also der Temperatursensor kommuniziert ja bestens mit meinem Master. Ein 
schönes ACK dh lowpegel bevor die 9te steigende Taktflanke kommt.

Der Beschleunigungssensor liefert NACK dh highpegel bevor die 9te 
steigende Taktflanke kommt. Im Datenblatt wird leider nicht erwähnt 
unter welchen Umständen ein NACK erzeugt wird.

Ich habe nun die Frequenz auf 50 kHz halbiert und als Wartezeit bevor 
der I2C das erste mal "losfeuert" von 1ms auf 1s erhöht.

Zwischendurch habe ich mal bemerkt dass ich die Slaveadresse immer noch 
falsch hatte (0x1D um 1 Bit nach links geschoben). Dieser Fehler erzeugt 
aber auch dasselbe Verhalten. Eigentlich sollte sich bei falscher 
Adressierung der Baustein doch nicht angesprochen fühlen und einfach nix 
machen.

Also selbes Problem mit MMA7455 bei halber Taktfrequenz und richtiger 
und falscher Adresse.
Gast #2367286
Lesenswert?

Ich habe nun noch alle beiden Slaves vom Bus abgeklemmt (pullups 
weiterhin vorhanden) und es zeigt sich dasselbe Problem. Der NACK 
scheint also nicht vom Beschleunigungssensor erzeugt zu sein, sondern 
wie Klaus schon geschrieben hat durch die Pullups
Gast #2367296
Lesenswert?

Klaus schrieb:
> Thorsten schrieb:
>> Warum immer ein NACK kommt weiß ich nicht, da ich den
>> Beschleunigungssensor nicht kenne.
>
> Das muß nicht am Sensor liegen, NACK kommt auch von alleine, wenn keiner
> den Bus low zieht.
>
> MfG Klaus

Ich meinte damit, dass ich den Sensor nicht kenne und dadurch nichts 
genaueres sagen kann, ob man bei diesem Baustein etwas beachten muss 
oder nicht. Ich hab nur darauf hinweisen wollen, dass keines der Pakete 
mit einem ACK bestätigt wird. Warum das so ist, ob es am Sensor oder am 
Master liegt, weiß ich nicht.
Gast #2367309
Lesenswert?

> DS0002.png Aktivität von i2c_start

In diesem Bild lese ich die Bitsequenz
1
<Start><0><0><1><1><1><1><0><write><nack>

Es gibt eine Konfusion, wie Hersteller die slave address in der Doku 
angeben - mit/ohne RW-Bit, mit ohne Shift nach links...
http://www.totalphase.com/support/kb/10039/

Ich gehe davon aus, dass die 0x1D in der Freescale Doku eine korrekte 
7-Bit ([6:0]) Adresse ist. D.h. 1 zeigt nicht die I2C slave address 
$1D, wie sie in der Freescale Doku beschrieben ist (S. 16), sondern die 
slave address $1E.

Ich hätte das folgende Muster erwartet:
2
<Start><0><0><1><1><1><0><1><write>...

Die Fleury-I2C-Lib schickt die an i2c_start übergebene Adresse (inkl. 
RW-Bit) 1:1 and die TWI Schnittstelle. D.h. man muss sich um das Shiften 
der slave address um 1 Bit nach links selbst kümmern. Ich würde das 
deshalb bei der Definition berücksichtigen - Adresse aus der  Doku der 
Lesbarkeit halber eintragen und gleich 1x shiften.
1
#define MMA7455_SLAVE_ADDRESS (0x1D<<1)
Gast #2367310
Lesenswert?

Alex schrieb:
> Ich habe nun noch alle beiden Slaves vom Bus abgeklemmt (pullups
> weiterhin vorhanden) und es zeigt sich dasselbe Problem. Der NACK
> scheint also nicht vom Beschleunigungssensor erzeugt zu sein, sondern
> wie Klaus schon geschrieben hat durch die Pullups

Zum Verständnis: Genau das ist die Aufgabe der Pullups. Master und Slave 
sind nur in der Lage die Leitungen auf Low zu ziehen. Wenn alle "die 
Füße still halten", wird die Leitung durch die Pullups auf High gezogen.

Ein NACK ist keine aktive Handlung eines Bausteins, sondern bedeutet 
nur, dass keiner aktiv reagiert und die Leitung auf low zieht (ACK).

Stell dir eine Menschenmenge vor. Du bist der Master und rufst einen 
Namen in die Runde (unter der Annahme, dass jeder Name nur einmal 
vertreten ist). Derjenige, der sich angesprochen fühlt, wird sich 
melden, alle anderen werden nicht reagieren. Fühlt sich keiner 
angesprochen (die gesuchte Person ist nicht da) oder einer hat dich 
vielleicht nicht verstanden, meldet sich halt keiner.
Gast #2367343
Lesenswert?

Wenn ich das Datenblatt richtig deute, gilt die Addresse 1D (bzw. 1D << 
1) nur wenn der Pin IADDR0 auf High liegt. Wie hast du den Pin 
beschaltet? Liegt der Pin auf Low, müsste die Adresse entsprechend 1C 
(bzw. 1C << 1) sein.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren