Probleme mit RealTimeClock PCF8583P

nabend,

wollte mich mal endlich wieder an dem RTC IC Philips PCF8583P datasheet pdf wagen. habe es bis jetzt auch hinbekommen die Zeit zu stellen allerdings zählt er nicht wie gewünscht im sekundentakt. habe bis jetzt auch nur den bsp code benutzt.

#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h>

void setup()
{
  Serial.begin(9600);

  RTC.stop();
  RTC.set(DS1307_SEC,1);        //set the seconds
  RTC.set(DS1307_MIN,23);     //set the minutes
  RTC.set(DS1307_HR,12);       //set the hours
  RTC.set(DS1307_DOW,4);       //set the day of the week
  RTC.set(DS1307_DATE,5);       //set the date
  RTC.set(DS1307_MTH,3);        //set the month
  RTC.set(DS1307_YR,9);         //set the year
  RTC.start();

}

void loop()
{

  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year 
  Serial.println();

  delay(1000);

}

das bekomm ich dann in der konsole angezeigt:

12:23:0      5/3/2009
13:26:0      5/3/2009
14:28:0      5/3/2009
15:31:0      5/3/2009
16:33:0      5/3/2009
17:35:0      5/3/2009
18:38:0      5/3/2009
19:40:0      5/3/2009
20:42:0      5/3/2009
21:45:0      5/3/2009
22:48:0      5/3/2009
23:50:1      5/3/2009
24:52:1      5/3/2009
25:55:1      5/3/2009
26:57:1      5/3/2009
27:59:1      5/3/2009

