Hallo Liebe Forengemeinde, Kurz vorweg ist dies mein erster Beitrag, also bitte nicht prügeln :) Ich habe alle bestehenden Beiträge durchstöbert, habe jedoch nicht meinen Spezial-Fall gefunden. Bin dabei den leidigen DS1307 RTC anzusteuern. Ich habe folgendes Modul 2 mal zuhause: https://www.ebay.de/itm/2PCS-Arduino-I2C-RTC-DS1307-AT24C32-Real-Time-Clock-Module-For-AVR-ARM-PIC-SMD/272950653008?_trkparms=aid%3D222007%26algo%3DSIM.MBE%26ao%3D2%26asc%3D49133%26meid%3Deeee0f071d7d4c428fddd08574273458%26pid%3D100623%26rk%3D3%26rkt%3D6%26sd%3D152484121686&_trksid=p2047675.c100623.m-1 Angeschlossen an meinen uC sind GND, VCC, SDA und SCL. Ich programmiere in C mittels KeiluVision einen 8051er von Silabs. (f310) nun zu meinem Problem: Ich bekomme, außer nach dem Übertragen der BusAdresse (+ Read/Write-Bit), also 0xD0 bzw. 0xD1, kein ACK-bit vom DS1307 zurückgesendet egal welche Bytes ich sende... Beispielcode mit Anmerkung: start(); write(D0); // ACK-Bit wird vom DS1307 gesendet write(Adresse zum beschreiben); // kein ACK-Bit wird gesendet write(Inhalt); // kein ACK-Bit wird gesendet stop(); d.h. bei allen weiteren gesendeten Bytes, bekomme ich keine Rückmeldung des ICs. beim Senden von 0xD0 direkt nach dem Start-Befehl aber schon! Seltsamerweise habe ich mit meinem Code (bis auf Änderung im Sende-aufbau) bei anderen Chips - sei es der am Board mitverbaute EEPROM-AT24C32, PWM-Controller, Display SSD1306 - per I²C keine Ansteuerungsprobleme. Ich habe auch ein Programm, welches alle I²C-Adressen am Bus ausließt und es werden 0xD0 und 0xD1 des DS1307 erkannt. Die Übertragung habe ich am Oszi natürlich mit meinem Wissen schon überprüft. Ich habe mir derweil den DS3231 bestellt der genauer sein soll. Wenn der ohne Probleme läuft habe ich vermutlich einen Fake-IC erhalten. Hatte von euch schon jemand das selbe Problem?? Beste Grüße Manuel
wenn du nur ein Byte oder das letzte Byte liest dann gibts NACK ACK gibts nur bei einer Reihe von Byte welches nicht das Letzte ist. Ich hatte mit der Fleury Lib keine Probleme und neu mit der Arduino LIB auch nicht. Da muss was in deiner SW falsch laufen, ACK vs. NACK nicht verstanden?
Hallo Joachim, Meiner Erkenntnis nach folgt nach jedem schreiben von Bytes ein ACK und beim lesen eines Bytes ein NACK. Im meinem Fall funktioniert nicht mal das schreiben eines Bytes auf eine Adresse. Hier gibt es meines Wissens nur ACKs. (wie im Bild)
Manuel _. schrieb: > Meiner Erkenntnis nach folgt nach jedem schreiben von Bytes ein ACK und > beim lesen eines Bytes ein NACK. nein bei einer aufeinander folgenden Bytefolge (Block Read/Write) gibts ein ACK und beim letzen Byte ein NACK so hatte ich das verstanden, müsste noch mal in meinen alten Fleury Code schauen für die Clock, liegt bei mir schon wieder Jahre zurück. lesen
1 | i2c_write(SECONDS); // write address = SECONDS |
2 | i2c_rep_start(DS3231+I2C_READ); // set device address and read mode |
3 | _rtc_t[2]=bcdtoint(i2c_readAck()&0x7f); // sekunden |
4 | _rtc_t[1]=bcdtoint(i2c_readAck()&0x7f); // minuten |
5 | _rtc_t[0]=bcdtoint(i2c_readAck()&0x3f); // stunden |
6 | _rtc_d[4]=i2c_readAck()&7; // wt |
7 | _rtc_d[0]=bcdtoint(i2c_readAck()&0x3f); // tag |
8 | _rtc_d[1]=i2c_readAck(); // monat mit CENTURY |
9 | _rtc_d[2]=i2c_readNak(); // jahr |
10 | i2c_stop(); |
man sieht NACK nur beim letzten Byte bei write dito
1 | i2c_write(SECONDS); // write address = SECONDS |
2 | i2c_rep_start(DS3231+I2C_READ); // set device address and read mode |
3 | _rtc_t[2]=i2c_readAck()&0x7f; // Seconds |
4 | _rtc_t[1]=i2c_readAck()&0x7f; // Minutes |
5 | _rtc_t[0]=i2c_readNak()&0x3f; // Hours |
6 | i2c_stop(); |
Moin, Habe mich jetzt nochmal kurz eingelesen.. So wie ich dies jetzt verstanden habe: Beim Schreiben: Nach dem Senden der Busadresse // ACK vom SLAVE Nach dem Senden jedes Bytes // ACK vom SLAVE - auch beim letzten Byte Beim Lesen: Nach dem Senden der Busadresse // ACK vom SLAVE Nach dem Senden der Blockadresse // ACK vom SLAVE Nach dem Senden der Busadresse inkl. Read-Befehl // ACK vom SLAVE Nach dem Übermitteln der Daten // ACK vom Master Nach dem übermitteln aller weiterer Daten //ACK vom Master Nach dem Übermitteln des letzten Bytes // Not acknowlege vom Master In deinem Beispielcode konkret: i2c_write(SECONDS); // ACK vom SLAVE i2c_rep_start(DS3231+I2C_READ); // ACK vom SLAVE _rtc_t[2]=i2c_readAck()&0x7f; // ACK vom Master _rtc_t[1]=i2c_readAck()&0x7f; // ACK vom Master _rtc_t[0]=i2c_readNak()&0x3f; // NACK vom Master i2c_stop(); Liege ich hier richtig? Ich habe aber schon das Problem, dass ich bei "i2c_write(SECONDS);" nicht einmal ein ACK vom Slave - also "DS1307" bekomme.... Ich bekomme ausschließlich bei "i2c_write(Busadresse) eine Rückmeldung... Wie bereits erwähnt hatte ich bei anderen I²C-Geräten keinerlei Probleme. Am Beispiel des AT24C32 Z.B bekomme ich nach dem "Senden" jedes Bytes eine ACK Rückmeldung.. Beim DS1307 nur direkt nach dem Senden der Busadresse.. lg Manuel
Und die Batterie ist eingelegt und hat 3.0 Volt. Es funktioniert mit beiden Modulen nicht
Dann hilft wahrscheinlich nur noch ein Oszi weiter um die Signale einmal genau zu analysieren. Mit welcher Geschwindigkeit arbeitet der IIC, welche PullUps werden benutzt und welche Versorgungsspannungen liegen am uC und am DS an? Gruß TK
Tipp am Rande - die Module funktionieren eigentlich gut, aber der verbaute Quartz war bei mir schon mehrere male extrem ungenau! Mit einem Markenquarz (EPSON) lief das dann wie gewollt. Grüße, egberto
Ich habe mir schon alles am Oszi angesehn, laut mir passts ;) Ich arbeite glaub ich mit mit ca. 30-50kHz... habe aber auch schon auf unter 10kHz verlangsamt, keine Änderung.. Der uC und der DS bekommen 3.3V. Es werden die internen Pullups des uC verwendet, wie gesagt am Oszi siehts sonst schön aus.. Ich glaub ich wird einfach mal auf die neuen Teile warten und werde dann berichten. Danke euch, lg
Ja egberto das habe ich dann im nachhinein erfahren dass die nicht so genau sind. :) Hab mir daher die ds3231 bestellt, welche auch einen Alarm besitzen.
>Es werden die internen Pullups des uC verwendet, wie gesagt am Oszi >siehts sonst schön aus.. Keine gute Idee (aber bei 10kHz kann das funktionieren) Wenn es am Oszi schön aussieht, dann muß doch auch zu sehen sein, wieso nach dem 2. Byte schon ein NACK kommt (und wieso wird danach die Übertragung nicht mit einem STOPP abgebrochen? Wertest Du das ACK/NACK denn nicht aus? Kann es sein, dass Du die Pegel SCL/SDA aktiv treibst?) Gruß TK
Da es nur ein Testaufbau ist verwende ich nur die internen Pullups. Da ich aber ein 128x64 OLED mit 15FPS per IIC ansteuern kann sollts nicht daran liegen. Die Überprüfung der ACK/NACK sind bei mir derzeit deaktiviert damit ich alles am Oszi sehen kann, die Übertragung wird daher nicht abgebrochen. Da ich einen ganzen Block eines EEPROM per IIC beschreiben und lesen kann geht es mir nicht ein warum das das einzige Teil ist das nicht funtioniert...
habe noch mal geschaut Manuel _. schrieb: > Beim Schreiben: i2c_write
1 | //************************************************************************
|
2 | // Send one byte to I2C device
|
3 | //
|
4 | // Input: byte to be transfered
|
5 | // Return: 0 write successful
|
6 | // 1 write failed
|
7 | //************************************************************************
|
8 | unsigned char i2c_write( unsigned char data ) |
9 | { uint8_t twst; |
10 | if(!_i2c_init) |
11 | i2c_init(); |
12 | _i2c_busy=1; |
13 | // send data to the previously addressed device
|
14 | TWDR = data; |
15 | TWCR = (1<<TWINT) | (1<<TWEN); |
16 | |
17 | // wait until transmission completed
|
18 | while(!(TWCR & (1<<TWINT))); |
19 | |
20 | // check value of TWI Status Register. Mask prescaler bits
|
21 | twst = TW_STATUS & 0xF8; |
22 | if( twst != TW_MT_DATA_ACK) return 1; |
23 | return 0; |
24 | } // i2c_write |
write
1 | if(!_time_i2c_rtc) |
2 | { while(_i2c_busy); |
3 | i2c_start_wait(DS3231+I2C_WRITE); // set device address and write mode |
4 | i2c_write(SECONDS); // write address = SECONDS |
5 | i2c_write(int2bcd(atoi(rights(t_bld, 2)))); |
6 | i2c_write(int2bcd(atoi(mids(t_bld, 11, 2)))); |
7 | i2c_write(int2bcd(atoi(mids(t_bld, 9, 2)))); |
8 | |
9 | //UWORD tagesnummer( UWORD jahr, UBYTE monat, UBYTE tag )
|
10 | //UBYTE wochentag_im_jahr(UWORD jahr, UWORD n) // Eingabe: Jahr, Tagesnummer // Ausgabe: WT (1=Mo,..., 6=Sa, 7=So)
|
11 | |
12 | i2c_write(wochentag_im_jahr(atoi(lefts(t_bld,4)),tagesnummer(atoi(lefts(t_bld,4)),atoi(mids(t_bld, 5, 2)),atoi(mids(t_bld, 7, 2))))); |
13 | i2c_write(int2bcd(atoi(mids(t_bld, 7, 2)))); // tag |
14 | i2c_write(int2bcd(atoi(mids(t_bld, 5, 2)))|(1<<CENTURY)); |
15 | i2c_write(int2bcd(atoi(mids(t_bld, 3, 2)))); |
16 | |
17 | i2c_stop(); |
18 | } // if(!_time_i2c_rtc) |
wird direkt geschrieben, mit ACK NACK hattte ich mich wohl verguckt Manuel _. schrieb: > Beim Lesen: > Nach dem Senden der Busadresse // ACK vom SLAVE > Nach dem Senden der Blockadresse // ACK vom SLAVE > Nach dem Senden der Busadresse inkl. Read-Befehl // ACK vom SLAVE > Nach dem Übermitteln der Daten // ACK vom Master > Nach dem übermitteln aller weiterer Daten //ACK vom Master > Nach dem Übermitteln des letzten Bytes // Not acknowlege vom Master waren wir schon einig nun sollte es ja klappen
:
Bearbeitet durch User
Hallo Joachim, Ich verstehe deinen Code und verwende ja grundsätzlich die gleiche Übertragungsfolge. Jedoch reagiert er nicht auf meine übertragenen Bytes. Auch beim lesen bekomme ich nur 0xFF d.h. SDA ist immer High.. -> DS1307 reagiert nicht auf meine Befehle. Wie geschrieben reagiert er nur direkt nach dem Übertragen der Busadresse - sonst auf nichts... echt komisch.. Es hat derzeit keinen Sinn wenn ich mich Stundenlang herumspiele und vielleicht doch der Chip fehlerhaft ist. Ich werde daher erstmal abwarten bis der andere Chip kommt. Wenn der nicht funktioniert habe ich wirklich irgendwas nicht verstanden und einen fehlerhaften code. Trotzdem vielen Dank für eure Mühen. Ich werde mich dann wieder melden wenn ich was weiß. lg Manuel
PS sendest du mit 100kHz oder 400kHz I2C? Ich hatte früher immer 100kHz gewählt, heute auch meist 400kHz was immer klappte bis zum I2C EEPROM schreiben, da muss ich temporär auf 100 kHz runterschalten.
> Ich arbeite glaub ich mit ca. 30-50kHz... habe aber auch schon auf > unter 10kHz verlangsamt, keine Änderung.. Vielleicht auch 100kHz, müsste ich daheim nachsehen. Man Muss halt immer die Timings der jeweiligen Chips einhalten.
Morgen, Nun sind die neuen DS3231 angekommen. ...angesteckt... und siehe da.... es geht !!! dürften wohl wirklich fehlerhafte/fake Chips gewesen sein! lg
Manuel _. schrieb: > dürften wohl wirklich fehlerhafte/fake Chips gewesen sein! Nö, typischer RTFM-Fehler. Manuel _. schrieb: > Der uC und der DS bekommen 3.3V. MÖÖÖP! Ein Blick ins Datenblatt erleichtert die Fehlersuche. Der DS1307 läuft nicht mit 3.3V, der will die guten alten 5V an Vcc haben.
Und das Modul hat die Pullups schon auf der Platine, daher sind keine internen Pullups notwendig.
mhh...ich habs zwar schon auf 5V probiert werds ich aber nochmal versuchen.. Ja manchmal übersieht man die logischsten Dinge... der Horst :)
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.