Da im Forum immer nur Fragmente zu finden sind, wenn es um die Datumsfunktion geht, stell ich hier mein meinen vollständigen Code für einen PCF8583 rein.
Es wird Datum und Uhrzeit in einer Zeile auf einem 4x20 LCD ausgegeben.
Mit 2 Tastern wird Wochentag+Uhrzeit+Datum verstellt.
Speicherbedarf: weniger als 2 kB
Ich habe den Code kurz gehalten. Ich nutze ihn weiter, um Messwerte in ein AT24Cxxx zu schreiben. Da die EEPROMs die gleiche Adresse wie der 8583 haben (!!) habe ich den 8583 auf die Adresse &HA2 gesetzt.Code:'BASCOM 1.11.8.1 'Uhrzeit und Datum mit Timer PCF8583 'Stützbatterie an PCF8583 für Stromausfall erforderlich ' 'Bedienung mit 2 Tastern an Pind.4 und Pind.5 gegen Masse und internen Pullups 'Ausgabe auf LCD 4x20 Zeichen in der obersten Zeile 'Mo*23:15:02*29.04.06 'Ausgabe entspricht genau 20 Zeichen 'Taster 1 wählt die Position zum Stellen der Uhr aus (Blinkt) 'Taster 2 zählt hoch $regfile = "m32def.dat" 'AVR Mega 32 $framesize = 32 'Stackanweisungen nicht optimiert $swstack = 16 $hwstack = 16 $crystal = 8000000 'Frequenz $baud = 9600 'Baudrate RS232 Ausgabe. $lib "mcsbyte.lbx" 'only support bytes!! for numeric<>string conversion $lib "I2C_TWI.LBX" 'Hardware I2C aktiviert Config Twi = 100000 'Config Sda = Portc.1 'für Software I2C umstellen 'Config Scl = Portc.0 I2cinit 'Adresse des PCF8583 ggf. auch &HA0 !! Const Addressw = &HA2 'slave write address Const Addressr = Addressw + 1 'slave read address 'Taster 1 und 2 Config Portd = &B00000000 '0=INPUT 1=OUTPUT Portd = Portd Or &B00110000 'pull up Widerstände setzen Taster1 Alias Pind.4 'Auswahl der Position Taster2 Alias Pind.5 'Hochzählen 'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7 Config Lcdmode = Port Config Lcdbus = 4 '4 bit mode Config Lcd = 20 * 4 Initlcd Cls Declare Sub Settime() Declare Sub Gettime() Declare Sub Menu() 'Declare array Dim Tm_raw(5) As Byte At &H60 'pointers to Tm_raw() for simple handling. Dim S As Byte At &H60 Overlay Dim M As Byte At &H61 Overlay Dim H As Byte At &H62 Overlay Dim Yd As Byte At &H63 Overlay 'Year+Day Dim Wm As Byte At &H64 Overlay 'Week+Month Dim Tm(7) As Byte At &H70 'pointers to Tm() for simple handling. Dim Weekday As Byte At &H70 Overlay Dim Hour As Byte At &H71 Overlay Dim Minute As Byte At &H72 Overlay Dim Second As Byte At &H73 Overlay Dim Day As Byte At &H74 Overlay Dim Month As Byte At &H75 Overlay Dim Year As Byte At &H76 Overlay 'Declare variables Dim Weekday_s As String * 2 Dim I As Byte Dim Menupunkt As Byte Menupunkt = 0 'Main Do Call Menu() Call Gettime() Locate 1 , 1 Lcd Weekday_s For I = 2 To 7 'Uhrzeit+Datum 20 Zeichen breit ausgeben If I = 2 Or I = 5 Then Lcd Chr(255) Else Lcd ":" If Tm(i) < 10 Then Lcd "0" Lcd Tm(i) Next If Menupunkt > 0 Then I = 3 * Menupunkt Decr I Locate 1 , I Cursor On Blink Else Cursor Off Noblink End If Waitms 100 If Taster1 = 0 Or Taster2 = 0 Then Waitms 200 Loop End Weekdays: Data "Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So" '0=Mo 1=Di ... 6=So Sub Settime() Second = Second Mod 60 Minute = Minute Mod 60 Hour = Hour Mod 24 Decr Day Day = Day Mod 31 Incr Day Decr Month Month = Month Mod 12 Incr Month 'Year = Year Mod 4 'unnötig da 2 Bit Variable Weekday = Weekday Mod 7 Tm_raw(1) = Makebcd(second) Tm_raw(2) = Makebcd(minute) Tm_raw(3) = Makebcd(hour) Tm_raw(4) = Year * 64 'Jahr um 6 Bit verschieben Tm_raw(4) = Tm_raw(4) + Makebcd(day) Tm_raw(5) = Weekday * 32 'Wochentag um 5 Bit verschieben Tm_raw(5) = Tm_raw(5) + Makebcd(month) I2cstart 'generate start I2cwbyte Addressw 'write address I2cwbyte 0 'select control register I2cwbyte 0 'set year and day bit for masking I2cstart 'repeated start I2cwbyte Addressw 'write mode I2cwbyte 2 'select Register 2 = seconds For I = 1 To 5 I2cwbyte Tm_raw(i) Next 'write Register 2,3,4,5,6 I2cstop End Sub Sub Gettime() Tm_raw(1) = 2 'set start point to second register I2creceive Addressw , Tm_raw(1) , 1 , 5 'write 1 byte from Tm_raw(1) = 2, and read 5 bytes Second = Makedec(s) 'values are stored in BCD format Minute = Makedec(m) Hour = Makedec(h) Day = Yd And &B00111111 'Bit 6 und 7 löschen Day = Makedec(day) Month = Wm And &B00011111 'Bit 5,6 und 7 löschen Month = Makedec(month) Year = Yd / 64 'Register YYDD DDDD Year = Year + 4 '2004 bis 2007 Weekday = Wm / 32 'Register WWWM MMMM Weekday_s = Lookupstr(weekday , Weekdays) 'Wochentag ermitteln End Sub Sub Menu() If Taster1 = 0 Then Incr Menupunkt Menupunkt = Menupunkt Mod 8 If Taster2 = 0 And Menupunkt > 0then Incr Tm(menupunkt) Call Settime() End If End Sub
Wer will kann die Jahreszahl aufbohren (derzeit nur 04 bis 07), indem man den batteriegestützen RAM des PCF 8583 benutzt, um eine Variable für die Jahreszahl abzulegen, die von Bascom mit hochgezählt wird.
Ich gehe von einer gestützen Stromversorgung für die RTC aus.
Obwohl im Datenblatt steht VDD=1.0V bei I2C-bus inactive, kommen mir die 1,5V mit Diode mir etwas knapp vor. Bei mir sind es 3V aus einer CR2032. Der Stromverbrauch bei Stromausfall beträgt dann 3,0 µA.
Lesezeichen