denke mal das es der quarz (http://www.reichelt.de/index.html?;ACTION=7;LA=28;OPEN=0;INDEX=0;FILENAME=B400%252FMS1V-7.pdf;SID=13TXUuSn8AAAIAACF02TUa5cf7ecf1bf887e01c4022a8428f5c48)ist der nicht richtig schwingt. hab auch schon versucht ein 1nF kondensator zwischen OSCI und +5V zu stecken, dann zählt er gar net mehr, ohne halt viel zu schnell. es soll ja auch ein 1Hz signal auf pin 7 kommen was ich auch nicht bekomm. was kann ich da tun?

Hallo Akrlfix
Der Kondensator auf dem Schaltbild im Datenblatt ist für den Genauigkeitsabgleich. 32.768 Quarze gibt es mit 2 Kapazitäten (Load Capacitance): 6 und 12,5pF. Wenn Du den falschen nimmst geht die RTC bißchen falsch 20 Sekunden am Tag für DS130x RTC's. Der PCF8583P will eine Quarzkapazität von 10pF. ups. Und eine Trimmerkapaziät con 5p bis 25pF.
1nF war definitiv zu groß. Versuchs mit einem kleineren Kondensator.

Hatte auch mal das Problem daß ein 32kHz Quarz mit 1MHz schwang. Habs gelöst indem ich einen kleinen Kondensator com Quarz auf Masse schaltete. Die Anwendung mußte nicht so genau sein.

Du verwendest ein Breadbord? Ist nicht optimal für diese Anwendung.

Grüße Uwe

nabend uwe,

ja, is momentan aufm steckbrett, hab aber auch ein Protoshield auf dem ich den RTC-IC setzen kann. dort ist auch ein quarz mit 10pF (oder 12,5pF, weiss ich net mehr genau. auf steckbrett hab ich grad ein mit 6pF), aber mit gleichem verhalten.

1nF is momentan das kleinste was ich da hab und mit trimmerkondensatoren siehts auch sehr schlecht aus ( :~ vor ein paar std erst ne bestellung aufgegeben)

kleiner kondensator -> 10pF ? oder wie groß sollte der sein; der zwischen masse und quarz

Versuchs mal mit einem 10pF auf 5V
Grüße Uwe

Nabend,

hab jetzt mit trimm kondensatoren und feste 10pF gekauft und so wie im schaltplan oben verbunden. allerdings habe ich immer noch das gleiche verhalten. hab ma versucht die frequenz mitn dreisatz auszurechnen, hab da was mit 1,24 GHz rausbekommen :astonished:

werd denke ich mal n display anschließen mit 9 V batterie und dann ma schaun obs besser wird, oder wie würdet ihr weitermachen?

greetz akrlfix

Mit Batterie und Display immer noch gleiches verhalten, sprich er zählt in einer Sekunde ca. eine Stunde und 3 Minuten, weiss echt nicht weiter

Ich bekomme ca 124 MHz heraus ( (1 Stunde *60 +3 Minuten )*60 sind 3780 Sekunden mal die Quarzfrequenz (32768) = 124Mhz )
Mach mal ein paar Fotos des Aufbaus. Vieleicht sehe ich da was.
Grüße Uwe

jep, hast recht. bin da wohl mit dem komma etwas verrutscht. :roll_eyes:

hab auch mal ein paar fotos gemacht. ist meine erste selber gelötete platine :slight_smile:

der dünner kupfer draht ist Kupferlackdraht (echt ätzend den zu löten) , zusätzlich zum pcf8583 ist auch noch ein temperatursensor (LM75, auch mit I²C) drauf

Grüße akrlfix

Hi,

vielleicht hilf dir das hier weiter mal zur Info. Amateurfunkbasteln :: Foxcontrol, die Steuerung für Fuchsjagdsender

nabend,

danke bic-maec für den schaltplan und link.

glaube aber so langsam dass es nicht der quarz ist. habe mal mit einem Oszilloskop http://www.watterott.com/de/Digitales-Speicher-Oszilloskop-DSO-Bausatz-improved nachgemessen an OSCO und in 400us schwingt er 13 mal, 13/0,0004s = ca. 32500Hz, bei ca 5V mit einer amplitude von ca 0,2-0,3V .
hab mir das datenblatt nochmal genau angeschaut und dort gibt es auch die optionen für 50Hz modus, aber dass passt ja auch nicht.

Hab mir auch nochmal die DS1307 library angeschaut, werd daraus aber irgendwie net schlau. Die Adresse für den PCF8583 musste ich da ja auch schon ändern.

DS1307.h und DS1307.cpp:

/*
  DS1307.h - library for DS1307 rtc
*/

// ensure this library description is only included once
#ifndef DS1307_h
#define DS1307_h

// include types & constants of Wiring core API
#include <WConstants.h>

// include types & constants of Wire ic2 lib
#include <../Wire/Wire.h>

#define DS1307_SEC 0
#define DS1307_MIN 1
#define DS1307_HR 2
#define DS1307_DOW 3                               <------------ glaube das sind die RAM-Adressen, wenn ja, sind die alle falsch,
#define DS1307_DATE 4                                       im Datenblatt steht das in "02" die Sekunden sind und nicht die Stunden
#define DS1307_MTH 5                                                           das würde auch das extrem schnelle zählen erklären
#define DS1307_YR 6

#define DS1307_BASE_YR 2000

#define DS1307_CTRL_ID B1010000  //PCF8583    <-----Hier hab ich die Adresse geändert

 // Define register bit masks
#define DS1307_CLOCKHALT B10000000

#define DS1307_LO_BCD  B00001111           
#define DS1307_HI_BCD  B11110000           

#define DS1307_HI_SEC  B01110000           
#define DS1307_HI_MIN  B01110000           
#define DS1307_HI_HR   B00110000            <  wofür diese ganzen bytes sind habe ich noch nicht ganz herausgefunden
#define DS1307_LO_DOW  B00000111
#define DS1307_HI_DATE B00110000
#define DS1307_HI_MTH  B00110000
#define DS1307_HI_YR   B11110000

// library interface description
class DS1307
{
  // user-accessible "public" interface
  public:
    DS1307();
    void get(int *, boolean);
    int get(int, boolean);
	void set(int, int);
    void start(void);
    void stop(void);

  // library-accessible "private" interface
  private:
    byte rtc_bcd[7]; // used prior to read/set ds1307 registers;
	void read(void);
	void save(void);
};

extern DS1307 RTC;

#endif
=========================================================================================================
=========================================================================================================


DS1307.cpp
==========
extern "C" {
#include <../Wire/Wire.h>
}
#include "DS1307.h"

DS1307::DS1307()
{
  Wire.begin();
}

DS1307 RTC=DS1307();

// PRIVATE FUNCTIONS

// Aquire data from the RTC chip in BCD format
// refresh the buffer
void DS1307::read(void)
{
  // use the Wire lib to connect to tho rtc
  // reset the resgiter pointer to zero
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.send(0x00);
  Wire.endTransmission();

  // request the 7 bytes of data    (secs, min, hr, dow, date. mth, yr)
  Wire.requestFrom(DS1307_CTRL_ID, 7);
  for(int i=0; i<7; i++)
  {
    // store data in raw bcd format
    rtc_bcd[i]=Wire.receive();
  }
}

// update the data on the IC from the bcd formatted data in the buffer
void DS1307::save(void)
{
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.send(0x00); // reset register pointer
  for(int i=0; i<7; i++)
  {
    Wire.send(rtc_bcd[i]);
  }
  Wire.endTransmission();
}


// PUBLIC FUNCTIONS
void DS1307::get(int *rtc, boolean refresh)   // Aquire data from buffer and convert to int, refresh buffer if required
{
  if(refresh) read();
  for(int i=0;i<7;i++)  // cycle through each component, create array of data
  {
    rtc[i]=get(i, 0);
  }
}

int DS1307::get(int c, boolean refresh)  // aquire individual RTC item from buffer, return as int, refresh buffer if required
{
  if(refresh) read();
  int v=-1;
  switch(c)
  {
  case DS1307_SEC:
    v=(10*((rtc_bcd[DS1307_SEC] & DS1307_HI_SEC)>>4))+(rtc_bcd[DS1307_SEC] & DS1307_LO_BCD);
    break;
  case DS1307_MIN:
    v=(10*((rtc_bcd[DS1307_MIN] & DS1307_HI_MIN)>>4))+(rtc_bcd[DS1307_MIN] & DS1307_LO_BCD);
    break;
  case DS1307_HR:
    v=(10*((rtc_bcd[DS1307_HR] & DS1307_HI_HR)>>4))+(rtc_bcd[DS1307_HR] & DS1307_LO_BCD);
    break;
  case DS1307_DOW:
    v=rtc_bcd[DS1307_DOW] & DS1307_LO_DOW;
    break;
  case DS1307_DATE:

    
       v=rtc_bcd[DS1307_DATE]/16 * 10 +  rtc_bcd[DS1307_DATE] % 16;
    
    break;
  case DS1307_MTH:
    v=(10*((rtc_bcd[DS1307_MTH] & DS1307_HI_MTH)>>4))+(rtc_bcd[DS1307_MTH] & DS1307_LO_BCD);
    break;
  case DS1307_YR:

    
      v=2000 + rtc_bcd[DS1307_YR]/16 * 10 + rtc_bcd[DS1307_YR] % 16;
    
    break; 

  } // end switch
  return v;
}

void DS1307::set(int c, int v)  // Update buffer, then update the chip
{
  switch(c)
  {
  case DS1307_SEC:
    if(v<60 && v>-1)
    {
      //preserve existing clock state (running/stopped)
      int state=rtc_bcd[DS1307_SEC] & DS1307_CLOCKHALT;
      rtc_bcd[DS1307_SEC]=state | ((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_MIN:
    if(v<60 && v>-1)
    {
      rtc_bcd[DS1307_MIN]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_HR:
    // TODO : AM/PM  12HR/24HR
    if(v<24 && v>-1)
    {
      rtc_bcd[DS1307_HR]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_DOW:
    if(v<8 && v>-1)
    {
      rtc_bcd[DS1307_DOW]=v;
    }
    break;
  case DS1307_DATE:
    if(v<32 && v>-1)
    {
      rtc_bcd[DS1307_DATE]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_MTH:
    if(v<13 && v>-1)
    {
      rtc_bcd[DS1307_MTH]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_YR:
    if(v<50 && v>-1)
    {
      rtc_bcd[DS1307_YR]=((v / 10)<<4) + (v % 10);
    }
    break;
  } // end switch
  save();
}

void DS1307::stop(void)
{
  // set the ClockHalt bit high to stop the rtc
  // this bit is part of the seconds byte
  rtc_bcd[DS1307_SEC]=rtc_bcd[DS1307_SEC] | DS1307_CLOCKHALT;
  save();
}

void DS1307::start(void)
{
  // unset the ClockHalt bit to start the rtc
  // TODO : preserve existing seconds
  rtc_bcd[DS1307_SEC]=0;
  save();
}

heut abend leider keine zeit mehr, werd mir das aber die tage nochmal genauer anschaun.

grüße akrlfix

Hi,

Es gibt aber auch schon eine passende Librarie für den PCF8583P Project mit Arduino.

Der Link zu den benutzten Libraries Linkmit PCF8583 librarie

Das DSO hat auch eine Frequenzmessung.
Wenn Du mit dem DSO mißt, ist dann die Geschwindigkeit des RTC richtig oder zählt er die Sekunden immernoch zu schnell?
Grüße Uwe

Nabend,

hab nochmal ein bischen nachgemessen und hab ein sehr merkwürdiges Verhalten festgestellt. Wenn ich OSCO-GND messe dann bekomm ich ca. 32,5kHz raus (Graph 1), wird bei der Frequenzmessung aber leider nicht angezeigt, wohl zu unempfindlich. Wenn ich nun aber OSCO-OSCI messe bekomm ich 50Hz, wird so auch in der Frequenzmessung angezeigt (Graph 2) und zusätzlich ändert sich auch die zählgeschwindigkeit, so ca 10min in einer Sekunde.

Graph 1:

Graph 2:

Habs aber schluss endlich hinbekommen. Es lag an der DS1307-Library, die nicht für den PCF8538P gemacht ist. Hab mich mal wieder zu sehr auf Webmeisters Buch verlassen ;), da kommt es so rüber als könnt man den auch mit der DS-lib. ansteuern. Mit der PCF-Lib. funktioniert es einwandfrei.

danke nochmal für die hilfe von euch beiden

grüße akrlfix

Die Kapazität und Eingangswiderstand des DSO stört den Oszillator. Darum die komischen Meßwerte.
Nicht umsonst habe ich in der Schule 2 Jahre lang Meßtechnik gepaukt; Jede Meßung beeinflußt die Meßgröße und nicht jedes Meßgerät ist für jede Meßung geeignet.

Schön, daß Du Dein Problem gelöst hast.
grüße Uwe