2C: StartCondition bleibt stecken

Hemi

Aktives Mitglied
Premium Benutzer
30. Nov. 2008
1.103
19
38
Korntal-Münchingen, Germany
Sprachen
  1. ANSI C
  2. C++
  3. PHP
  4. Java
I2C: StartCondition bleibt stecken

Hallo zusammen,

ich habe ein Problem mit I2C und zwar, bleibt meine MCU in der StartCondition stecken.

Die MCU ist ein AtMega644 und I2C-Slave ist ein DS1307. An den SCL und SDA ist jeweils ein 10k Widerstand.

Init-Routine:

Code:
void i2c_init (void) {
	TWSR = 0;
	TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
	TWCR = (1 << TWEN);
}

Und hier ist die StartCondition:

Code:
void i2c_start (void) {
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 	// Senden der Start-Condition
	while (!(TWCR & (1<<TWINT))); 				// Warten bis übertragen
}

In der While bleibt er stehen und kommt nicht mehr raus.

Habt Ihr eine Idee woran das liegen könnte?

Danke & Grüsse
Heinrich
 
Code:
void i2c_start (void) {
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 	// Senden der Start-Condition
	while (!(TWCR & (1<<TWINT))); 				// Warten bis übertragen
}

In der While bleibt er stehen und kommt nicht mehr raus.

Habt Ihr eine Idee woran das liegen könnte?


Hallo Heinrich !

Ich habe zwar keine Ahnung von C ;) , aber wenn dein Programm in der While-Schleife "hängen" bleibt dann würde ich eher darauf tippen, dass kein "Response" kommt.

Liegt es also eher an der Komunikation, als an deinem Programm? :hmmmm:

Stimmt die Slaveadresse des DS1307 wirklich?
Hast du es mal mit 4K7 oder 2K2 Pullup`s versucht?

Grüße,
Cassio
 
Hallo Heinrich,

An den SCL und SDA ist jeweils ein 10k Widerstand.
Das brauchts nicht, wenn Du die Pullups für die beiden aktivierst.
Code:
// Setup PortC
PORTC = 0x00;	// alles aus
DDRC = 0x00;
PORTC |= (1<<PC0) | (1<<PC1);	// Pullup für SCL und SDA

Code:
void i2c_init (void) {
	TWSR = 0;
	TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
	TWCR = (1 << TWEN);
}
hab ich auch so, bis auf die letzte Zeile. TWEN wird erst beim Start gesetzt. Ob das die Ursache ist, kann ich nicht sagen.

Wie hoch hast Du die Gechwindigkeit gesetzt? Ich nehme meist 100kHz
Code:
#define SCL_CLOCK  100000L

Michael
 
Sodelle, jetzt habe ich etwas ausprobiert.

So sieht die Init-Routine aus:

Code:
void i2c_init (void) {
	TWSR = 0;
	TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
}

Und dann die i2c_start:

Code:
void i2c_start (void) {
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 	// Senden der Start-Condition
	while (!(TWCR & (1<<TWINT))); 				// Warten bis übertragen
}

Der Bus läuft mit 100.000Hz:

Code:
#define SCL_CLOCK	100000UL

Ich habe jetzt in die MAIN() einfach mal die i2c_init(); i2c_start(); und i2c_stop(); aufgenommen. Dann schicke ich die MCU für 1 Sekunde schlafen und mache noch mal ein i2c_start(); und i2c_stop();

Das Interessante an der Sache ist, einmal läuft start und stop problemlos durch, dann aber nicht mehr, er bleibt in der while vom i2c_start() hängen und kommt da nicht mehr raus.

@Cassio: Ja, mit 4k7 habe ich es schon probiert. Die waren davor schon drin, jetzt habe ich es mit 10k.

Grüsse
Heinrich
 
Hallo zusammen,

Ich habe jetzt in die MAIN() einfach mal die i2c_init(); i2c_start(); und i2c_stop(); aufgenommen. Dann schicke ich die MCU für 1 Sekunde schlafen und mache noch mal ein i2c_start(); und i2c_stop();

Das Interessante an der Sache ist, einmal läuft start und stop problemlos durch, dann aber nicht mehr, er bleibt in der while vom i2c_start() hängen und kommt da nicht mehr raus.

@Cassio: Ja, mit 4k7 habe ich es schon probiert. Die waren davor schon drin, jetzt habe ich es mit 10k.
und dies ist genau der Augenblick an dem man ein Speicherscope einsetzen
könnte um sich mal anzusehen was da auf dem Bus überhaupt abgeht.

Wenn vorhanden dann würde ich das jetzt einsetzen.

Gruß
Dino
 
Tja Dino, das ist genau das Ding, was ich nicht habe :(

Meine Vermutung ist es, dass derDS1307 irgendwie abstürzt oder sowas.

Grüsse
Heinrich
 
Hallo Heinrich,

Tja Dino, das ist genau das Ding, was ich nicht habe :(

Meine Vermutung ist es, dass derDS1307 irgendwie abstürzt oder sowas.
Die Betriebsspannung muß um einen bestimmten Faktor über der Batteriespannung
des DS1307 sein sonst stellt er sich tot (TimeKeeper-Funktion).
Schau dir mal das Datenblatt an. Den genauen Wert hab ich grade nicht mehr
im Kopf. Ich glaube wenn man ohne Batterie arbeiten will dann muß man den
VBatt-Pin auf GND legen. Ist jetzt nur so eine Idee.

Gruß
Dino
 
Hallo Heinrich,

dann wäre eigentlich nur noch die stop-Routine ein Kandidat, die hast Du noch nicht gepostet. Dann kann ich die mal mit meiner vergleichen.
Wenn Du sagts, jetzt geht es einmal und dann nicht mehr, tippe ich auf die i2c_stop().

Das mit dem VBAT-Pin ist richtig, der muss auf GND, wenn DU keine STützbatterie anschließt.

Michael
 
Hallo Michael,

die Stop-Routine ist eigentlich ganz trivial:

Code:
void i2c_stop (void) {
	TWCR =  (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);	// Senden der Stop-Condition
}

Die Stützbatterie ist natürlich angeschlossen, so wie es das Datenblatt vorschreibt. Ich kann man versuchen sie rauszunehmen und VBat an GND zu legen und schauen, wie er sich dann verhält.

Grüsse
Heinrich
 
Hallo Heinrich,

meine Stop sieht so aus:

Code:
void i2c_stop(void)
{
    /* send stop condition */
   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
	
  // wait until stop condition is executed and bus released
  while(TWCR & (1<<TWSTO));

}

Probier es mal damit. Es könnte sein, dass durch Dein Schlafenlegen das stop nicht fertig abgearbeitet wird und beim nächsten Start Probleme bereitet.

Viel Erfolg
Michael
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)