Hallo,
anbei Code zum Verwenden der RTC PCF8583. Die I²C-Lib von Peter Fleury
http://jump.to/fleury dient als Basis zur Kommunikation.
Routinen zur Auslösung/Abarbeitung eines sekündlichen Interrupts durch
die RTC muß je nach Controller und Beschaltung selbst implantiert
werden.
Es kann sinnvoll sein, in der Interruptserviceroutine (ISR) nur ein Flag
zu setzen, welches in der Main-Loop erkannt wird. So kann die ISR sehr
kurz gehalten werden und main() entscheidet, wann/ob die RTC zu lesen
ist. main() könnte z.B. die Zeit/Datumsvariablen einfach selber
weiterdrehen und nur einmalig bei PowerUp oder jeweils Nachts um
00:00:00 die RTC auslesen.
Noch so am Rande:
Ne automatische Sommer/Winterzeitumschaltung ist nett und beim PowerUp
sollte die RTC-Uhrzeit/Datum auf Plausibilität geprüft werden.
Sommer/Winterzeitumstellung kann wie folgt ermittelt werden:
1 | int8_t checkSummertime(DATETIME_T *DT){
|
2 | static uint8_t Summertime=255; //255 means not definied (eg after PowerUp)
|
3 | if(DT->wday == SUNDAY && DT->day > 24){
|
4 | if(DT->mon==3 && DT->hour==2 && (!Summertime || Summertime==255)){
|
5 | Summertime=TRUE;
|
6 | DT->hour++;
|
7 | return 1;
|
8 | }
|
9 | else if(DT->mon==10 && DT->hour==3 && (Summertime || Summertime==255)){
|
10 | Summertime=FALSE;
|
11 | DT->hour--;
|
12 | return -1;
|
13 | }
|
14 | }
|
15 | return 0;
|
16 | }
|
17 | //Wird ein Wert zurückgegeben, muss die Stunde in der RTC um diesen Wert korrigiert werden.
|
Als Gerüst zur Plausibilitätsprüfung kann folgendes (Ursprünglicher
Autor ist mir leider unbekannt) dienen:
1 | /*************************************************************************/
|
2 | static const unsigned char days_in_month[] =
|
3 | { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
4 | BOOL isDateValid(DATETIME_T *date){
|
5 | uint8_t leap = ((date->mon == 2) && ((date->year % 4) == 0)) ? 1 : 0;
|
6 | if(date->year > 99 || date->year < 1 || date->mon > 12 || date->mon < 1 || date->day < 1 || date->day > (days_in_month[date->mon] + leap))
|
7 | return FALSE;
|
8 | else
|
9 | return TRUE;
|
10 | }
|
11 | /*************************************************************************/
|
12 | BOOL isTimeValid(DATETIME_T *time){
|
13 | if(time->hour > 23 || time->min > 59 || time->sec > 59)
|
14 | return FALSE;
|
15 | else
|
16 | return TRUE;
|
17 | }
|
Die Beispiele hier sind in der *.zip enthalten
Gruß Frank