Added some more projects and libraries.

This commit is contained in:
Johannes Findeisen 2022-11-27 16:14:05 +01:00
commit 1e1459fa50
94 changed files with 11904 additions and 0 deletions

View file

@ -0,0 +1,243 @@
#include "DateTime.h"
/**********************************************************
Konstruktor
**********************************************************/
DateTime::DateTime()
{}
/*---------------------------------------------------------
Name: DateTime
Beschreibung: Konstruktor mit Übergabe der Datum und Uhrzeit
Eingänge: unsigned char year
Jahr
unsigned char month
Monat
unsigned char day
Tag
unsigned char weekday
Wochentag (0: Sonntag, 1: Montag ...)
unsigned char hour
Stunde
unsigned char minute
Minute
unsigned char second
Sekunde
Ausgang: void
---------------------------------------------------------*/
DateTime::DateTime( unsigned char year, unsigned char month, unsigned char day, unsigned char weekday,
unsigned char hour, unsigned char minute, unsigned char second)
{
this->year = year;
this->month = month;
this->day = day;
this->weekday = weekday;
this->hour = hour;
this->minute = minute;
this->second = second;
}
/**********************************************************
öffentliche Methoden
**********************************************************/
/*---------------------------------------------------------
Name: addSecond
Beschreibung: addiert eine Sekunde auf die aktuell
gespeicherte Zeit inkl. Auswertung aller
Überträge
Eingänge: void
Ausgang: void
---------------------------------------------------------*/
void DateTime::addSecond(void)
{
this->second++;
if(this->second >= 60)
{
this->second = 0;
this->minute++;
if(this->minute >= 60)
{
this->minute = 0;
this->hour++;
if(this->hour >= 24)
{
this->hour = 0;
this->day++;
this->weekday = (this->weekday + 1) % 7;
if(this->day >= daysInMonth(month, year))
{
this->day = 1;
this->month++;
if(this->month > 12)
{
this->month = 1;
this->year++;
}
}
}
}
}
}
/*---------------------------------------------------------
Name: daysInMonth
Beschreibung: gibt die Anzahl der Tages eines Monats zurück
Eingänge: unsigned char month
Monat für den die Anzahl der Tage gesucht wird
unsigned char year
Jahr in dem sich der Monat befindet
(wird bei der Entscheidung benötigt, ob
der Februar 28 oder 29 Tage hat)
Ausgang: unsigned char
Anzahl der Monatstage
---------------------------------------------------------*/
unsigned char DateTime::daysInMonth(unsigned char month, unsigned char year)
{
unsigned char days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
unsigned char daysInMonth = days[month];
if(month == 2 && isLeapyear(year))
{
daysInMonth = 29;
}
return daysInMonth;
}
/*---------------------------------------------------------
Name: isLeapyear
Beschreibung: gibt zurück ob das übergebene Jahr ein Schaltjahr ist
Hinweis:
Bei der Auswertung wird nur kontrolliert, ob das Jahr
durch 4 teilbar ist.
Eingänge: unsigned char year
Jahr, das auf Schaltjahr geprüft werden soll
(Angabe als 2stelliger Wert)
Ausgang: unsigned char
Jahr ist ein Schaltjahr?
0: kein Schaltjahr
1: Schaltjahr
---------------------------------------------------------*/
unsigned char DateTime::isLeapyear(unsigned char year)
{
unsigned char leapyear = 0;
if(year & 0x03 == 0)
{
leapyear = 1;
}
return leapyear;
}
/*---------------------------------------------------------
Name: getDateTimeString
Beschreibung: gibt die gespeicherte Zeit als Zeichenkette
zurück
Eingänge: char* dateTimeString
enthält am Ende der Funktion die gespeicherte
Zeit (Datum und Uhrzeit)
Mindestgröße: 18 Byte
Ausgabeformat: dd.MM.yy-hh:mm:ss
Ausgang: void
---------------------------------------------------------*/
void DateTime::getDateTimeString(char* dateTimeString)
{
getDateString(dateTimeString);
dateTimeString[8] = '-';
getTimeString(dateTimeString + 9);
}
/*---------------------------------------------------------
Name: getDateString
Beschreibung: gibt das gespeicherte Datum als Zeichenkette
zurück
Eingänge: char* dateString
enthält am Ende der Funktion das gespeicherte
Datum
Mindestgröße: 9 Byte
Ausgabeformat: dd.MM.yy
Ausgang: void
---------------------------------------------------------*/
void DateTime::getDateString(char* dateString)
{
dateString[0] = (this->day / 10) + '0';
dateString[1] = (this->day % 10) + '0';
dateString[2] = '.';
dateString[3] = (this->month / 10) + '0';
dateString[4] = (this->month % 10) + '0';
dateString[5] = '.';
dateString[6] = (this->year / 10) + '0';
dateString[7] = (this->year % 10) + '0';
dateString[8] = '\n';
}
/*---------------------------------------------------------
Name: getTimeString
Beschreibung: gibt die gespeicherte Uhrzeit als Zeichenkette
zurück
Eingänge: char* timeString
enthält am Ende der Funktion die gespeicherte
Uhrzeit
Mindestgröße: 9 Byte
Ausgabeformat: hh:mm:ss
Ausgang: void
---------------------------------------------------------*/
void DateTime::getTimeString(char* timeString)
{
timeString[0] = (this->hour / 10) + '0';
timeString[1] = (this->hour % 10) + '0';
timeString[2] = ':';
timeString[3] = (this->minute / 10) + '0';
timeString[4] = (this->minute % 10) + '0';
timeString[5] = ':';
timeString[6] = (this->second / 10) + '0';
timeString[7] = (this->second % 10) + '0';
timeString[8] = '\n';
}

