Atmega328p und DS1307

OP #7483768
Lesenswert?

Hallo, ich versuche nun schon seit 2 Wochen aus dem DS1307 vernünftige Werte zu bekommen. Im Anhang befindet sich einmal das gesamte Projekt(Den Code selbst hier rein zu schicken ergibt keinen Sinn, da er auf mehrere Dateien verteilt ist). Der Atmega328p läuft mit 8MHz über den internen Quarz (falls das für euch wichtig ist). An der Schaltung liegt es nicht, diese habe ich bereits mehrfach geprüft und habe sie auch von dritten prüfen lassen. Hängen tut der Code in der

1
i2c_start_wait()

(twimaster.c) wenn ich versuche die Werte auszulesen. Hängen genau tut der Code genau an dieser Stelle

1
while(TWCR & (1<<TWSTO));

an der gewartet werden soll bis die Stoppbedingung durch ist und der Bus wieder frei.

Angehängte Dateien:
#7483852
Lesenswert?

Hi, da scheinbar

1
RTC_Init();

und

1
RTC_SetDateTime(&rtc);

nach deine Aussage funktionieren kann es ja nicht an

1
while(TWCR & (1<<TWSTO));

liegen da diese Funktionen

1
i2c_start()

aufrufen und diese bis auf den Teil identisch zu

1
i2c_start_wait()

ist.

1
      twst = TW_STATUS & 0xF8;
2
      if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) 
3
      {          
4
          /* device busy, send stop condition to terminate write operation */
5
          TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
6
          
7
          // wait until stop condition is executed and bus released
8
          while(TWCR & (1<<TWSTO));
9
          
10
          continue;
11
      }
12
      //if( twst != TW_MT_SLA_ACK) return 1;
13
      break;

Sicher dass du Pullups an SCl und SDA angeschlossen hast?

Gast #7483861
Lesenswert?

Jonas N. schrieb:

vielleicht helfen einen Lösungsansatz zu finden

Messe die Spannung an SCA und SDL. Sie müssen vor der ersten Kommunikation schon auf HIGH sein. Und danach auch.

Überprüfe die beiden Leitungen mit einem Oszilloskop und zeige uns das Bild.

Am einfachsten geht das, indem zu die Kommunikation nur einmal nach einem Tastendruck versuchst und das Oszilloskop auf den Tastendruck oder auf die fallende Flanke an SDA triggerst.

Beitrag #7483864 wurde von einem Moderator gelöscht.
Gast #7483869
Lesenswert?

Du könntest folgenden Code versuchen:

1
TWBR = 32;  // 100 kHz bei 8 MHz CPU Takt
2

3
// Sende Start 
4
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
5
while (!(TWCR & (1<<TWINT)));
6
uint8_t status=TWSR & 0xf8;
7
if (status != 0x08 && status != 0x10) {
8
  // Hier bitte eine Fehlermeldung ausgeben
9
}
10
    
11
// Sende Adresse (write mode)
12
TWDR=slave_address << 1; // keine Ahnung, welche Adresse deine RTC hat
13
TWCR=(1<<TWINT) | (1<<TWEN);
14
while (!(TWCR & (1<<TWINT)));
15
if ((TWSR & 0xf8) != 0x18) {
16
  // Hier bitte eine Fehlermeldung ausgeben
17
}
18

19
// Sende STOP
20
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

Das sollte 9 Takte auf SCL erzeugen und ein Byte auf SDA übertragen. Das ist mit einem digitalen Oszilloskop recht übersichtlich darstellbar. Wenn die Slave Adresse richtig ist, sollte die RTC die Leitung SDA beim 9. Takt auf LOW ziehen.

#7484041
Lesenswert?

