Forum: Mikrocontroller und Digitale Elektronik DS1307 - I2C Übertragung ACK


von Manuel _. (mani123)


Lesenswert?

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

von Joachim B. (jar)


Lesenswert?

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?

von Manuel _. (mani123)


Angehängte Dateien:

Lesenswert?

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)

von Manuel _. (mani123)


Lesenswert?

Oder habe ich da was falsch verstanden?

von Hmmm (Gast)


Lesenswert?

Keine Batterie angeschlossen? Das mag der DS1307 nicht.

von Joachim B. (jar)


Lesenswert?

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();

von Manuel _. (mani123)


Lesenswert?

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

von Manuel _. (mani123)


Lesenswert?

Und die Batterie ist eingelegt und hat 3.0 Volt.

Es funktioniert mit beiden Modulen nicht

von TK (Gast)


Lesenswert?

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

von egberto (Gast)


Lesenswert?

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

von Manuel _. (mani123)


Lesenswert?

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

von Manuel _. (mani123)


Lesenswert?

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.

von TK (Gast)


Lesenswert?

>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

von Manuel _. (mani123)


Lesenswert?

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...

von Joachim B. (jar)


Lesenswert?

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
von Manuel _. (mani123)


Lesenswert?

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

von Joachim B. (jar)


Lesenswert?

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.

von Manuel _. (mani123)


Lesenswert?

> 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.

von Manuel _. (mani123)


Angehängte Dateien:

Lesenswert?

Morgen,

Nun sind die neuen DS3231 angekommen.

...angesteckt... und siehe da.... es geht !!!

dürften wohl wirklich fehlerhafte/fake Chips gewesen sein!

lg

von Horst (Gast)


Lesenswert?

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.

von Pete K. (pete77)


Lesenswert?

Und das Modul hat die Pullups schon auf der Platine, daher sind keine 
internen Pullups notwendig.

von Manuel _. (mani123)


Lesenswert?

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
Noch kein Account? Hier anmelden.