View file

@ -0,0 +1,70 @@
#ifndef DateTime_h
#define DateTime_h
/**********************************************************
Klasse DateTime
**********************************************************/
class DateTime
{
private:
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char weekday;
unsigned char day;
unsigned char month;
unsigned char year;
public:
enum weekday {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};
DateTime();
DateTime( unsigned char year, unsigned char month, unsigned char day, unsigned char weekday,
unsigned char hour, unsigned char minute, unsigned char second);
// Schreiben bzw. Lesen der Sekunde
unsigned char getSecond(void) { return second; }
void setSecond(unsigned char value) { second = value; }
// Schreiben bzw. Lesen der Minute
unsigned char getMinute(void) { return minute; }
void setMinute(unsigned char value) { minute = value; }
// Schreiben bzw. Lesen der Stunde
unsigned char getHour(void) { return hour; }
void setHour(unsigned char value) { hour = value; }
// Schreiben bzw. Lesen des Wochentags
unsigned char getWeekday(void) { return weekday; }
void setWeekday(unsigned char value) { weekday = value; }
// Schreiben bzw. Lesen des Tags
unsigned char getDay(void) { return day; }
void setDay(unsigned char value) { day = value; }
// Schreiben bzw. Lesen des Monats
unsigned char getMonth(void) { return month; }
void setMonth(unsigned char value) { month = value; }
// Schreiben bzw. Lesen des Jahres
unsigned char getYear(void) { return year; }
void setYear(unsigned char value) { year = value; }
// Weiterzählen der Sekunden
void addSecond(void);
// Anzahl Tage im Monat
unsigned char daysInMonth(unsigned char month, unsigned char year);
// Kontrolle, ob Schaltjahr
unsigned char isLeapyear(unsigned char year);
// Datum und/oder Uhrzeit als Zeichenkette
void getDateTimeString(char* dateTimeString);
void getDateString(char* dateString);
void getTimeString(char* timeString);
};
#endif

View file