Wie stehen die Fuses? Wie ist der Compiler konfiguriert? (boards.txt) Wenn du bspw. auf externen Quarz gefused hast und da ist keiner, dann schwingt garnichts. Teilst du dem Compiler die falsche Frequenz mit, haut dein Timing nicht hin (8 statt 16 Mhz, oder umgekehrt) Das kann z.B. der Fall sein, wenn du das falsche Board in der IDE auswählst 3,3 statt 5V Variante und umgekehrt.

Beitrag #7484043 wurde von einem Moderator gelöscht.
#7484283
Lesenswert?

Hallo,

hab es mal kurz überflogen.

1
    rtc_t rtc; 
2
    uart_init();
3
    RTC_Init();
4
    rtc.hour = 0x10; //  10:40:20 am
5
    rtc.min =  0x40;                 <------ 
6
    rtc.sec =  0x00;

ist HEX 0x40 in DEC 64 ?? evtl. führt das zum Problem ?

Wo ist denn jetzt überhaupt noch das Problem ? Du konntest doch die Sekunden auslesen. Hast du ein 100nF (Abblockkondensator) hinzugefügt ?

Gruß

OP #7484292
Lesenswert?

Michael M. schrieb:

1
>     rtc_t rtc;
2
>     uart_init();
3
>     RTC_Init();
4
>     rtc.hour = 0x10; //  10:40:20 am
5
>     rtc.min =  0x40;                 <------
6
>     rtc.sec =  0x00;
7
> 
8
>

ist HEX 0x40 in DEC 64 ?? evtl. führt das zum Problem ?

Hab ich korrigiert, hat aber dennoch nichts geändert.

Wo ist denn jetzt überhaupt noch das Problem ? Du konntest doch die Sekunden auslesen.

Nein konnte ich nicht, hab immer noch das Problem überhaupt nichts lesen zu können.

Hast du ein 100nF (Abblockkondensator) hinzugefügt ?

Ja

#7484340
Lesenswert?

Jonas N. schrieb:

Der Atmega328p läuft mit 8MHz über den internen Quarz

hat intern kein Quarz!

Jonas N. schrieb:

Hier einmal die gesetzten Fuses und der Schaltplan.

warum schwindelst du? Quarz ist auch nicht eingezeichnet

Jonas N. schrieb:

Versuche es morgen auch mal ohne den Quarz.

wo wird denn F_CPU gesetzt? Welchen I2C Clock nutzt du? Ich durchsuche nun nicht den ganzen Code, irgendwo wird dein Fehler sein.

#7484347
Lesenswert?

Hallo,

nimm mal eine andere Lib für I²C oder DS1307 Modul. sieht schonmal komisch aus, wenn die Header und C Datei nicht den selben Namen haben (muss natürlich nichts heißen).

google einfach mal : "atmega328P IIC github" und probiere eine andere aus.

Wenn du ganz einfach machen willst lad dir die Arduino IDE wähl da den Atmega328P (UNO) aus und probiere ein Beispiel.

Hab auch keine Zeit komplett durch die Lib zu surfen.

Gruß

#7484349
Lesenswert?

Joachim B. schrieb:

Jonas N. schrieb:

Der Atmega328p läuft mit 8MHz über den internen Quarz

hat intern kein Quarz!

Jonas N. schrieb:

Hier einmal die gesetzten Fuses und der Schaltplan.

warum schwindelst du? Quarz ist auch nicht eingezeichnet

Jonas N. schrieb:

Versuche es morgen auch mal ohne den Quarz.

wo wird denn F_CPU gesetzt? Welchen I2C Clock nutzt du? Ich durchsuche nun nicht den ganzen Code, irgendwo wird dein Fehler sein.

Die Diskussion hatten wir gestern schon. Er benutzen den internen Oszillator am ATMega328P F_CPU wird auf 8000000 gesetzt.

Wir hatten den über den Quarz am DS1307 gesprochen, weil ich keinen 32,768 kHz da hatte hab ich mit nem 16Mhz versucht, was nicht von Erfolg gekrönt war. Deshalb hab ich seinen Code genommen und an nen Grove-DS1307 gehängt und es hat funktioniert, woraus ich schließe dass es ein Hardware-Problem ist.

#7484353
Lesenswert?

Jonas N. schrieb:

Das ist übrigens die Ausgabe auf den SCL und SDA Leitungen, wenn er an der While schleife, stehen geblieben ist.

Das wiederum kann garnicht sein, weil die While-Schleife

1
while(TWCR & (1<<TWSTO));

keinerlei weitere Ausgaben auf dem I²C enthält und demnach spätestens nach etwas Zeit Ruhe auf dem Bus herrschen muss. ISRs die pausenlos den I²C befeuern habe ich bei dir nicht gesehen.

Also: Entweder bleibt dein Programm an einer anderen Stelle hängen, und nicht in der Schleife die du vermutest, oder dein Oszi-Bild ist Fake, oder du hast noch geheime Zusatz-Hardware mit an dem Bus, von der du uns nichts verraten hast.

#7484372
Lesenswert?

Ok habs eben nochmal auf nem nackten 328p probiert. 1 zu 1 mit dem von dir geposteten Code(Bis auf meinen Versuch einen Zeilenumbruch hinzubekommen "uart_puti(0x0A);" was leider nicht funktioniert) und es funktioniert problemlos. Es muss daher an deiner Hardware liegen.

Wie schaust du dir die daten am seriellen Port an? Vielleicht gibt es da Probleme. Ich kenne mich mit dem Atmel Studio nicht aus. gibt es da nen Seriellen Monitor?

Angehängte Dateien:
#7484376
Lesenswert?

Wie schaust du dir die daten am seriellen Port an? Vielleicht gibt es da Probleme.

Diese Vermutung hatte ich auch bereits, bekam aber als Antwort:

Hast du dir den Code überhaupt angesehen? Wenn ja, dann wüsstest du, dass es nicht an der Ausgabe liegen kann.

#7484386
Lesenswert?

Jonas N. schrieb:

Leute, ich bekomme im Debugmode doch mit, dass er aus der einen Schleife nicht mehr herauskommt

Das kann nicht sein. Laut deinem Oszi-Screenshot hast du innerhalb der Schleife kontinuierlich Flankenwechsel auf SCL. Wenn du keine geheime Troll-Hardware mit angeschlossen hast, müssen die vom ATMega kommen. Der wiederrum wackelt garantiert nicht am SCL, wenn ihm das nicht aufgetragen wird. Während er im Debugger gestoppt ist erst recht nicht.

Hast du evtl. den Strichpunkt nach

1
while(TWCR & (1<<TWSTO))

vergessen?

#7484389
Lesenswert?

Leute ...

Eine Frage von Wahrscheinlichkeit und Aufwand - zu Programmbeginn ein 'hallo' einbauen, den Debugmode abschalten und das Ganze laufen lassen: kostet Sie vielleicht ein oder zwei Minuten. Was ist das schon verglichen mit diesem Thread mit inzwischen 43 Beiträgen.

Zumindest verfahre ich so, wenn ich nicht mehr weiterweiss.

Gast #7484454
Lesenswert?

Jonas N. schrieb:

Das ist übrigens die Ausgabe auf den SCL und SDA Leitungen, wenn er an der While schleife, stehen geblieben ist.

Auch hier sieht man beim jeweils 9. Takt, dass deine RTC die Slave Adresse nicht bestätigt.

Ich finde aber seltsam das dein Bild mindesten eine Wiederholung der Adresse zeigt, obwohl das Programm nach deiner Aussage beim Fehler hängen bleibt. Hast du noch einen Watchdog aktiviert, der dabei einen Reset auslöst?

Gast #7484530
Lesenswert?

Ich habe mal die 9 Bits eingezeichnet.

Die 7 Bit Slave Adresse ist 1101000 (= 0x68, oder 104), was mit dem Datenblatt des DS1307 überein stimmt.

