DS1307 - I2C Übertragung ACK

OP #5264605
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
#5264613
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?
#5264653
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();
OP #5265235
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
Gast #5265249
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
Gast #5265262
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
OP #5265264
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
Gast #5265283
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
OP #5265410
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...
#5265547
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
OP #5265583
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren