Forum: Mikrocontroller und Digitale Elektronik PCF8563 Sekunden lassen sich nicht einstellen


von Zeitlos (Gast)


Lesenswert?

Hallo,

ich versuche gerade die Zeit eines PCF8563 einzustellen. Danach möchte 
ich in einer While(1)-Schleife die Zeit auf ein Display ausgeben.

So siehts momentan aus:
1
i2c_init();
2
i2c_write(0x02);
3
i2c_write(0x87);
4
i2c_rep_start(0xA2);
5
i2c_write(0x03);
6
i2c_write(0x00);
7
i2c_rep_start(0xA2);
8
i2c_write(0x04);
9
i2c_write(0x00);
10
i2c_rep_start(0xA2);
11
i2c_write(0x0D);
12
i2c_write(0x83);
13
i2c_stop();
14
15
while(1)
16
{...}

Allerdings funktioniert es nicht. Auf dem Display erscheint nichts.Ganz 
aufgehängt hat er sich aber auch nicht. Der Clock_out-Pin funktioniert 
noch.

Auch interessant, lass ich die folgenden drei Zeilen weg, funktionierts:
1
i2c_write(0x02);
2
i2c_write(0x87);
3
i2c_rep_start(0xA2);

Hab ich was übersehen?

Gruß,
Jürgen

von HolgerT (Gast)


Lesenswert?

Du schreibst von zwei Problemen:
 * ..versuche gerade die Zeit eines PCF8563 einzustellen...
 * ..Auf dem Display erscheint nichts..


>Der Clock_out-Pin funktioniert noch.
Gewöhnlich erhält man dort (nach dem Reset) einen Sekundenimpuls im 
Tastverhältnis 1:1. Die Uhr sollte vom 1.1. 00:00 loslaufen.

1. Du solltest zuerst versuchen, Deine Anzeige in Ordung zu bringen.
2. Dann den RTC auslesen und anzeigen.
3. Erst danach, kannst Du versuchen, die Uhrzeit zu stellen.

-Holger

P.S. Deine Codeschnipsel habe ich nicht angesehen, daDatenblatt nicht 
zur Hand

von Zeitlos (Gast)


Lesenswert?

Danke für deine schnelle Antwort.

Da hab ich mich woll falsch ausgedrückt.

HolgerT schrieb:
> 1. Du solltest zuerst versuchen, Deine Anzeige in Ordung zu bringen.
> 2. Dann den RTC auslesen und anzeigen.

Das funktioniert schon. Allerdings nur wenn ich die drei Zeilen 
auskommentiere:
1
i2c_write(0x02);
2
i2c_write(0x87);
3
i2c_rep_start(0xA2);

von m.n. (Gast)


Lesenswert?

Als Beispiel, wie es funktioniert:

static unsigned char dez_bin(unsigned char d)
{
  return((d/16)*10 + d%16);
}

CLOCK *set_clock(CLOCK *cl)
{
  iic_adr_write(UHR_ADRESSE);      /* uhr adressieren */
  iic_write(2);                    /* sekundenstelle anwaehlen */
  iic_write(bin_dez(cl->second));  /* sekunde */
  iic_write(bin_dez(cl->minute));  /* minute */
  iic_write(bin_dez(cl->hour));    /* stunde */
  iic_write(bin_dez(cl->day)+cl->year*64);       /* tag und jahr%4 */
  iic_write(bin_dez(cl->month)+cl->weekday*32);  /* monat + Wochentag */
  iic_write(0);                    /* ins timer-register */
  iic_write(cl->year);             /* wie vorhanden */
  iic_stop();
  return(cl);
}

von HolgerT (Gast)


Lesenswert?

>Das funktioniert schon. Allerdings nur wenn ich die drei Zeilen
>auskommentiere:

..dann laß sie halt weg!

Nee, im Ernst: Beschreibe, was Du mit diesen (und den anderen) Zeilen 
bezweckst (wie geschrieben, hier fehlt das Datenblatt!)

An welcher I2C-Adresse "hängt" der PCF8563?

von Zeitlos (Gast)


Lesenswert?

Also gut noch einmall mit Kommentaren:
1
#include "i2cmaster.h"
2
...
3
4
i2c_init(); //Bus initsallisiern
5
i2c_start_wait(0xA2+I2C_WRITE);     // set device address and write mode
6
i2c_write(0x02);   //Register Sekunde ansprechen
7
i2c_write(0x83);  //Sekunde z.B. 3 stellen
8
i2c_rep_start(0xA2);
9
i2c_write(0x03);  //Register Minute ansprechen  
10
i2c_write(0x00);  //Minute auf Null stellen
11
i2c_rep_start(0xA2);
12
i2c_write(0x04);  //Register Stunde ansprechen
13
i2c_write(0x87);  //Stunde auf z.b. 7 setzten
14
i2c_stop();

Zugrunde liegt die I2C-Routine von Peter Fleury.
Muss ich irgendwas bei den Sekunden beachten wenn ich das Register 
beschreibe ?

von m.n. (Gast)


Lesenswert?

HolgerT schrieb:
> An welcher I2C-Adresse "hängt" der PCF8563?

Das ist 0xA2.
Wie ich gerade sehe, ist meine obige Routine für den PCF8583, aber die 
Einstellung der Uhrzeit ist identisch.

Zeitlos schrieb:
> i2c_write(0x83);  //Sekunde z.B. 3 stellen
> i2c_rep_start(0xA2);

Warum schreibst Du nicht einfach 0x03?
VL ist ein Status-Bit zum Lesen!
Und warum gibst Du immer einen neuen START aus und eine neue 
(sequentielle) Adresse?
Das ist alles doch recht umständlich.

von (prx) A. K. (prx)


Lesenswert?

"As a consequence of this method, it is very important to make a read or 
write access in one go,"

Also nicht jedes Byte einzen, wie bei dir.

von (prx) A. K. (prx)


Lesenswert?

m.n. schrieb:
> Einstellung der Uhrzeit ist identisch.

In etwa ähnlich, aber nicht identisch. Der PCF8583 hat nur 2 Bits für 
das Jahr, der PCF8563 volle 8. Zudem sollte man beim PCF8583 die RTC für 
einen Update erst stoppen und danach wieder starten, beim PCF8563 
erfolgt das implizit als Teil des Schreibvorgangs - weshalb der wie 
erwähnt am Stück erfolgen sollte.

von (prx) A. K. (prx)


Lesenswert?

Zu beachten, wenn der Code unter Kontrolle eines Debuggers läuft, oder 
anderweitig durch Debugging stark verlangsamt wird:

"Should the interface be active for more than 1 s from the time a valid 
slave address is transmitted, then the PCF8563 will automatically clear 
the interface and allow the time counting circuits to continue counting"

von Zeitlos (Gast)


Angehängte Dateien:

Lesenswert?

Also ich dreh jetzt gleich durch!
Ich habe euch mein gesammtes Program angehängt und erkläre euch meinen 
Vorgang gerne noch einmal.

->Ich spiele das Program so wie es ist auf den µC. Anzeige:
"Hallo Welt"

->Maskiere folgende Zeilen aus:
1
//i2c_write(0x02);   //Register Sekunde ansprechen
2
//i2c_write(0x03);  //Sekunde z.B. 3 stellen
3
//i2c_rep_start(0xA2);
Anzeige: "Hallo Welt"
Bemerkung: Uhr fehlt und zweites "Hallo Welt" auch.

->Trenne die Stromversorgung und stecke sie wieder ein
Anzeige:
"Hallo Welt
770
Hallo Welt"

Die Null zählt hoch. Uhr leuft also.

Weiterer Versuch:
1
i2c_start_wait(0xA2+I2C_WRITE);     // set device address and write mode
2
i2c_write(0x02);   //Register Sekunde ansprechen
3
i2c_write(0x03);  //Sekunde z.B. 3 stellen
4
//i2c_rep_start(0xA2);
5
i2c_write(0x03);  //Register Minute ansprechen  
6
i2c_write(0x87);  //Minute auf 7 stellen
7
//i2c_rep_start(0xA2);
8
i2c_write(0x84);  //Register Stunde ansprechen
9
i2c_write(0x87);  //Stunde auf z.b. 7 setzten
10
i2c_stop();
Anzeige: "Hallo Welt"

Ändere ich das Program wieder um wie zuvor, muss ich den µC von der 
Spannungsversorgung trennen das es wieder Uhr und zweites Hallo Welt 
anzeigt.

So, der Versuch alles auf einmal zu machen ist also auch gescheitert.
Was mach ich falsch???

Ich weis, mein Program ist sehr kaotisch, aber es ist eines meiner 
ersten und Übung macht den Meister. Es geht bestimmt auch einfacher.

von Zeitlos (Gast)


Lesenswert?

Entschuldigung, da hat sich eine 8 reingemischt. Ich hatte das ganze 
Spiel mit der richtigen Adresse 0x04 versucht.

Zeitlos schrieb:
> i2c_write(0x84);  //Register Stunde ansprechen

von (prx) A. K. (prx)


Lesenswert?

Schon mal die Hardware kontrolliert, also ob die RTC auch ganz offiziell 
ihren Strom kriegt? Schaltung?

von Zeitlos (Gast)


Lesenswert?

A. K. schrieb:
> Schon mal die Hardware kontrolliert, also ob die RTC auch ganz offiziell
> ihren Strom kriegt? Schaltung?

Hi,

hab gerade denn Bus vom Chip abgetrennt und zwischen Pin 4 u. 8 5,03Volt 
gemessen.

Also auch das ist i.o.

Kann es sein das der Chip en Schuss hat? Ich kann ihn leider nicht 
tauschen, da ich keinen zweiten hab.

von Zeitlos (Gast)


Lesenswert?

Nächster Versuch.

Basierend auf Beispiel von m.n.:
1
i2c_start_wait(0xA2+I2C_WRITE);     // set device address and write mode
2
i2c_write(0x02);   //Register Sekunde ansprechen
3
i2c_write(0x83);  //Sekunde z.B. 3 stellen
4
//i2c_rep_start(0xA2);
5
//i2c_write(0x03);  //Register Minute ansprechen  
6
i2c_write(0x87);  //Minute auf 7 stellen
7
//i2c_rep_start(0xA2);
8
//i2c_write(0x04);  //Register Stunde ansprechen
9
i2c_write(0x87);  //Stunde auf z.b. 7 setzten
10
//i2c_write(0x00);
11
i2c_stop();

Ausgabe:
"Hallo Welt"

In einem geht auch nicht.

von Sascha W. (sascha-w)


Lesenswert?

@Zeilos,

Hallo,

ich kann in deinem Code nichts zur Konfig. der I2C-Geschwindigkeit 
sehen! Passt die zum PCF?
1
sekunde_temp = i2c_read(0x02);    //lese Sekunde in angelegte unsigned char
ich kenne zwar die Lib nicht, aber was soll der Wert in der Klammer? Das 
kann nicht die Adresse sein, denn die kannst du zu dem Zeitpunkt gar 
nicht mehr angeben!

Sascha

von Zeitlos (Gast)


Lesenswert?

Sascha Weber schrieb:
> sekunde_temp = i2c_read(0x02);    //lese Sekunde in angelegte unsigned char

Das ist die Adresse. Weil, kommentiere ich die drei Zeilen aus, gibt er 
mir ja die Uhrzeit aus und die Sekunden werden hochgezählt.

Hinweis: Im Zitat werden die Sekunden gelesen. Das Problem liegt aber im 
schreiben. Siehe Code.
1
i2c_write(0x02);   //Register Sekunde ansprechen
2
i2c_write(0x03);  //Sekunde z.B. 3 stellen
3
i2c_rep_start(0xA2);

von Sascha W. (sascha-w)


Lesenswert?

also das schreiben muss so funktionieren !
1
i2c_start_wait(0xA2+I2C_WRITE);     // set device address and write mode
2
i2c_write(0x02);   //Register Sekunde ansprechen
3
i2c_write(0x83);  //Sekunde z.B. 3 stellen
4
i2c_write(0x07);  //Minute auf 7 stellen
5
i2c_write(0x07);  //Stunde auf z.b. 7 setzten
6
i2c_stop();

wenn das Programm hier hängen bleibt, dann lass dir mal die 
Rückgabewerte der einzelnen Funktionen ausgeben um zu sehen wo es nicht 
mehr weiter geht.

die repeat_Start_Funktion brauchst du grundsätzlich NUR wenn du lesen 
willst, und dann auch nur 1x nach dem senden der Registeradresse.

Um die I2C-Taktrate einzustellen verwendet die Lib  >F_CPU<, hast du die 
bei Dir entsprechend definiert? An sonsten verwendet die Lib 4MHz.

Ach und zu i2c_read(), schau dir mal die Doku an - was du da übergibst, 
muss einfach nur >0 sein, um zu sagen, das du noch weitere Bytes lesen 
willst.

Sascha

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.