@ -0,0 +1,802 @@
#include "RealTimeClock_DCF.h"
/**********************************************************
Konstruktor
**********************************************************/
#if RTC_DCF_COMMUNICATION == 0x00
RealTimeClock_DCF::RealTimeClock_DCF() : softSerial(2, 3)
{}
#else
RealTimeClock_DCF::RealTimeClock_DCF()
{}
#endif
/**********************************************************
öffentliche Methoden
**********************************************************/
/*---------------------------------------------------------
Name: begin
Beschreibung: initialisiert den gewählten Kommunikations-
weg
Eingä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ä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ä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änge: RTCAlarmWeekdays_t weekdays
Wochentage für den der Alarm gelten soll
mö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 über das bitweise Oder (|)
verknüpfbar.
Beispiel: Für einen Alarm an den Wochentagen
Montag und Donnerstag wird der Funktion folgendes
übergeben:
(RTC_ALARM_WEEKDAYS_MON | RTC_ALARM_WEEKDAYS_THU)
uint8_t hour
Stunde zu der der Alarm auslösen soll
uint8_t minute
Minute zu der der Alarm auslö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ä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ä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ä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ä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ä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ä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ä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ä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ückgesetzt, sondern mü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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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änge: unsigned char decimal
umzurechnender Dezimalwert
Ausgang: unsigned char
BCD-Wert der ü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änge: unsigned char bcd
umzurechnender BCD-Wert
Ausgang: unsigned char
Dezimalwert der ü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();

View file

@ -0,0 +1,170 @@
#ifndef RealTimeClock_DCF_h
#define RealTimeClock_DCF_h
#include <Arduino.h>
#include "DateTime.h"
#include "config/RTC_DCF_config.h"
#if RTC_DCF_COMMUNICATION == 0x00
#include "../modSoftSerial/modSoftwareSerial.h"
#define RTC_DCF_ALARM_INT_PIN 11
#define RTC_DCF_PER_INT_PIN 12
#define RTC_DCF_DCF77_INT_PIN 10
#endif
#if RTC_DCF_COMMUNICATION == 0x01
#include "../SPI/SPI.h"
#define RTC_DCF_ALARM_INT_PIN 2
#define RTC_DCF_PER_INT_PIN 18
#define RTC_DCF_DCF77_INT_PIN 19
#endif
#if RTC_DCF_COMMUNICATION == 0x02
#include "../Wire/Wire.h"
#define RTC_DCF_ALARM_INT_PIN 11
#define RTC_DCF_PER_INT_PIN 12
#define RTC_DCF_DCF77_INT_PIN 10
#endif
#define SPI_SLAVE_SELECT_PIN 10
typedef enum
{
SPI_BURST_WRITE = 0x00,
SPI_SINGLE_WRITE = 0x80,
SPI_BURST_READ = 0x40,
SPI_SINGLE_READ = 0xc0
} SPITransferFormat_t;
typedef enum
{
RTC_DCF_REG_SECOND = 0x20,
RTC_DCF_REG_MINUTE,
RTC_DCF_REG_HOUR,
RTC_DCF_REG_WEEKDAY,
RTC_DCF_REG_DAY,
RTC_DCF_REG_MONTH,
RTC_DCF_REG_YEAR,
RTC_DCF_REG_ALARM_MINUTE,
RTC_DCF_REG_ALARM_HOUR,
RTC_DCF_REG_ALARM_WEEKDAY,
RTC_DCF_REG_PERIODIC_INTERRUPT,
RTC_DCF_REG_ALARM_CONFIG,
RTC_DCF_REG_PER_INT_CONFIG,
RTC_DCF_REG_DCF77_CONFIG,
RTC_DCF_REG_STATUS,
RTC_DCF_REG_RESERVED
} RTCRegister_t;
typedef enum
{
RTC_PERIODIC_INT_PULSE_1_HZ = 0x00,
RTC_PERIODIC_INT_PULSE_2_HZ = 0x01,
RTC_PERIODIC_INT_LEVEL_EVERY_SECOND = 0x02,
RTC_PERIODIC_INT_LEVEL_EVERY_MINUTE = 0x03,
RTC_PERIODIC_INT_LEVEL_EVERY_HOUR = 0x04,
RTC_PERIODIC_INT_LEVEL_EVERY_DAY = 0x05,
RTC_PERIODIC_INT_LEVEL_EVERY_MONTH = 0x06
} RTCPeriodicInterruptMode_t;
typedef enum
{
RTC_ALARM_CONFIG_REGISTER_AIE = 0x02, // Alarm-Interrupt Enable
RTC_ALARM_CONFIG_REGISTER_AILED = 0x04 // LED-Signalisation at Alarm-Interrupt Enable
} RTCAlarmConfigRegisterBits_t;
typedef enum
{
RTC_PER_INT_CONFIG_REGISTER_PIE = 0x02, // Periodic-Interrupt Enable
RTC_PER_INT_CONFIG_REGISTER_PILED = 0x04 // LED-Signalisation at Periodic-Interrupt Enable
} RTCPeriodicInterruptConfigRegisterBits_t;
typedef enum
{
RTC_DCF77_CONFIG_REGISTER_DCFE = 0x01, // DCF77 Enable
RTC_DCF77_CONFIG_REGISTER_DCFIE = 0x02, // DCF77-Interrupt Enable
RTC_DCF77_CONFIG_REGISTER_DCFLED = 0x04 // LED-Signalisation at DCF77-Interrupt Enable
} RTCDCF77ConfigRegisterBits_t;
typedef enum
{
RTC_STATUS_DCFIF = 0x01, // DCF77-Interrupt Flag
RTC_STATUS_PIF = 0x02, // Periodic-Interrupt Flag
RTC_STATUS_AIF = 0x04 // Alarm-Interrupt Flag
} RTCStatusRegisterBits_t;
typedef enum
{
RTC_ALARM_WEEKDAYS_NONE = 0x00,
RTC_ALARM_WEEKDAYS_MON = 0x01,
RTC_ALARM_WEEKDAYS_TUE = 0x02,
RTC_ALARM_WEEKDAYS_WED = 0x04,
RTC_ALARM_WEEKDAYS_THU = 0x08,
RTC_ALARM_WEEKDAYS_FRI = 0x10,
RTC_ALARM_WEEKDAYS_SAT = 0x20,
RTC_ALARM_WEEKDAYS_SUN = 0x40,
RTC_ALARM_WEEKDAYS_MON_TO_FRI = 0x1f,
RTC_ALARM_WEEKDAYS_SAT_TO_SUN = 0x60,
RTC_ALARM_WEEKDAYS_ALL = 0x7f
} RTCAlarmWeekdays_t;
/**********************************************************
Klasse RealTimeClock_DCF
**********************************************************/
class RealTimeClock_DCF
{
private:
// Schreiben bzw. Lesen der Register
void writeRegister(RTCRegister_t, uint8_t*, uint8_t);
void readRegister(RTCRegister_t, uint8_t, uint8_t*);
// Konvertierung BCD zu Dezimal bzw. Dezimal zu BCD
uint8_t decimalToBCD(uint8_t);
uint8_t BCDToDecimal(uint8_t);
#if RTC_DCF_COMMUNICATION == 0x00
modSoftwareSerial softSerial;
#endif
public:
RealTimeClock_DCF();
// Systemstart
void begin(void);
// Zeiteinstellung
void setDateTime(DateTime*);
void getDateTime(DateTime*);
// Alarm
void setAlarmTime(RTCAlarmWeekdays_t, uint8_t, uint8_t);
void getAlarmTime(RTCAlarmWeekdays_t*, uint8_t*, uint8_t*);
void enableAlarmInterrupt(void);
void disableAlarmInterrupt(void);
void resetAlarmInterrupt(void);
void enableAlarmLED(void);
void disableAlarmLED(void);
// Periodic Interrupt
void setPeriodicInterruptMode(RTCPeriodicInterruptMode_t);
void enablePeriodicInterrupt(void);
void disablePeriodicInterrupt(void);
void resetPeriodicInterrupt(void);
void enablePeriodicInterruptLED(void);
void disablePeriodicInterruptLED(void);
// DCF77
void enableDCF77Reception(void);
void disableDCF77Reception(void);
void enableDCF77Interrupt(void);
void disableDCF77Interrupt(void);
void resetDCF77Interrupt(void);
void enableDCF77LED(void);
void disableDCF77LED(void);
};
extern RealTimeClock_DCF RTC_DCF;
#endif /* RealTimeClock_DCF_h */

