802 lines
22 KiB
C++
802 lines
22 KiB
C++
|
|
#include "RealTimeClock_DCF.h"
|
|||
|
|
|
|||
|
|
/**********************************************************
|
|||
|
|
Konstruktor
|
|||
|
|
**********************************************************/
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x00
|
|||
|
|
RealTimeClock_DCF::RealTimeClock_DCF() : softSerial(2, 3)
|
|||
|
|
{}
|
|||
|
|
#else
|
|||
|
|
RealTimeClock_DCF::RealTimeClock_DCF()
|
|||
|
|
{}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/**********************************************************
|
|||
|
|
<EFBFBD>ffentliche Methoden
|
|||
|
|
**********************************************************/
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: begin
|
|||
|
|
|
|||
|
|
Beschreibung: initialisiert den gew<EFBFBD>hlten Kommunikations-
|
|||
|
|
weg
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: RTCCommunication_t rtcCommunication
|
|||
|
|
Kommunikationsweg zum RTC-DCF
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::begin(void)
|
|||
|
|
{
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x00
|
|||
|
|
softSerial.begin(RTC_DCF_UART_BAUDRATE);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x01
|
|||
|
|
SPI.begin();
|
|||
|
|
SPI.setBitOrder(MSBFIRST);
|
|||
|
|
SPI.setClockDivider(SPI_CLOCK_DIV32);
|
|||
|
|
SPI.setDataMode(SPI_MODE1);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x02
|
|||
|
|
Wire.begin();
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: setTime
|
|||
|
|
|
|||
|
|
Beschreibung: setzt die Uhrzeit des RTC-DCF
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: DateTime *dateTime
|
|||
|
|
Struktur mit Datum und Uhrzeit, die im
|
|||
|
|
RTC-DCF gesetzt werden soll.
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::setDateTime(DateTime *dateTime)
|
|||
|
|
{
|
|||
|
|
uint8_t dateTimeBCD[7];
|
|||
|
|
|
|||
|
|
dateTimeBCD[0] = decimalToBCD(dateTime->getSecond());
|
|||
|
|
dateTimeBCD[1] = decimalToBCD(dateTime->getMinute());
|
|||
|
|
dateTimeBCD[2] = decimalToBCD(dateTime->getHour());
|
|||
|
|
dateTimeBCD[3] = decimalToBCD(dateTime->getWeekday() + 1);
|
|||
|
|
dateTimeBCD[4] = decimalToBCD(dateTime->getDay());
|
|||
|
|
dateTimeBCD[5] = decimalToBCD(dateTime->getMonth());
|
|||
|
|
dateTimeBCD[6] = decimalToBCD(dateTime->getYear());
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_SECOND, dateTimeBCD, 7);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: getTime
|
|||
|
|
|
|||
|
|
Beschreibung: liest die Uhrzeit des RTC-DCF
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: DateTime *dateTime
|
|||
|
|
Struktur mit Datum und Uhrzeit, in die Daten
|
|||
|
|
aus dem RTC-DCF gespeichert werden
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::getDateTime(DateTime *dateTime)
|
|||
|
|
{
|
|||
|
|
uint8_t dateTimeBCD[7];
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_SECOND, 7, dateTimeBCD);
|
|||
|
|
|
|||
|
|
dateTime->setSecond(BCDToDecimal(dateTimeBCD[0]));
|
|||
|
|
dateTime->setMinute(BCDToDecimal(dateTimeBCD[1]));
|
|||
|
|
dateTime->setHour(BCDToDecimal(dateTimeBCD[2]));
|
|||
|
|
dateTime->setWeekday(BCDToDecimal(dateTimeBCD[3]) - 1);
|
|||
|
|
dateTime->setDay(BCDToDecimal(dateTimeBCD[4]));
|
|||
|
|
dateTime->setMonth(BCDToDecimal(dateTimeBCD[5]));
|
|||
|
|
dateTime->setYear(BCDToDecimal(dateTimeBCD[6]));
|
|||
|
|
}
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: setAlarmTime
|
|||
|
|
|
|||
|
|
Beschreibung: setzt einen der beiden Alarmuhrzeiten im RTC-Chip
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: RTCAlarmWeekdays_t weekdays
|
|||
|
|
Wochentage f<EFBFBD>r den der Alarm gelten soll
|
|||
|
|
m<EFBFBD>gliche Werte:
|
|||
|
|
RTC_ALARM_WEEKDAYS_NONE,
|
|||
|
|
RTC_ALARM_WEEKDAYS_MON,
|
|||
|
|
RTC_ALARM_WEEKDAYS_TUE,
|
|||
|
|
RTC_ALARM_WEEKDAYS_WED,
|
|||
|
|
RTC_ALARM_WEEKDAYS_THU,
|
|||
|
|
RTC_ALARM_WEEKDAYS_FRI,
|
|||
|
|
RTC_ALARM_WEEKDAYS_SAT,
|
|||
|
|
RTC_ALARM_WEEKDAYS_SUN,
|
|||
|
|
RTC_ALARM_WEEKDAYS_MON_TO_FRI,
|
|||
|
|
RTC_ALARM_WEEKDAYS_SAT_TO_SUN,
|
|||
|
|
RTC_ALARM_WEEKDAYS_ALL
|
|||
|
|
|
|||
|
|
die Wochentage sind <EFBFBD>ber das bitweise Oder (|)
|
|||
|
|
verkn<EFBFBD>pfbar.
|
|||
|
|
|
|||
|
|
Beispiel: F<EFBFBD>r einen Alarm an den Wochentagen
|
|||
|
|
Montag und Donnerstag wird der Funktion folgendes
|
|||
|
|
<EFBFBD>bergeben:
|
|||
|
|
(RTC_ALARM_WEEKDAYS_MON | RTC_ALARM_WEEKDAYS_THU)
|
|||
|
|
|
|||
|
|
uint8_t hour
|
|||
|
|
Stunde zu der der Alarm ausl<EFBFBD>sen soll
|
|||
|
|
|
|||
|
|
uint8_t minute
|
|||
|
|
Minute zu der der Alarm ausl<EFBFBD>sen soll
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::setAlarmTime(RTCAlarmWeekdays_t weekdays, uint8_t hour, uint8_t minute)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmTimeBCD[] = { decimalToBCD(minute),
|
|||
|
|
decimalToBCD(hour),
|
|||
|
|
(uint8_t)weekdays };
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_ALARM_MINUTE, alarmTimeBCD, 3);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: getAlarmTime
|
|||
|
|
|
|||
|
|
Beschreibung: liest einen der beiden Alarmuhrzeiten aus dem RTC-Chip
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: RTCAlarmWeekdays_t *weekdays
|
|||
|
|
ausgelesener Wochentag an dem Alarm aktiv ist
|
|||
|
|
(Bitkodierung siehe setAlarmTime)
|
|||
|
|
|
|||
|
|
uint8_t *hour
|
|||
|
|
ausgelesene Stunde des Alarms
|
|||
|
|
|
|||
|
|
uint8_t *minute
|
|||
|
|
ausgelesene Minute des Alarms
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::getAlarmTime(RTCAlarmWeekdays_t *weekdays, uint8_t *hour, uint8_t *minute)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmTimeBCD[3];
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_ALARM_MINUTE, 7, alarmTimeBCD);
|
|||
|
|
|
|||
|
|
*minute = BCDToDecimal(alarmTimeBCD[0]);
|
|||
|
|
*hour = BCDToDecimal(alarmTimeBCD[1]);
|
|||
|
|
*weekdays = (RTCAlarmWeekdays_t)alarmTimeBCD[2];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enableAlarmInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert den eingestellten Alarm
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enableAlarmInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_ALARM_CONFIG, 1, &alarmRegister);
|
|||
|
|
|
|||
|
|
alarmRegister |= RTC_ALARM_CONFIG_REGISTER_AIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_ALARM_CONFIG, &alarmRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disableAlarmInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert den eingestellten Alarm
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disableAlarmInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_ALARM_CONFIG, 1, &alarmRegister);
|
|||
|
|
|
|||
|
|
alarmRegister &= ~RTC_ALARM_CONFIG_REGISTER_AIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_ALARM_CONFIG, &alarmRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: resetAlarmInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: schaltet den Alarm wieder scharf
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::resetAlarmInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t statusRegister = RTC_STATUS_AIF;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_STATUS, &statusRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enableAlarmLED
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert, dass die LED bei einem Alarm ein- bzw.
|
|||
|
|
nach ausschalten des Alarms wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enableAlarmLED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_ALARM_CONFIG, 1, &alarmRegister);
|
|||
|
|
|
|||
|
|
alarmRegister |= RTC_ALARM_CONFIG_REGISTER_AILED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_ALARM_CONFIG, &alarmRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disableAlarmLED
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert, dass die LED bei einem Alarm ein- bzw.
|
|||
|
|
nach ausschalten des Alarms wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disableAlarmLED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t alarmRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_ALARM_CONFIG, 1, &alarmRegister);
|
|||
|
|
|
|||
|
|
alarmRegister &= ~RTC_ALARM_CONFIG_REGISTER_AILED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_ALARM_CONFIG, &alarmRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: setPeriodicInterruptMode
|
|||
|
|
|
|||
|
|
Beschreibung: stellt den periodischen Interruptbetrieb ein
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: PeriodicInterruptSelection_t periodicInterruptSelection
|
|||
|
|
Art des periodischen Betriebs:
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_PULSE_1_HZ
|
|||
|
|
Pulsmodus mit 1 Hz
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_PULSE_2_HZ
|
|||
|
|
Pulsmodus mit 2 Hz
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_LEVEL_EVERY_SECOND
|
|||
|
|
Interrupt jede Sekunde (synchron mit Sekundenz<EFBFBD>hler)
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_LEVEL_EVERY_MINUTE
|
|||
|
|
Interrupt jede Minute (bei Sekunde = 0)
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_LEVEL_EVERY_HOUR
|
|||
|
|
Interrupt jede Stunde (bei Minute und Sekunde = 0)
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_LEVEL_EVERY_DAY
|
|||
|
|
Interrupt jeden Tag (bei Stunde, Minute und Sekunde = 0)
|
|||
|
|
|
|||
|
|
RTC_PERIODIC_INT_LEVEL_EVERY_MONTH
|
|||
|
|
Interrupt jeden Monat (jeweils am 1. um 0:00:00)
|
|||
|
|
|
|||
|
|
Hinweis:
|
|||
|
|
Die Interrupts mit der Bezeichnung LEVEL werden
|
|||
|
|
nicht automatisch zur<EFBFBD>ckgesetzt, sondern m<EFBFBD>ssen durch
|
|||
|
|
den Aufruf der Methode resetPeriodicInterrupt wieder
|
|||
|
|
scharf geschaltet werden.
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::setPeriodicInterruptMode(RTCPeriodicInterruptMode_t periodicInterruptMode)
|
|||
|
|
{
|
|||
|
|
uint8_t mode = (uint8_t)periodicInterruptMode;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_PERIODIC_INTERRUPT, &mode, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enablePeriodicInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert den eingestellten periodischen
|
|||
|
|
Interrupt
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enablePeriodicInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t perIntRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_PER_INT_CONFIG, 1, &perIntRegister);
|
|||
|
|
|
|||
|
|
perIntRegister |= RTC_PER_INT_CONFIG_REGISTER_PIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_PER_INT_CONFIG, &perIntRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disablePeriodicInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert den eingestellten periodischen
|
|||
|
|
Interrupt
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disablePeriodicInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t perIntRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_PER_INT_CONFIG, 1, &perIntRegister);
|
|||
|
|
|
|||
|
|
perIntRegister &= ~RTC_PER_INT_CONFIG_REGISTER_PIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_PER_INT_CONFIG, &perIntRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: resetPeriodicInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: schaltet den periodischen Interrupt bei
|
|||
|
|
Auswahl eines der Level-Modi wieder scharf
|
|||
|
|
(siehe setPeriodicInterrupt)
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::resetPeriodicInterrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t statusRegister = RTC_STATUS_PIF;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_STATUS, &statusRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enablePeriodicInterruptLED
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert, dass die LED bei einem periodischen Interrupt
|
|||
|
|
ein- bzw. nach ausschalten des Interrupts wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enablePeriodicInterruptLED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t perIntRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_PER_INT_CONFIG, 1, &perIntRegister);
|
|||
|
|
|
|||
|
|
perIntRegister |= RTC_PER_INT_CONFIG_REGISTER_PILED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_PER_INT_CONFIG, &perIntRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disablePeriodicInterruptLED
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert, dass die LED bei einem periodischen Interrupt
|
|||
|
|
ein- bzw. nach ausschalten des Interrupts wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disablePeriodicInterruptLED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t perIntRegister;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_PER_INT_CONFIG, 1, &perIntRegister);
|
|||
|
|
|
|||
|
|
perIntRegister &= ~RTC_PER_INT_CONFIG_REGISTER_PILED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_PER_INT_CONFIG, &perIntRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enableDCF77Reception
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert den DCF77-Empfang
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enableDCF77Reception(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register |= RTC_DCF77_CONFIG_REGISTER_DCFE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disableDCF77Reception
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert den DCF77-Empfang
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disableDCF77Reception(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register &= ~RTC_DCF77_CONFIG_REGISTER_DCFE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enableDCF77Interrupt
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert den Interrupt bei DCF77-Empfang
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enableDCF77Interrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register |= RTC_DCF77_CONFIG_REGISTER_DCFIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disableDCF77Interrupt
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert den Interrupt bei DCF77-Empfang
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disableDCF77Interrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register &= ~RTC_DCF77_CONFIG_REGISTER_DCFIE;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: resetAlarmInterrupt
|
|||
|
|
|
|||
|
|
Beschreibung: schaltet den Interrupt bei DCF77-Empfang
|
|||
|
|
wieder scharf
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::resetDCF77Interrupt(void)
|
|||
|
|
{
|
|||
|
|
uint8_t statusRegister = RTC_STATUS_DCFIF;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_STATUS, &statusRegister, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: enableDCF77LED
|
|||
|
|
|
|||
|
|
Beschreibung: aktiviert, dass die LED bei einem DCF77-Empfangs-Interrupt
|
|||
|
|
ein- bzw. nach ausschalten des Interrupts wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::enableDCF77LED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register |= RTC_DCF77_CONFIG_REGISTER_DCFLED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: disableDCF77LED
|
|||
|
|
|
|||
|
|
Beschreibung: deaktiviert, dass die LED bei einem DCF77-Empfangs-Interrupt
|
|||
|
|
ein- bzw. nach ausschalten des Interrupts wieder ausgeschaltet
|
|||
|
|
wird.
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: void
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::disableDCF77LED(void)
|
|||
|
|
{
|
|||
|
|
uint8_t dcf77Register;
|
|||
|
|
|
|||
|
|
readRegister(RTC_DCF_REG_DCF77_CONFIG, 1, &dcf77Register);
|
|||
|
|
|
|||
|
|
dcf77Register &= ~RTC_DCF77_CONFIG_REGISTER_DCFLED;
|
|||
|
|
|
|||
|
|
writeRegister(RTC_DCF_REG_DCF77_CONFIG, &dcf77Register, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**********************************************************
|
|||
|
|
private Methoden
|
|||
|
|
**********************************************************/
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: writeRegister
|
|||
|
|
|
|||
|
|
Beschreibung: schreibt eine vorgegebene Anzahl Register des
|
|||
|
|
des RTC-DCF
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: unsigned char regAddress
|
|||
|
|
Registeradresse ab der die Daten geschrieben
|
|||
|
|
werden sollen
|
|||
|
|
|
|||
|
|
unsigned char *data
|
|||
|
|
zu schreibende Daten
|
|||
|
|
|
|||
|
|
unsigned char datalength
|
|||
|
|
Anzahl der zu schreibenden Daten
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::writeRegister(RTCRegister_t regAddress, uint8_t *data, uint8_t datalength)
|
|||
|
|
{
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x00
|
|||
|
|
/* start byte */
|
|||
|
|
softSerial.write(0x02);
|
|||
|
|
|
|||
|
|
/* write direction */
|
|||
|
|
softSerial.write((uint8_t)0x00);
|
|||
|
|
|
|||
|
|
/* start address */
|
|||
|
|
softSerial.write(regAddress);
|
|||
|
|
|
|||
|
|
/* data */
|
|||
|
|
while(datalength--)
|
|||
|
|
{
|
|||
|
|
/* use bytestuffing at data bytes equal to STX, ETX and DLE */
|
|||
|
|
if( (*data == 0x02) ||
|
|||
|
|
(*data == 0x03) ||
|
|||
|
|
(*data == 0x10) )
|
|||
|
|
{
|
|||
|
|
softSerial.write(0x10);
|
|||
|
|
softSerial.write(*data | 0x80);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
softSerial.write(*data);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
data++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* end byte */
|
|||
|
|
softSerial.write(0x03);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x01
|
|||
|
|
digitalWrite(SPI_SLAVE_SELECT_PIN, LOW);
|
|||
|
|
|
|||
|
|
delayMicroseconds(50);
|
|||
|
|
SPI.transfer(regAddress | SPI_BURST_WRITE);
|
|||
|
|
|
|||
|
|
while(datalength--)
|
|||
|
|
{
|
|||
|
|
delayMicroseconds(50);
|
|||
|
|
SPI.transfer(*data);
|
|||
|
|
|
|||
|
|
data++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
digitalWrite(SPI_SLAVE_SELECT_PIN, HIGH);
|
|||
|
|
|
|||
|
|
delayMicroseconds(300);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x02
|
|||
|
|
Wire.beginTransmission(RTC_DCF_I2C_ADDRESS);
|
|||
|
|
|
|||
|
|
Wire.write(regAddress);
|
|||
|
|
|
|||
|
|
while(datalength--)
|
|||
|
|
{
|
|||
|
|
Wire.write(*data);
|
|||
|
|
|
|||
|
|
data++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Wire.endTransmission();
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: readRegister
|
|||
|
|
|
|||
|
|
Beschreibung: liest eine vorgegebene Anzahl Register des
|
|||
|
|
des RTC-DCF
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: unsigned char regAddress
|
|||
|
|
Registeradresse ab der die Daten gelesen
|
|||
|
|
werden sollen
|
|||
|
|
|
|||
|
|
unsigned char length
|
|||
|
|
Anzahl der zu lesenden Daten
|
|||
|
|
|
|||
|
|
unsigned char *data
|
|||
|
|
gelesene Daten
|
|||
|
|
|
|||
|
|
Ausgang: void
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
void RealTimeClock_DCF::readRegister(RTCRegister_t regAddress, uint8_t length, uint8_t *data)
|
|||
|
|
{
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x00
|
|||
|
|
uint8_t receivedByte;
|
|||
|
|
uint8_t nextByteStuffed;
|
|||
|
|
|
|||
|
|
/* start byte */
|
|||
|
|
softSerial.write(0x02);
|
|||
|
|
|
|||
|
|
/* write direction */
|
|||
|
|
softSerial.write(0x01);
|
|||
|
|
|
|||
|
|
/* start address */
|
|||
|
|
softSerial.write(regAddress);
|
|||
|
|
|
|||
|
|
/* count of read register */
|
|||
|
|
softSerial.write(length);
|
|||
|
|
|
|||
|
|
/* end byte */
|
|||
|
|
softSerial.write(0x03);
|
|||
|
|
|
|||
|
|
/* wait for start byte of slave */
|
|||
|
|
while(softSerial.read() != 0x02)
|
|||
|
|
{}
|
|||
|
|
|
|||
|
|
/* receive data until length is reached */
|
|||
|
|
while(length != 0)
|
|||
|
|
{
|
|||
|
|
/* wait until there are data to receive */
|
|||
|
|
while(softSerial.available() == 0)
|
|||
|
|
{}
|
|||
|
|
|
|||
|
|
receivedByte = softSerial.read();
|
|||
|
|
|
|||
|
|
/* check for stuffed bytes */
|
|||
|
|
if(receivedByte == 0x10)
|
|||
|
|
{
|
|||
|
|
nextByteStuffed = 1;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if(nextByteStuffed == 1)
|
|||
|
|
{
|
|||
|
|
receivedByte &= 0x7f;
|
|||
|
|
nextByteStuffed = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*data = receivedByte;
|
|||
|
|
|
|||
|
|
data++;
|
|||
|
|
length--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x01
|
|||
|
|
digitalWrite(SPI_SLAVE_SELECT_PIN, LOW);
|
|||
|
|
|
|||
|
|
delayMicroseconds(50);
|
|||
|
|
SPI.transfer(regAddress | SPI_BURST_READ);
|
|||
|
|
|
|||
|
|
while(length--)
|
|||
|
|
{
|
|||
|
|
delayMicroseconds(50);
|
|||
|
|
*data = SPI.transfer(0xff);
|
|||
|
|
|
|||
|
|
data++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
digitalWrite(SPI_SLAVE_SELECT_PIN, HIGH);
|
|||
|
|
|
|||
|
|
delayMicroseconds(300);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if RTC_DCF_COMMUNICATION == 0x02
|
|||
|
|
// set the register pointer to the given position, but do not stop the communication
|
|||
|
|
// after writing the pointer
|
|||
|
|
Wire.beginTransmission(RTC_DCF_I2C_ADDRESS);
|
|||
|
|
Wire.write(regAddress);
|
|||
|
|
Wire.endTransmission(false);
|
|||
|
|
|
|||
|
|
// read out the given amount of data from the registers
|
|||
|
|
Wire.requestFrom((uint8_t)RTC_DCF_I2C_ADDRESS, length);
|
|||
|
|
|
|||
|
|
while( Wire.available() )
|
|||
|
|
{
|
|||
|
|
*data = Wire.read();
|
|||
|
|
data++;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: decimalToBCD
|
|||
|
|
|
|||
|
|
Beschreibung: rechnet Dezimalwerte in das BCD-System um
|
|||
|
|
(der RTC-DCF arbeitet intern mit BCD-Daten)
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: unsigned char decimal
|
|||
|
|
umzurechnender Dezimalwert
|
|||
|
|
|
|||
|
|
Ausgang: unsigned char
|
|||
|
|
BCD-Wert der <EFBFBD>bergebenen Dezimalzahl
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
uint8_t RealTimeClock_DCF::decimalToBCD(uint8_t decimal)
|
|||
|
|
{
|
|||
|
|
return (((decimal / 10) << 4) | (decimal % 10));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*---------------------------------------------------------
|
|||
|
|
Name: BCDToDecimal
|
|||
|
|
|
|||
|
|
Beschreibung: rechnet BCD-Werte in das Dezimal-System um
|
|||
|
|
(der RTC-DCF arbeitet intern mit BCD-Daten)
|
|||
|
|
|
|||
|
|
Eing<EFBFBD>nge: unsigned char bcd
|
|||
|
|
umzurechnender BCD-Wert
|
|||
|
|
|
|||
|
|
Ausgang: unsigned char
|
|||
|
|
Dezimalwert der <EFBFBD>bergebenen BCD-Zahl
|
|||
|
|
---------------------------------------------------------*/
|
|||
|
|
uint8_t RealTimeClock_DCF::BCDToDecimal(uint8_t bcd)
|
|||
|
|
{
|
|||
|
|
return (((((bcd)>>4) & 0x0F) * 10) + ((bcd) & 0x0F));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**********************************************************
|
|||
|
|
Vorinstantiiertes Objekt
|
|||
|
|
**********************************************************/
|
|||
|
|
RealTimeClock_DCF RTC_DCF = RealTimeClock_DCF();
|