Forum: Mikrocontroller und Digitale Elektronik I2C Bus wird nicht freigegeben nach i2c_start()


von Alex (Gast)


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

von heldvomfeld (Gast)


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ß~

von Alex (Gast)


Lesenswert?

Hallo

ich habe die Pullups auf 1k verkleinert (2k2 hatte ich nicht zur Hand), 
das Problem besteht aber weiterhin (SCL bleibt nach i2c_start() auf low)

von TestX .. (xaos)


Lesenswert?

kannst du mal oszi plots posten ?
SCL auf low ist erstmal ok, wenn eine start condition gesendet wurde ist 
das der normale zustand mit eine stop condition gesendet wird.

von heldvomfeld (Gast)


Lesenswert?

dann tausch die Widerstände zurück, bei 1k könnte der Strom für die Pins 
des µC zu groß sein. Baudrate gecheckt?

gruß~

von TestX .. (xaos)


Lesenswert?

heldvomfeld schrieb:
> dann tausch die Widerstände zurück, bei 1k könnte der Strom für die Pins
> des µC zu groß sein. Baudrate gecheckt?
>
> gruß~

an den widerständen liegt das nicht... alles von 1...10k funktioniert 
bei 3.3v..

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

die Pullups habe ich wieder auf 4k7 geändert.
DS0000.png zeigt die Aktivität von i2c_start().
DS0001.png zeigt die Pegel danach.

Ich hoffe das hilft.

von Alex (Gast)


Lesenswert?

achja, Frequenz sind überprüfte 100kHz

von TestX .. (xaos)


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

von Alex (Gast)


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.

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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

von Alex (Gast)


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.

von Krapao (Gast)


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

von Alex (Gast)


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.

von Alex (Gast)


Lesenswert?

In einem anderen Projekt setze ich übrigens den MMA7455L erfolgreich mit 
SPI Interface ein. Daher verstehe ich nicht warum ich das (eigentlich 
simplere) I2C Interface nicht zum laufen bekomme.

von Krapao (Gast)


Lesenswert?

Hast du den nackigen Sensor von Freescale oder bereits ein Modul wie 
z.B. von Parallax?

Vielleicht mal CS nicht frei bambeln lassen wie in der Appnote von 
Parallax 
(http://www.parallax.com/Portals/0/Downloads/docs/prod/sens/28526-MMA7455-3axisAccel-v1.1.pdf) 
sondern mit einem Pullup dauerhaft auf HIGH legen.

von Alex (Gast)


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

von Krapao (Gast)


Lesenswert?

Hmm, jetzt gehen mir die Ideen aus :-(

von Alex (Gast)


Lesenswert?

Schade, mir auch...

von Klaus (Gast)


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

von Alex (Gast)


Lesenswert?

Hallo Klaus,

i2c_stop() wird auch aufgerufen, siehe die beiden Code Auszüge.
Nur einen Screenshot davon habe ich nicht, da der µC gar nicht soweit 
kommt.

Frage an I2C Kenner: seht ihr auf den Screenshots DS002 bis DS004 ACKs 
vom Slave?

von Alex (Gast)


Lesenswert?

Man sieht auf den Shots 2 bis 4 doch NACKs oder?
NACK == high, ACK == low ?

von Klaus (Gast)


Lesenswert?

Alex schrieb:
> NACK == high, ACK == low ?

ACK ;-)
ich merk es mir so: wenn keiner etwas macht, ist der Bus high durch den 
Pullup, also ist high NACK. Wenn sich einer angesprochen fühlt, wird er 
aktiv und erzeugt ein low.

MfG Klaus

von Thorsten (Gast)


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.

von Klaus (Gast)


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

von Klaus (Gast)


Lesenswert?

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

von Alex (Gast)


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.

von Alex (Gast)


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

von Thorsten (Gast)


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.

von Krapao (Gast)


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)

von Thorsten (Gast)


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.

von Alex (Gast)


Lesenswert?

Hallo Krapao

ja, das habe ich inzwischen behoben. Dein erwartetes Muster 2 kommt nun 
auch.
Problem besteht weiterhin

von Krapao (Gast)


Lesenswert?

Das geht aus Beitrag "Re: I2C Bus wird nicht freigegeben nach i2c_start()" nicht 
so klar hervor.

Aber wenn du sagst, dein Oszibild entspricht jetzt dem Muster aus 2 
und du benutzt die Fleury-I2C-Library mit
1
#define MMA7455_SLAVE_ADDRESS (0x3A)
bin ich wieder ratlos. Wäre definitiv eine Fehlerquelle gewesen, die 
deine Beobachtung erklärt.

von Thorsten (Gast)


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.

von Alex (Gast)


Lesenswert?

Hallo zusammen,

nachdem mir und euch die Ideen ausgegangen sind,
habe ich den IC ausgetauscht.....

ACK kommt nun, Daten auch.

Vielen Dank für euer Bemühen, schönen Abend !

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.