View file

@ -0,0 +1,20 @@
#ifndef RTC_DCF_config_h
#define RTC_DCF_config_h
/******************************************************************************
Definitionen
******************************************************************************/
/* Wahl der Kommunikationsart
mögliche Werte: 0x00 UART
0x01 SPI
Ox02 I2C */
#define RTC_DCF_COMMUNICATION 0x02
/* eingestellte I2C-Adresse des RTC-DCF (wird nur bei I2C-Kommunikation benötigt) */
#define RTC_DCF_I2C_ADDRESS 0x01
/* eingestellte Baudrate des RTC-DCF (wird nur bei UART-Kommunikation benötigt) */
#define RTC_DCF_UART_BAUDRATE 4800
#endif /* RTC_DCF_config_h */

View file

@ -0,0 +1,116 @@
/******************************************************************************
Beispiel: alarmInterrupt
Beschreibung: Dieses Beispiel zeigt die Verwendung des Alarms innerhalb des
RTC-DCF.
Hinweis: Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
kann der Kommunikationsweg umgestellt werden.
Bei Verwendung der UART-Schnittstelle wird ein Objekt der Klasse
modSoftSerial angelegt. Diese Klasse entspricht einer
modifizierten SoftSerial-Klasse. Innerhalb der modifizierten
Klasse wird nur der PinChange-Interrupt für den Port D (PCINT2_vect)
angelegt, anstatt alle PinChange-Interrupts anzulegen. Ohne diese
Modifizierung wäre eine Verwendung von SoftSerial und PinChangeInt
nicht parallel möglich.
Die modifizierte SoftSerial-Klasse ist Teil der RTC-DCF-Library.
Die PinChangeInt-Klasse ist nicht Teil der RTC-DCF-Library, kann
aber auf folgender Internetseite heruntergeladen werden:
http://arduino.cc/playground/Main/PinChangeInt
******************************************************************************/
#include <stdio.h>
#include "DateTime.h"
#include "RealTimeClock_DCF.h"
/* leider setzt die Arduino-IDE voraus, dass alle in einem Projekt verwendeten
Klassen auch ins Sketch übernommen werden. Wird dieses nicht berücksichtigt,
kommt es zu Fehlern beim Linken des Programms. Daher muss an dieser Stelle
die Headerdatei zu der jeweils verwendeten Kommunikationsklasse eingefügt
werden. Die beiden jeweils nicht verwendeten Header müssen auskommentiert
werden. */
/* für die Kommunikation über UART die modSoftwareSerial.h verwenden */
//#include "modSoftwareSerial.h"
/* für die Kommunikation über SPI die SPI.h verwenden */
//#include "SPI.h"
/* für die Kommunikation über Wire die Wire.h verwenden */
#include "Wire.h"
/******************************************************************************
Definitionen
******************************************************************************/
/* für die Kommunikation über UART wird ein Objekt der Klasse modSoftwareSerial
benötigt. Da diese Klasse den Pin Change Interrupt am Port D blockiert, muss
dieser für die Klasse PinChangeInt deaktiviert werden. */
#if RTC_DCF_COMMUNICATION == 0x00
#define NO_PORTD_PINCHANGES
#endif
#include "PinChangeInt.h"
/******************************************************************************
globale Variablen
******************************************************************************/
/* einzustellende Uhrzeit */
DateTime dateTime = DateTime(0, 1, 1, DateTime::SATURDAY, 0, 59, 55);
/* Flag zur Anzeige eines Alarms */
volatile uint8_t alarmFlag = 0;
/******************************************************************************
Funktionen
******************************************************************************/
void setup()
{
/* der RTC-DCF benötigt ca. 1,5 Sekunden bis er Daten empfangen kann */
delay(1500);
/* den Pin für den Alarm-Interrupt als Eingang und als externe
Interrupt-Quelle definieren */
pinMode(RTC_DCF_ALARM_INT_PIN, INPUT);
PCintPort::attachInterrupt(RTC_DCF_ALARM_INT_PIN, &alarmInterrupt, FALLING);
/* RTC-DCF initialisieren */
RTC_DCF.begin();
/* Uhrzeit im RTC-DCF setzen */
RTC_DCF.setDateTime(&dateTime);
/* den Alarm auf 1:00 Uhr (5 Sekunden nach der eingestellten Uhrzeit) setzen */
RTC_DCF.setAlarmTime(RTC_ALARM_WEEKDAYS_ALL, 1, 0);
/* den Alarm-Interrupt des RTC-DCF aktivieren */
RTC_DCF.enableAlarmInterrupt();
/* die serielle Ausgabe initialisieren */
Serial.begin(115200);
/* Interrupts einschalten */
interrupts();
}
void loop()
{
/* "ALARM" über die serielle Schnittstelle ausgeben und den Alarm-Interrupt
des RTC-DCF zurücksetzen, wenn das Alarm-Flag gesetzt wird */
if(alarmFlag == 1)
{
Serial.println("ALARM");
RTC_DCF.resetAlarmInterrupt();
alarmFlag = 0;
}
}
void alarmInterrupt(void)
{
alarmFlag = 1;
}

