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.
Nee der Fehler kommt nach dem Aufruf twi_start_mit_addr(0xd0). Die Addresse stimmt scheinbar nicht.Er kommt nicht aus twi_addr(...) heraus
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?
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 .
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
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
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!?
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.