mikrocontroller.net

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


Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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: 
Ebay-Artikel Nr. 272950653008

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

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Manuel ___ (mani123)
Datum:
Angehängte Dateien:

Bewertung
1 lesenswert
nicht 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)

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder habe ich da was falsch verstanden?

Autor: Hmmm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keine Batterie angeschlossen? Das mag der DS1307 nicht.

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht 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
i2c_write(SECONDS);            // write address = SECONDS
      i2c_rep_start(DS3231+I2C_READ);       // set device address and read mode
      _rtc_t[2]=bcdtoint(i2c_readAck()&0x7f);  // sekunden
      _rtc_t[1]=bcdtoint(i2c_readAck()&0x7f); // minuten
      _rtc_t[0]=bcdtoint(i2c_readAck()&0x3f); // stunden
      _rtc_d[4]=i2c_readAck()&7;        // wt
      _rtc_d[0]=bcdtoint(i2c_readAck()&0x3f);  // tag
      _rtc_d[1]=i2c_readAck();        // monat mit CENTURY
      _rtc_d[2]=i2c_readNak();        // jahr
         i2c_stop();

man sieht NACK nur beim letzten Byte

bei write dito
i2c_write(SECONDS);            // write address = SECONDS
    i2c_rep_start(DS3231+I2C_READ);       // set device address and read mode
    _rtc_t[2]=i2c_readAck()&0x7f;      // Seconds
    _rtc_t[1]=i2c_readAck()&0x7f;      // Minutes
    _rtc_t[0]=i2c_readNak()&0x3f;      // Hours
    i2c_stop();

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und die Batterie ist eingelegt und hat 3.0 Volt.

Es funktioniert mit beiden Modulen nicht

Autor: TK (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: egberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: TK (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe noch mal geschaut

Manuel _. schrieb:
> Beim Schreiben:
i2c_write
//************************************************************************
//  Send one byte to I2C device
//  
//  Input:    byte to be transfered
//  Return:   0 write successful 
//            1 write failed
//************************************************************************
unsigned char i2c_write( unsigned char data )
{  uint8_t   twst;
  if(!_i2c_init)
    i2c_init();
   _i2c_busy=1;  
  // send data to the previously addressed device
  TWDR = data;
  TWCR = (1<<TWINT) | (1<<TWEN);

  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));

  // check value of TWI Status Register. Mask prescaler bits
  twst = TW_STATUS & 0xF8;
  if( twst != TW_MT_DATA_ACK) return 1;
  return 0;
} // i2c_write

write
if(!_time_i2c_rtc)
{  while(_i2c_busy);
   i2c_start_wait(DS3231+I2C_WRITE);     // set device address and write mode
   i2c_write(SECONDS);                   // write address = SECONDS
   i2c_write(int2bcd(atoi(rights(t_bld, 2))));
   i2c_write(int2bcd(atoi(mids(t_bld, 11, 2))));
   i2c_write(int2bcd(atoi(mids(t_bld, 9, 2))));
    
   //UWORD tagesnummer( UWORD jahr, UBYTE monat, UBYTE tag )
   //UBYTE wochentag_im_jahr(UWORD jahr, UWORD n) // Eingabe:  Jahr, Tagesnummer // Ausgabe:  WT (1=Mo,..., 6=Sa, 7=So)

   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)))));
   i2c_write(int2bcd(atoi(mids(t_bld, 7, 2)))); // tag
   i2c_write(int2bcd(atoi(mids(t_bld, 5, 2)))|(1<<CENTURY));
   i2c_write(int2bcd(atoi(mids(t_bld, 3, 2))));
  
   i2c_stop();
} // 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
Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Manuel ___ (mani123)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Morgen,

Nun sind die neuen DS3231 angekommen.

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

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

lg

Autor: Horst (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pete K. (pete77)
Datum:

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

Autor: Manuel ___ (mani123)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mhh...ich habs zwar schon auf 5V probiert werds ich aber nochmal 
versuchen..

Ja manchmal übersieht man die logischsten Dinge...

der Horst :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.