View file

@ -0,0 +1,151 @@
/******************************************************************************
Beispiel: dcf77Interrupt
Beschreibung: Dieses Beispiel zeigt die Verwendung des DCF77-Empfänger
innerhalb des RTC-DCF.
Hinweis: Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
kann der Kommunikationsweg umgestellt werden.
Bei Verwendung der UART-Schnittstelle wird ein Objekt der Klasse
modSoftSerial angelegt. Diese Klasse entspricht einer
modifizierten SoftSerial-Klasse. Innerhalb der modifizierten
Klasse wird nur der PinChange-Interrupt für den Port D (PCINT2_vect)
angelegt, anstatt alle PinChange-Interrupts anzulegen. Ohne diese
Modifizierung wäre eine Verwendung von SoftSerial und PinChangeInt
nicht parallel möglich.
Die modifizierte SoftSerial-Klasse ist Teil der RTC-DCF-Library.
Die PinChangeInt-Klasse ist nicht Teil der RTC-DCF-Library, kann
aber auf folgender Internetseite heruntergeladen werden:
http://arduino.cc/playground/Main/PinChangeInt
******************************************************************************/
#include <stdio.h>
#include "DateTime.h"
#include "RealTimeClock_DCF.h"
/* leider setzt die Arduino-IDE voraus, dass alle in einem Projekt verwendeten
Klassen auch ins Sketch übernommen werden. Wird dieses nicht berücksichtigt,
kommt es zu Fehlern beim Linken des Programms. Daher muss an dieser Stelle
die Headerdatei zu der jeweils verwendeten Kommunikationsklasse eingefügt
werden. Die beiden jeweils nicht verwendeten Header müssen auskommentiert
werden. */
/* für die Kommunikation über UART die modSoftwareSerial.h verwenden */
//#include "modSoftwareSerial.h"
/* für die Kommunikation über SPI die SPI.h verwenden */
//#include "SPI.h"
/* für die Kommunikation über Wire die Wire.h verwenden */
#include "Wire.h"
/******************************************************************************
Definitionen
******************************************************************************/
/* für die Kommunikation über UART wird ein Objekt der Klasse modSoftwareSerial
benötigt. Da diese Klasse den Pin Change Interrupt am Port D blockiert, muss
dieser für die Klasse PinChangeInt deaktiviert werden. */
#if RTC_DCF_COMMUNICATION == 0x00
#define NO_PORTD_PINCHANGES
#endif
#include "PinChangeInt.h"
/******************************************************************************
globale Variablen
******************************************************************************/
/* gelesene Uhrzeit */
DateTime readDateTime;
/* Flag zur Anzeige eines periodischen Interrupts */
volatile uint8_t perInterruptFlag = 0;
/* Flag zur Anzeige eines DCF77-Empfangs-Interrupts */
volatile uint8_t dcf77InterruptFlag = 0;
/******************************************************************************
Funktionen
******************************************************************************/
void setup()
{
/* der RTC-DCF benötigt ca. 1,5 Sekunden bis er Daten empfangen kann */
delay(1500);
/* den Pin für den periodischen Interrupt als Eingang definieren und als externe
Interrupt-Quelle definieren */
pinMode(RTC_DCF_PER_INT_PIN, INPUT);
PCintPort::attachInterrupt(RTC_DCF_PER_INT_PIN, &periodicInterrupt, FALLING);
/* den Pin für den DCF77-Interrupt als Eingang definieren und als externe
Interrupt-Quelle definieren */
pinMode(RTC_DCF_DCF77_INT_PIN, INPUT);
PCintPort::attachInterrupt(RTC_DCF_DCF77_INT_PIN, &dcf77Interrupt, FALLING);
/* RTC-DCF initialisieren */
RTC_DCF.begin();
/* DCF77-Empfang aktivieren */
RTC_DCF.enableDCF77Reception();
RTC_DCF.enableDCF77Interrupt();
/* den periodischen Interrupt auf 1 Hz einstellen */
RTC_DCF.setPeriodicInterruptMode(RTC_PERIODIC_INT_PULSE_1_HZ);
/* den periodischen Interrupt des RTC-DCF aktivieren */
RTC_DCF.enablePeriodicInterrupt();
/* die serielle Ausgabe initialisieren */
Serial.begin(115200);
/* Interrupts einschalten */
interrupts();
}
void loop()
{
/* wenn das Flag für den periodischen Interrupt gesetzt wird die Uhrzeit aus dem
RTC-DCF auslesen und über die serielle Schnittstelle */
if(perInterruptFlag == 1)
{
RTC_DCF.getDateTime(&readDateTime);
printClock();
perInterruptFlag = 0;
}
if(dcf77InterruptFlag == 1)
{
Serial.println("DCF77 empfangen");
RTC_DCF.getDateTime(&readDateTime);
RTC_DCF.resetDCF77Interrupt();
printClock();
dcf77InterruptFlag = 0;
}
}
void periodicInterrupt(void)
{
perInterruptFlag = 1;
}
void dcf77Interrupt(void)
{
dcf77InterruptFlag = 1;
}
void printClock(void)
{
char clockString[30];
sprintf(clockString, "Es ist %02u:%02u:%02u am %02u.%02u.%02u", readDateTime.getHour(), readDateTime.getMinute(), readDateTime.getSecond(), readDateTime.getDay(), readDateTime.getMonth(), readDateTime.getYear());
Serial.println(clockString);
}