Danach kommt das R/W Bit mit dem Wert 0, womit der Master mitteilt, dass er in der folgenden Kommunikation schreibend auf den Slave zugreifen will.

Danach sollte eigentlich das ACK kommen. Der Slave müsste beim 9. Taktimpuls die SDA Leitung auf Low ziehen um zu signalisieren "hier bin ich, bereit zur Kommunikation". Genau das fehlt in deinem Fall, der Slave hat nicht bestätigt.

Vergleiche mit https://de.wikipedia.org/wiki/I%C2%B2C#Takt_und_Zust%C3%A4nde_des_Busses

Ich tippe immer noch darauf, dass der Chip nicht funktioniert, weil der Abblock-Kondensator an der Stromversorgung fehlt. Vielleicht auch, weil der Quarz fehlt. Auf dem Steckbrett funktioniert der Oszillator außerdem wahrscheinlich nicht, weil die Kontakte von dem Brett zu viel Kapazität haben. Das wird wohl nur auf einer gelöteten Platine funktionieren können.

Andere Bild: Jonas N. schrieb im Beitrag #7484198:

Sieht das so in Ordnung aus?

Dieser Screenshot sieht doch nicht gut aus. Hier ist die 7 Bit Adresse 1010000, was nicht mit dem Datenblatt überein stimmt.

Angehängte Dateien:
Beitrag #7484535 wurde von einem Moderator gelöscht.
OP #7484825
Lesenswert?

Stefan F. schrieb:

Auf dem Steckbrett funktioniert der Oszillator außerdem wahrscheinlich nicht, weil die Kontakte von dem Brett zu viel Kapazität haben. Das wird wohl nur auf einer gelöteten Platine funktionieren können.

Habe mal den Quarz direkt an den Chip gelötet und erhalte nun endlich eine Ausgabe. Die Werte, die ich derzeit bekomme, sind nur etwas komisch. Die Zeitwerte gehen über 60 hinaus und springen auch sehr stark.

Angehängte Dateien:
Gast #7484869
Lesenswert?

Hast du den Abblock-Kondensator hinzugefügt und dafür gesorgt, dass die Pins X1 und X2 nicht im Steckbrett stecken?

Hänge nochmal das Oszilloskop an den I²C Bus, so dass man die Kommunikation sehen kann (zumindest die ersten 9 Takte).

OP #7484906
Lesenswert?

Kondensator ist hinzugefügt und die Pins X1 und X2 stecken zwar im Steckbrett, aber auf die ist der Quarz aufgelötet, sollte also passen.

Den Fehler bei den Sekunden konnte ich beheben, das war nur ein Fehler in der Ausgabe, aber bei den Minuten gibt es noch Probleme: Wenn ich die Minuten auf 59 stelle, springen sie nicht wieder auf 0, sondern auf 68.

Angehängte Dateien:
Gast #7485104
Lesenswert?

Jonas N. schrieb:

Kondensator ist hinzugefügt und die Pins X1 und X2 stecken zwar im Steckbrett, aber auf die ist der Quarz aufgelötet, sollte also passen.

Nein, sollte nicht passen. Denn die Kontakte des Steckbretts haben typischerweise mehr als 10pF Kapazität, die den Oszillator belasten. Dafür ist er nicht vorgesehen.

Wenn er trotzdem für einen kurzes Experiment halbwegs läuft, hast du Glück. Den finalen Aufbau wirst du eh nicht auf Steckbrett machen, nehme ich mal an.

#7485154
Lesenswert?

Z.B. Max schrieb:

Was ist denn das bitte für eine Ausdrucksweise? Nicht jeder wird Allwissend geboren und wir haben alle verstanden was er mit internen Quarz gemeint hat. Deswegen ist man noch lange kein Vollidiot...

Hat ja auch niemand behauptet. Die Schwerpunkt lag ganz eindeutig auf "Troll". Ich habe nur auch die einzige rationale Alternative aufgezeigt...

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