Forum: Compiler & IDEs RTC(DS1307) Problem mit Addresse


von Ralf S. (Gast)


Angehängte Dateien:

Lesenswert?

Moin moin,

ich muss mit einem RTC (DS1307) über TWI kommunizieren.

Habe erst mal ein paar Grundfunktionen programmiert.

Wenn ich aber die Funktion twi_addr(0xd0) aufrufe bekomme ich immer 
einen Fehler mit der Addresse.
Bzw mein Dislay zeigt mit den txt: "Error:TWIaddr"

Was mache ich falsch?

Habe den Atmega16 mit 8MHz.

von 42 (Gast)


Lesenswert?

Zeile 42 im Hauptprogramm...

von Ralf S. (Gast)


Lesenswert?

Nee der Fehler kommt nach dem Aufruf twi_start_mit_addr(0xd0).
Die Addresse stimmt scheinbar nicht.Er kommt nicht aus twi_addr(...)
heraus

von 42 (Gast)


Lesenswert?

Ralf S. schrieb:
> Nee der Fehler kommt nach dem Aufruf twi_start_mit_addr(0xd0).
> Die Addresse stimmt scheinbar nicht.Er kommt nicht aus twi_addr(...)
> heraus
>
und wer sagt dir, dass der Fehler nicht schon in Zeile 42 deines 
Hauptprogramms gemacht wird?

von Ralf S. (Gast)


Lesenswert?

Ich weiss nicht welche Zeile du meinst ,aber wenn du auf die Antwort für 
alles anspielst "42" bitte ich dich den Kinderkram zu lassen .

von Karl H. (kbuchegg)


Lesenswert?

Ich würde mal damit anfangen, hier
1
void twi_start(void)
2
{
3
  TWCR =  (1<<TWINT)|(1<<TWSTA) | (1<<TWEN);
4
  
5
  
6
  while((TWCR & (1<<TWINT)))
7
  {  
8
    Write_String("Error: TWIstart");
9
    CurserHome();
10
    _delay_ms(1000);
11
  }
12
  
13
}
dann auch darauf zu warten, bis TWINT von der TWI-Hardware gesetzt wird 
und nicht so wie du die Funktion schon zu verlassen, während die 
Hardware noch am Start-Zustand arbeitet.

Das könnte sich auf das nachfolgende Versenden der Adresse günstig 
auswirken, wenn sichergestellt ist, dass die TWI Hardware auch 
aufnahmebereit ist.


Im Datenblatt ab Seite 183 ist das alles doch ausführlichst beschrieben. 
Inklusive der "Tabelle" auf Seite 185, in der der ganze Vorgang auch in 
C haarklein ausprogrammiert ist.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

PS: Du scheinst nicht wirklich begriffen zu haben, wie das funktioniert.
Mittels
1
  TWCR = .... ( 1 << TWINT ) ....
wird das TWINT Flag GELÖSCHT!
Darauf hin fängt die Hardware zu buddeln an, und wenn sie damit fertig 
ist, dann setzt sie TWINT. Ob da jetzt ein Fehler aufgetreten ist oder 
nicht, das verrät dir das TWINT Flag überhaupt nicht. TWINT erlaubt dir 
nur die Aussage "Ich buddle noch" oder "Ich bin fertig".

D.h. du wirst IMMER darauf warten, dass die TWI fertig wird. Es heißt 
immer
1
  // warte bis die TWI fertig ist
2
  while( !( TWCR & ( 1 << TWINT ) ) )
3
    ;

ob die Operation gut gegangen ist oder nicht, das erzählt dir der INhalt 
des TWSR Registers. TWINT hat damit nichts zu tun. TWINT erzählt dir 
nur, ob du schon in TWSR nachsehen kannst, oder ob die TWI noch am 
buddeln ist.

: Bearbeitet durch User
von Ralf S. (Gast)


Lesenswert?

Erstmal danke , ok das stimmt  dort muss ein ! hin.
Nur jetzt hab ich immer den Fehler:"Error: TWIstart".

Wenn ich mein RTC aufstecke, leuchten PC3 und PC4 (SCL und SDA)
Guck ich mir den Zustand mit nem Oszi an ,bleiben die beiden PIN's auf 
High.
Ich müsste doch die Start Übertragung sehen!?

von Karl H. (kbuchegg)


Lesenswert?

Ralf S. schrieb:
> Erstmal danke , ok das stimmt  dort muss ein ! hin.
> Nur jetzt hab ich immer den Fehler:"Error: TWIstart".

Ja, das glaub ich sofort, dass du hier
1
void twi_start(void)
2
{
3
  TWCR =  (1<<TWINT)|(1<<TWSTA) | (1<<TWEN);
4
  
5
  
6
  while(!(TWCR & (1<<TWINT)))
7
  {  
8
    Write_String("Error: TWIstart");
9
    CurserHome();
10
    _delay_ms(1000);
11
  }
12
  
13
}

eine Fehlermeldung kriegst.
So ein µC ist doch kein Wunderwuzzi!

Nach dem
1
  TWCR =  (1<<TWINT)|(1<<TWSTA) | (1<<TWEN);
dauert das seine Zeit, bis der Startmode durch ist! Wenn du danach 
sofort
1
  while(!(TWCR & (1<<TWINT)))
2
  {  
3
    Write_String("Error: TWIstart");
die Übertragung als gescheitert erklärst, nur weil der TWI noch am 
werken ist, dann kriegst du eine Fehlermeldung.

Aber: die ganze Auswertung ist falsch
1
void twi_start(void)
2
{
3
  TWCR =  (1<<TWINT)|(1<<TWSTA) | (1<<TWEN);
4
  
5
  while(!(TWCR & (1<<TWINT)))
6
    ;
7
8
  if( (TWSR & 0xF8) != START) {  
9
    Write_String("Error: TWIstart");
10
    CurserHome();
11
  }
12
}

von Ralf S. (Gast)


Angehängte Dateien:

Lesenswert?

Ok danke, nur habe ich jetzt das Problem das er nicht mehr aus der 
Warteschleife rauskommt :(
Kann ich jeden Port beim At16 benutzen für die TWI Kommunikation?

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.