View file

@ -0,0 +1,123 @@
/******************************************************************************
Beispiel: periodicInterrupt
Beschreibung: Dieses Beispiel zeigt die Verwendung des periodischen Interrupts
innerhalb des RTC-DCF.
Hinweis: Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
kann der Kommunikationsweg umgestellt werden.
Bei Verwendung der UART-Schnittstelle wird ein Objekt der Klasse
modSoftSerial angelegt. Diese Klasse entspricht einer
modifizierten SoftSerial-Klasse. Innerhalb der modifizierten
Klasse wird nur der PinChange-Interrupt für den Port D (PCINT2_vect)
angelegt, anstatt alle PinChange-Interrupts anzulegen. Ohne diese
Modifizierung wäre eine Verwendung von SoftSerial und PinChangeInt
nicht parallel möglich.
Die modifizierte SoftSerial-Klasse ist Teil der RTC-DCF-Library.
Die PinChangeInt-Klasse ist nicht Teil der RTC-DCF-Library, kann
aber auf folgender Internetseite heruntergeladen werden:
http://arduino.cc/playground/Main/PinChangeInt
******************************************************************************/
#include <stdio.h>
#include "DateTime.h"
#include "RealTimeClock_DCF.h"
/* leider setzt die Arduino-IDE voraus, dass alle in einem Projekt verwendeten
Klassen auch ins Sketch übernommen werden. Wird dieses nicht berücksichtigt,
kommt es zu Fehlern beim Linken des Programms. Daher muss an dieser Stelle
die Headerdatei zu der jeweils verwendeten Kommunikationsklasse eingefügt
werden. Die beiden jeweils nicht verwendeten Header müssen auskommentiert
werden. */
/* für die Kommunikation über UART die modSoftwareSerial.h verwenden */
#include "modSoftwareSerial.h"
/* für die Kommunikation über SPI die SPI.h verwenden */
//#include "SPI.h"
/* für die Kommunikation über Wire die Wire.h verwenden */
//#include "Wire.h"
/******************************************************************************
Definitionen
******************************************************************************/
/* für die Kommunikation über UART wird ein Objekt der Klasse modSoftwareSerial
benötigt. Da diese Klasse den Pin Change Interrupt am Port D blockiert, muss
dieser für die Klasse PinChangeInt deaktiviert werden. */
#if RTC_DCF_COMMUNICATION == 0x00
#define NO_PORTD_PINCHANGES
#endif
#include "PinChangeInt.h"
/******************************************************************************
globale Variablen
******************************************************************************/
/* aktuelle Uhrzeit */
DateTime dateTime;
/* Flag zur Anzeige eines periodischen Interrupts */
volatile uint8_t periodicInterruptFlag = 0;
/******************************************************************************
Funktionen
******************************************************************************/
void setup()
{
/* der RTC-DCF benötigt ca. 1,5 Sekunden bis er Daten empfangen kann */
delay(1500);
/* den Pin für den periodischen Interrupt als Eingang und als externe
Interrupt-Quelle definieren */
pinMode(RTC_DCF_PER_INT_PIN, INPUT);
PCintPort::attachInterrupt(RTC_DCF_PER_INT_PIN, &periodicInterrupt, FALLING);
/* RTC-DCF initialisieren */
RTC_DCF.begin();
/* den periodischen Interrupt auf 1 Hz einstellen */
RTC_DCF.setPeriodicInterruptMode(RTC_PERIODIC_INT_PULSE_1_HZ);
/* den periodischen Interrupt des RTC-DCF aktivieren */
RTC_DCF.enablePeriodicInterrupt();
/* die serielle Ausgabe initialisieren */
Serial.begin(115200);
/* Interrupts einschalten */
interrupts();
}
void loop()
{
/* wenn das Flag für den periodischen Interrupt gesetzt wird die Uhrzeit aus dem
RTC-DCF auslesen und über die serielle Schnittstelle */
if(periodicInterruptFlag == 1)
{
RTC_DCF.getDateTime(&dateTime);
printClock();
periodicInterruptFlag = 0;
}
}
void periodicInterrupt(void)
{
periodicInterruptFlag = 1;
}
void printClock(void)
{
char clockString[30];
sprintf(clockString, "Es ist %02u:%02u:%02u am %02u.%02u.%02u", dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(), dateTime.getDay(), dateTime.getMonth(), dateTime.getYear());
Serial.println(clockString);
}

