Hallo! wer hat schon mal erfolgreich den Uhrenchip PCF8583 vollständig programmiert in BASCOM ? d.h. auch mit Datum? Welcher Tag ist der "Tag 0"? Sonntag oder Montag? Wie wird das Schaltjahr gesetzt? Bei mir kommt nach dem 28.02. immer der 29.02 und 30.02! Irgendwo hab ich sicherlich irgendwo etwas übersehen! Hat evtl jemand ein Programmlisting greifbar? Bislang habe ich nur Beispiele gefunden nur mit Uhrzeit also ohne Datum. Wäre für jeden Tipp dankbar! Dank im voraus! Roland.
Hallo Roland, ich habe vor längerer Zeit 'mal mit dem PCF8583 rumgespielt. Leider kann ich Dir nicht sagen wie sich die RTC im Februar verhält. Nachfolgend mein Programmcode. ' ************************************************************************ ****** ' Hardwarebeschreibung ' Hardware STK500 ' LCD HD44870-kompatibel ' LCD D7..D4 = P1.7..1.4, P1.3=RS, P3.4 = Enable (Einstellung Optionen/LCD) ' I2C-Bus RTC Phillips PCF8583P ' I2C-Bus EEPROM 24C64 ( ' I2C-Bus: SDA = PortC.6, SCL = PortC.7 ' ************************************************************************ ****** ' Konfiguration $regfile = "8515def.dat" $crystal = 3690000 $baud = 9600 Config Scl = Portc.7 ' I2C-Takt Config Sda = Portc.6 ' I2C-Daten CONFIG LCDPIN = PIN , DB4 = PORTA.4 , DB5 = PORTA.5 , DB6 = PORTA.6 , DB7 = PORTA.7 , E = PORTA.3 , RS = PORTA.2 Config LCD = 16 * 2 Config TIMER0 = timer , PRESCALE = 1024 ' Timer0 als Timer, Vorteiler=1024 ' ************************************************************************ ****** ' Variablendeklaration Dim ss As Byte , mm As Byte , hh As Byte , day As Byte , month As Byte Dim Wm As Byte , Yd As Byte Dim sDatumZeit as String * 16 Dim sStatus as string * 16 ' ************************************************************************ ****** ' Konstantendeklaration Const Rtc_w = &HA2 ' RTC-Schreibadresse Const Rtc_r = &HA3 ' RTC-Leseadresse ' ************************************************************************ ****** ' Subroutinendeklaration ' Setzen Uhrzeit/Datum Declare Sub Settime(ss As Byte , mm As Byte , hh As Byte , day As Byte , month As Byte) ' Auslesen Uhrzeit/datum Declare Sub Gettime ' ************************************************************************ ****** ' Hauptprogramm ' Initialisierung DDRB = &B11111111 ' PortB Ausgänge PortB = 255 ' Ausgänge auf High DDRD = &B00000000 ' PortD Eingänge PortD = &B11111111 ' Pull-Up Widerstände month = 1 ' Anfangsdatum day = 1 hh = 23 mm = 59 ss = 22 Call Settime(ss , mm , hh , day , month) ' RTC setzen On TIMER0 Timer0_ISR ' bei Timer0-Interrupt Enable Interrupts Enable TIMER0 ' Freigabe Timerinterrupt CLS LCD "Start" wait 2 Do ' Endlosschleife Nop Loop End ' Ende Programm ' ************************************************************************ ****** ' Subroutinen ' Auslesen Uhrzeit/datum Sub Gettime I2cstart ' Start I2cwbyte Rtc_w ' Write-addresse PCF8583 I2cwbyte 2 ' select second register I2cstart ' generate repeated start I2cwbyte Rtc_r ' write address for reading I2crbyte ss , Ack ' read seconds I2crbyte mm , Ack ' read minuts I2crbyte hh , Ack ' read hours ' I2crbyte Yd , Ack ' read year and days ' I2crbyte Wm , Nack ' read weekday and month I2crbyte Day , Ack ' read year and days I2crbyte Month , Nack ' read weekday and month I2cstop ' generate stop End Sub ' Setzen Uhrzeit/Datum Sub Settime(ss As Byte , mm As Byte , hh As Byte , day As Byte , month As Byte) ' Werte zu BCD konvertieren ss = Makebcd(ss) ' seconds mm = Makebcd(mm) ' minuts hh = Makebcd(hh) ' hours day = Makebcd(day) ' days month = Makebcd(month) ' months I2cstart ' generate start I2cwbyte Rtc_w ' write address I2cwbyte 0 ' select control register I2cwbyte 8 ' set year and day bit for masking I2cstop ' generate stop I2cstart ' generate start I2cwbyte Rtc_w ' write mode I2cwbyte 2 ' select seconds Register I2cwbyte ss ' write seconds I2cwbyte mm ' write minuts I2cwbyte hh I2cwbyte day ' write days I2cwbyte month I2cstop End Sub ' ************************************************************************ ****** ' Interruptbehandlung Timer0_ISR: ' Timer-Interruptroutine Call Gettime PortB = ss ' Sekunden an PortB ausgeben toggle PortB.7 sDatumZeit = BCD(Day) + "." + BCD(month) + " - " + bcd(hh) + ":" + bcd(mm) + ":" + bcd(ss) Locate 1 , 1 lcd sDatumZeit 'locate 1 , 1 Return
Hallo Roland, mit BASCOM kann ich nciht dienen. Aber zu der Schaltjahrproblematik folgendes: Der Chip zählt immer bis zum 29.2., sollange kein Flag gelöscht oder gesetzt ist. Weiß aber im Moment nicht welches - kein Datenblatt zur Hand - Du mußt dich aber um den 29.2. selber kümmern. Einen Tag pro Jahr selbst managen ist doch vertretbar oder? Gruß Marcus
Wenn Du auf den Alarm-Interupt nicht angewiesen bist, kann ich den DS1307 von MAXIM/Dallas empfehlen. Hat 100-Jahres-Kalender mit auto-Schaltjahr, nicht nur 3 Jahre wie der 8583, ist mit Batterie bis 10 Jahre pufferbar. Sven
Michael: danke für Dein input! ich bin der Sache nachgegangen: - also das "Schaltjahrproblem" existiert m.e. auch in Dein Programm. - auch die "weekdays" und "Jahreszahl" klappen nicht so recht. Du hast auch sicherheitshalber die zwei Stellen auskommentiert. Vermutlich hast Du ähnliche Probleme festgestellt wie ich ?? aber einige "neue features" aus Deinem Listing habe ich mittlerweile übernommen. Sven: danke für den Tipp mit dem DS1307. ich werde der Sache nachgehen. scheint mir eine "bessere??" Lösung zu sein. nochmals Dank an Euch beide, Roland
@Sven >Wenn Du auf den Alarm-Interupt nicht angewiesen bist, kann ich den >DS1307 von MAXIM/Dallas empfehlen. Wieso sollte man beim 1307 auf den Alarm verzichten ? Mit Pin 7 ist das überhaupt kein Akt. Obendrein bietet er ne menge zusatzfunktionen ;)
PCF8583 und Schaltjahr geht schon. Für das Jahr gibt es einen Zähler (year) von 0 bis 3. Wenn year==0 und month==2, dann läuft date bis 29. Wenn year!=0 und month==2, dann geht date nur bis 28. Normalerweise ist alle vier Jahre ein Schaltjahr, so dass das passt. Um die Ausnahme "Jahr durch 100 teilbar und nicht durch 400 teilbar" müsste man sich selber kümmern. Das wäre wohl im Jahr 2100 der Fall ;-) Setzen kann man year übrigens ganz einfach durch: year = real_year % 4; Also tatsächliches Jahr modulo 4. Bei der PCF8583 ist noch einwenig unpraktisch, dass man das Jahr nicht direkt auslesen kann, sondern nur immer diesen Wert von 0 bis 3 bekommt. Dafür gibt's aber auch einen Trick. Der PCF8583 hat ja ein paar Bytes RAM. Dort legt man das tatsächliche Jahr ab (z.B. als 16Bit-Wert in 2 Bytes aufgeteilt) und einen Kontrollwert (yearcheck). Beim Setzten der Uhrzeit macht man dann in etwa folgendes (nur Pseudocode): rtc.year = real_year % 4; rtc.yearcheck = rtc.year; rtc.real_year_low = (low) real_year; rtc.real_year_high = (high) real_year; Beim Auslesen: real_year = rtc.real_year_high << 8 + rtc.real_year_low if (rtc.year != rtc.yearcheck) then // Der Jahreszaehler hat sich veraendert real_year ++; rtc.yearcheck = rtc.year rtc.real_year_low = (low) real_year; rtc.real_year_high = (high) real_year; fi Setzt natürlich voraus, dass die Routine zum Auslesen mindestens einmal im Jahr aufgerufen wird. Thomas
Hallo Thomas, Deine Info war schon mal interessant! Demnach hast Du das Ding richtig zum laufen gebracht ? Also was ich haben möchte, ist eine Anzeige: 1.Zeile = SS:MM:HH 2.Zeile = WT-TT-MO-JJ wobei der Wochtentag (WT) nun mal zuerst eine Anzeige 0-6 seinkann. Ich habe das ganze in bascom-Basic probiert, aber der Ablauf muss immer derselbe sein. Also: zum Datum Eingeben: Startbefehl Schreibadresse Selektiere Control/Statusregister Schreibe "0" in das controlregister (dies um das Mask-Flag nicht zu setzen meistens wird hier Bit4 - maskflag- gesetzt dann wird aber lt. Datenblatt "read as zero if maskflag is set" der Wochentag (0-6) und das Jahr nicht ausgelesen) --- oder versteh ich das falsch? Stoppbefehl erneuter Startbefehl schreibadresse selektiere sekundenregister (location 2) schreibe sekunden (0-60) schreibe minuten (0-60) schreibe stunden (0-24) schreibe Tag (1-31) schreibe Wochentag (0-6) schreibe monat (1-12) schreibe Jahr (00-99) stoppbefehl und zum Auslesen dann analog, aber mit der Leseadresse. Vielleicht (sicherlich!) mach ich irgendwo einen Gedankenfehler!?? Wo mache ich etwas falsches? Vielleicht hast Du den entscheidenden Tipp!?? Gruss, Roland
Hallo Roland, ja, bei uns lief der PCF8583 recht gut. Nun verwenden wir zwar auch den DS1307, aber eigentlich nur wegen dem geringeren Stromverbrauch und damit längeren Batterie-Pufferzeit. Hmm.. also das Controlregister haben wir nie gesetzt, sondern einfach den Resetwert belassen (der ist laut Datenblatt 0). Die Reihenfolge der Befehle sollte ansonsten so passen. Was genau funktioniert damit nicht? Beim Wochentag kannst du dir übrigens selbst aussuchen, ob 0 Sonntag oder Montag ist... der Echtzeituhr ist das egal. Thomas
Hallo Leute, Ihr habt euch alle mit PCF8583 beschäftigt. Kann jemand von euch mir helfen? Bei mir funkzioniert alles richtig, nur die Sekunden laufen einbischen schneller wie normalerweise. Wenn die Uhr aber nur offline weitertaktet(es wird keine Zeitanzeige an der LCD ausgegeben) funkzioniert er auch richtig!!! Weiß jemand woran es kiegen kann? Grüsse, Iliya
@Iliya Das Thema gab es hier schon einmal vor ein paar Jahren. Eine Ursache: zu kleiner Abblockkondensator; 10µF ist gut. Zweite Möglichkeit: alter Baustein + zu häufiges Abfragen. Warte nach dem Auslesen 50-100 ms, bevor erneut ausgelesen wird. Wer sich die Schöpfungsgeschichte ansieht kommt nicht umhin, den Montag als 1. und den Sonntag als letzten Wochentag zu verwenden :-)
Hallo Mihael, Vielen Dank für die Hinweise. Nur hoffe ich dass du unter der Abblockkondensator, der zwischen die Spannungsversorgung und die "OSCi" Pin meinst. Ich habe so ein Kondensator, der ein Wert zwischen 2,5-5pF entsprechen soll(nach der Grundschaltung aller PCF8583-Echtzeituhren), aber wegen fehlende pF-Kondensator habe ich eine von 20 nF genommen. Ich werde vielleicht mit einem grösseren Kondensator ausprobieren, da sonst fällt mir nichts ein. Sonst ist die Uhr ganz neu. Ich sende auch mein Sourcecode(Die Uhr habe ich vorher eingestellt) mit dem ich die Zeit auslese. Also, für weitere Hinweise bin ich immer offen..
@Iliya Der Abblockkondensator liegt zwischen Pin 4 und Pin 8; der Kondensator an OSCI hat einen typ. Wert von 10-15pF. 20nF ist völlig ungeeignet !
Hallo Mihael, also das Problem ist jetzt gelöst!!! Der Abblockkondensator, der gefehlt hat, war die Ursache dafür. Ich danke dir für die Hinweise:-) Du hast mir wirklich geholfen!!!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.