Hallo, Ich mache gerade meine ersten Gehversuche mit einer Real Time Clock (ds1737). Für die Kommunikation benutze ich die TWI Funktionen des Atmega8. Der Großteil des Programms ist auch funktionsfähig. Ich kann Einstellungen an die RTC übertragen und danach erfolgreich einen Wert aus der RTC lesen. Nach dem lesen des Wertes sende ich ein NACK auf dem TWI und danach ein STOP. Versuche ich nun das ganze Prozedere von vorne zu starten, bleibt der Controller in der Schleife hängen, in der ich nach dem Senden des START Signal auf das setzten von TWINT warte. (Zeile 108) Ich bin was Mikrocontroller angeht noch blutiger Anfänger und wundere mich eigentlich permanent darüber dass ich bis hierher gekommen bin. Aber dieses Problem konnte ich nun seit mehreren Stunden nicht lösen. Ich kann mir nicht erklären warum das erneute START Signal nicht gesendet wird. Meine Vermutung ist, dass der BUS aus irgendeinem Grund noch busy ist, dürfte er aber nicht sein. Ich habe leider auch kein Oszilloskop um das zu überprüfen. Kann es ggf. sein, dass es einen Fehler in meiner _twi_send_nack() methode gibt, sodass die RTC nicht aufhört zu senden und so das STOP Signal bereits fehlschlägt? Hat hier jemand eine Idee?
Hi >Ich mache gerade meine ersten Gehversuche mit einer Real Time Clock >(ds1737). Und welchen benutzt du wirklich? MfG Spess
Hi > _twi_read(RTC_ADDR); > uint8_t secs = _twi_rec(); > _twi_send_nack(); > _twi_stop(); sieht etwas ulkig aus. Beim Lesen mehrerer Bytes werden werden bis auf das Letzte die Bytes vom Master mit ACK bestätigt. Das letzte Byte wird mit einem abschließenden NACK vom Master gelesen. Das Senden eines einzelnen NACK funktioniert nicht. MfG Spess
Spess53 schrieb: > Beim Lesen mehrerer Bytes werden werden bis auf > das Letzte die Bytes vom Master mit ACK bestätigt. Das letzte Byte wird > mit einem abschließenden NACK vom Master gelesen. Laut Datenblatt des DS1337 muß das aber so sein. Christian Kosmowski schrieb: > Ich habe leider auch kein Oszilloskop Überprüf mal mit einem Multimeter, ob BEIDE Leitungen vor dem START auf H-Pegel sind.
Hi >Laut Datenblatt des DS1337 muß das aber so sein. Was? Sieh dir doch mal das Datenblatt S.14 an. Das Senden von NACK muss aber dem AVR vor dem Lesen des letzten Bytes mitgeteilt werden. MfG Spess
Nach dem Datenblatt, das ich vom DS1337 habe, muß das letzte gelesene Byte mit NACK "bestätigt" werden. "The DS1337 must receive a “not acknowledge” to end a read."
Habe die beiden Leitungen überprüft. Während der controller sich in der Warteschleife tot läuft ist SCL low und SDA high.
Spess53 schrieb: > Das Senden von NACK muss > aber dem AVR vor dem Lesen des letzten Bytes mitgeteilt werden. Sorry, Mißverständnis meinerseits. Ist klar, der letzte Lesebefehl muß OHNE gesetztes TWEA erfolgen, das NACK wird also schon mit übergeben.
Hi >Sorry, Mißverständnis meinerseits. Ist klar, der letzte Lesebefehl muß >OHNE gesetztes TWEA erfolgen, das NACK wird also schon mit übergeben. Genau das meinte ich. MfG Spess
Christian Kosmowski schrieb: > Während der controller sich in der > Warteschleife tot läuft ist SCL low und SDA high. Vermutlich will der DS1337 weiter senden, weil er kein NACK bekommt.
Okay, super. Ich glaube dann habe ich verstanden was das Problem ist. Ich lese zuerst das Byte und führe dann die Funktion _twi_send_nack(); mit der ich eigentlich nur TWEA auf 0 setze. Ich habe gedacht, er würde dann tatsächlich das NACK nochmal "hinterherschicken". [...] void _twi_send_nack(){ TWCR = _BV(TWINT) | _BV(TWEN); } [...] uint8_t secs = _twi_rec(); _twi_send_nack(); tatsächlich, muss aber TWEA VOR dem lesen auf 0 sein und er verschickt es dann automatisch nach dem nächsten Lesevorgang. Ist das soweit richtig? Wenn ich das ganze also umdrehe: _twi_send_nack(); uint8_t secs = _twi_rec(); sollte es klappen. Klingt zumindest erstmal einleuchtend. Ich werde das nachher mal ausprobieren. Vielen Dank schonmal!
Chris K. schrieb: > Wenn ich das ganze also umdrehe: > _twi_send_nack(); > uint8_t secs = _twi_rec(); > > sollte es klappen. Im Sinne der maximalen Verwirrtheit: ja Tatsächlich solltest du einen Umbau deiner Funktionen ins Auge fassen. Entweder gibst du der twi_rec Funktion mit, ob sie mit einem ACK oder einem NAK weitermachen soll, oder du machst dir 2 getrennte Receive Funktionen in denen du die Unterscheidung durchführst. Aber darauf zu setzen, dass der Aufrufer das alles schon richtig machen wird - nun, heute weißt du das noch. Aber in einem halben Jahr sieht das alles ganz anders aus. Es liegt an dir, ob du das heute so gestaltest, dass es in Zukunft fehleranfällig ist oder nicht. so zb sehen die verfügbaren Funktionen bei P.Fleurys Lib aus
1 | void i2c_init(void); |
2 | void i2c_stop(void); |
3 | unsigned char i2c_start(unsigned char addr); |
4 | unsigned char i2c_rep_start(unsigned char addr); |
5 | void i2c_start_wait(unsigned char addr); |
6 | |
7 | unsigned char i2c_write(unsigned char data); |
8 | |
9 | unsigned char i2c_readAck(void); |
10 | unsigned char i2c_readNak(void); |
Beachte: es gibt 2 read-Funktionen: readAck und readNak
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.