View file

@ -0,0 +1,74 @@
/******************************************************************************
Beispiel: setTime
Beschreibung: Dieses Beispiel zeigt das Schreiben und Lesen der Uhrzeit aus
dem RTC-DCF.
Hinweis: Zur Einstellung des Kommunikationswegs (UART, SPI oder I2C) zum
RTC-DCF enthält die Library die Datei RTC_DCF_config.h im
Unterordner \libraries\RTC_DCF\config\. Innerhalb dieser Datei
kann der Kommunikationsweg umgestellt werden.
******************************************************************************/
#include <stdio.h>
#include "DateTime.h"
#include "RealTimeClock_DCF.h"
/* leider setzt die Arduino-IDE voraus, dass alle in einem Projekt verwendeten
Klassen auch ins Sketch übernommen werden. Wird dieses nicht berücksichtigt,
kommt es zu Fehlern beim Linken des Programms. Daher muss an dieser Stelle
die Headerdatei zu der jeweils verwendeten Kommunikationsklasse eingefügt
werden. Die beiden jeweils nicht verwendeten Header müssen auskommentiert
werden. */
/* für die Kommunikation über UART die modSoftwareSerial.h verwenden */
//#include "modSoftwareSerial.h"
/* für die Kommunikation über SPI die SPI.h verwenden */
//#include "SPI.h"
/* für die Kommunikation über Wire die Wire.h verwenden */
#include "Wire.h"
/******************************************************************************
globale Variablen
******************************************************************************/
/* einzustellende Uhrzeit */
DateTime dateTime = DateTime(0, 1, 1, DateTime::SATURDAY, 0, 0, 0);
/******************************************************************************
Funktionen
******************************************************************************/
void setup()
{
/* der RTC-DCF benötigt ca. 1,5 Sekunden bis er Daten empfangen kann */
delay(1500);
/* RTC-DCF initialisieren */
RTC_DCF.begin();
/* Uhrzeit im RTC-DCF setzen */
RTC_DCF.setDateTime(&dateTime);
/* die serielle Ausgabe initialisieren */
Serial.begin(115200);
}
void loop()
{
/* ca. jede Sekunde wird die Uhrzeit ausgelesen und über die serielle Schnittstelle
ausgegeben. */
delay(1000);
RTC_DCF.getDateTime(&dateTime);
printClock();
}
void printClock(void)
{
char clockString[30];
sprintf(clockString, "Es ist %02u:%02u:%02u am %02u.%02u.%02u", dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(), dateTime.getDay(), dateTime.getMonth(), dateTime.getYear());
Serial.println(clockString);
}

View file

@ -0,0 +1,69 @@
#######################################
# Syntax Coloring Map For RTC_DCF
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
RTC_PERIODIC_INT_PULSE_1_HZ KEYWORD1
RTC_PERIODIC_INT_PULSE_2_HZ KEYWORD1
RTC_PERIODIC_INT_LEVEL_EVERY_SECOND KEYWORD1
RTC_PERIODIC_INT_LEVEL_EVERY_MINUTE KEYWORD1
RTC_PERIODIC_INT_LEVEL_EVERY_HOUR KEYWORD1
RTC_PERIODIC_INT_LEVEL_EVERY_DAY KEYWORD1
RTC_PERIODIC_INT_LEVEL_EVERY_MONTH KEYWORD1
RTC_ALARM_WEEKDAYS_NONE KEYWORD1
RTC_ALARM_WEEKDAYS_MON KEYWORD1
RTC_ALARM_WEEKDAYS_TUE KEYWORD1
RTC_ALARM_WEEKDAYS_WED KEYWORD1
RTC_ALARM_WEEKDAYS_THU KEYWORD1
RTC_ALARM_WEEKDAYS_FRI KEYWORD1
RTC_ALARM_WEEKDAYS_SAT KEYWORD1
RTC_ALARM_WEEKDAYS_SUN KEYWORD1
RTC_ALARM_WEEKDAYS_MON_TO_FRI KEYWORD1
RTC_ALARM_WEEKDAYS_SAT_TO_SUN KEYWORD1
RTC_ALARM_WEEKDAYS_ALL KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
setDateTime KEYWORD2
getDateTime KEYWORD2
setAlarmTime KEYWORD2
getAlarmTime KEYWORD2
enableAlarmInterrupt KEYWORD2
disableAlarmInterrupt KEYWORD2
resetAlarmInterrupt KEYWORD2
enableAlarmLED KEYWORD2
disableAlarmLED KEYWORD2
setPeriodicInterruptMode KEYWORD2
enablePeriodicInterrupt KEYWORD2
disablePeriodicInterrupt KEYWORD2
resetPeriodicInterrupt KEYWORD2
enablePeriodicInterruptLED KEYWORD2
disablePeriodicInterruptLED KEYWORD2
enableDCF77Reception KEYWORD2
disableDCF77Reception KEYWORD2
enableDCF77Interrupt KEYWORD2
disableDCF77Interrupt KEYWORD2
resetDCF77Interrupt KEYWORD2
enableDCF77LED KEYWORD2
disableDCF77LED KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
RTC_DCF KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################