Files
Funkuhr/Uhr_DCF77_5Volt_V3.ino

333 lines
7.8 KiB
C++

/* Programm zum DCF77 Empfang für atmega 328p
Sekunden Timer ISR
5 Volt Variante für Peripherie
Datenempfang vom Coprozessor
19.05.2025
*/
#define bcdA 5 // D5
#define bcdB 6 // D6
#define bcdC 7 // D7
#define bcdD 8 // D8
#define displayPosition1 9 // D9
#define displayPosition2 10 // D10
#define displayPosition3 3 // D3
#define displayPosition4 4 // D4
byte selectZiffer = 0;
byte displayPosition = 0;
volatile byte noSignalMinutenCounter = 0;
volatile byte noSignalStundenCounter = 0;
volatile byte einerStunden = 7;
volatile byte zehnerStunden = 1;
volatile byte einerMinuten = 0;
volatile byte zehnerMinuten = 1;
volatile byte offlineCounter = 0;
void setup() {
pinMode(bcdA, OUTPUT);
pinMode(bcdB, OUTPUT);
pinMode(bcdC, OUTPUT);
pinMode(bcdD, OUTPUT);
pinMode(displayPosition1, OUTPUT);
pinMode(displayPosition2, OUTPUT);
pinMode(displayPosition3, OUTPUT);
pinMode(displayPosition4, OUTPUT);
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, HIGH);
digitalWrite(bcdC, HIGH);
digitalWrite(bcdD, HIGH);
digitalWrite(displayPosition1, HIGH);
digitalWrite(displayPosition2, HIGH);
digitalWrite(displayPosition3, HIGH);
digitalWrite(displayPosition4, HIGH);
Serial.begin(9600);
delay(100);
// Timer1 setzen (1 Sekunde = 49911, zwei Sekunden = 34286)
TCCR1A = 0x00;
TCCR1B = (1 << CS12) | (1 << CS10);
TIMSK1 = (1 << TOIE1);
TCNT1 = 49911;
}
ISR(TIMER1_OVF_vect) {
TCNT1 = 49911;
offlineCounter++;
if (offlineCounter > 59) {
offlineCounter = 0;
/***********************************************************************
Die einzelnen Ziffern der vier Variablen werden in
dekadische Zahlen umgewandelt, damit sie vom lokalen
Minutentakt weiter gezählt werden können
***********************************************************************/
byte m = zehnerMinuten * 10;
noSignalMinutenCounter = m + einerMinuten;
byte s = zehnerStunden * 10;
noSignalStundenCounter = s + einerStunden;
noSignalMinutenCounter++;
if (noSignalMinutenCounter > 59) {
noSignalMinutenCounter = 0;
noSignalStundenCounter++;
if (noSignalStundenCounter > 23) {
noSignalStundenCounter = 0;
}
}
/***********************************************************************
zerlegt die dekadische Zahl wieder in einzelne Ziffern
für die Anzeige
**********************************************************************/
einerStunden = noSignalStundenCounter % 10;
zehnerStunden = (noSignalStundenCounter / 10) % 10;
einerMinuten = noSignalMinutenCounter % 10;
zehnerMinuten = (noSignalMinutenCounter / 10) % 10;
}
}
void initDisplay() {
// Die Schleife ruft nacheinander die Anzeigestellen auf und übergibt die Ziffern
for (displayPosition = 1; displayPosition <= 4; displayPosition++) {
if (displayPosition == 1) {
digitalWrite(displayPosition1, HIGH);
digitalWrite(displayPosition2, LOW);
digitalWrite(displayPosition3, LOW);
digitalWrite(displayPosition4, LOW);
if (zehnerStunden == 0) {
selectZiffer = 0;
}
if (zehnerStunden == 1) {
selectZiffer = 1;
}
if (zehnerStunden == 2) {
selectZiffer = 2;
}
}
if (displayPosition == 2) {
digitalWrite(displayPosition1, LOW);
digitalWrite(displayPosition2, HIGH);
digitalWrite(displayPosition3, LOW);
digitalWrite(displayPosition4, LOW);
if (einerStunden == 0) {
selectZiffer = 0;
}
if (einerStunden == 1) {
selectZiffer = 1;
}
if (einerStunden == 2) {
selectZiffer = 2;
}
if (einerStunden == 3) {
selectZiffer = 3;
}
if (einerStunden == 4) {
selectZiffer = 4;
}
if (einerStunden == 5) {
selectZiffer = 5;
}
if (einerStunden == 6) {
selectZiffer = 6;
}
if (einerStunden == 7) {
selectZiffer = 7;
}
if (einerStunden == 8) {
selectZiffer = 8;
}
if (einerStunden == 9) {
selectZiffer = 9;
}
}
if (displayPosition == 3) {
digitalWrite(displayPosition1, LOW);
digitalWrite(displayPosition2, LOW);
digitalWrite(displayPosition3, HIGH);
digitalWrite(displayPosition4, LOW);
if (zehnerMinuten == 0) {
selectZiffer = 0;
}
if (zehnerMinuten == 1) {
selectZiffer = 1;
}
if (zehnerMinuten == 2) {
selectZiffer = 2;
}
if (zehnerMinuten == 3) {
selectZiffer = 3;
}
if (zehnerMinuten == 4) {
selectZiffer = 4;
}
if (zehnerMinuten == 5) {
selectZiffer = 5;
}
}
if (displayPosition == 4) {
digitalWrite(displayPosition1, LOW);
digitalWrite(displayPosition2, LOW);
digitalWrite(displayPosition3, LOW);
digitalWrite(displayPosition4, HIGH);
if (einerMinuten == 0) {
selectZiffer = 0;
}
if (einerMinuten == 1) {
selectZiffer = 1;
}
if (einerMinuten == 2) {
selectZiffer = 2;
}
if (einerMinuten == 3) {
selectZiffer = 3;
}
if (einerMinuten == 4) {
selectZiffer = 4;
}
if (einerMinuten == 5) {
selectZiffer = 5;
}
if (einerMinuten == 6) {
selectZiffer = 6;
}
if (einerMinuten == 7) {
selectZiffer = 7;
}
if (einerMinuten == 8) {
selectZiffer = 8;
}
if (einerMinuten == 9) {
selectZiffer = 9;
}
}
// BCD Zifferncode
switch (selectZiffer) {
case 0:
digitalWrite(bcdA, LOW);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, LOW);
break;
case 1:
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, LOW);
break;
case 2:
digitalWrite(bcdA, LOW);
digitalWrite(bcdB, HIGH);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, LOW);
break;
case 3:
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, HIGH);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, LOW);
break;
case 4:
digitalWrite(bcdA, LOW);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, HIGH);
digitalWrite(bcdD, LOW);
break;
case 5:
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, HIGH);
digitalWrite(bcdD, LOW);
break;
case 6:
digitalWrite(bcdA, LOW);
digitalWrite(bcdB, HIGH);
digitalWrite(bcdC, HIGH);
digitalWrite(bcdD, LOW);
break;
case 7:
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, HIGH);
digitalWrite(bcdC, HIGH);
digitalWrite(bcdD, LOW);
break;
case 8:
digitalWrite(bcdA, LOW);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, HIGH);
break;
case 9:
digitalWrite(bcdA, HIGH);
digitalWrite(bcdB, LOW);
digitalWrite(bcdC, LOW);
digitalWrite(bcdD, HIGH);
break;
}
// Unterdrueckung der fuehrenden Null
if (displayPosition == 1) {
if (selectZiffer == 0) {
goto noTime;
}
}
delayMicroseconds(2500); //Anschaltzeit der Ziffern
noTime: {}
}
}
void loop() {
if (Serial.available()) {
zehnerStunden = Serial.parseInt();
einerStunden = Serial.parseInt();
zehnerMinuten = Serial.parseInt();
einerMinuten = Serial.parseInt();
String(DCFzeit) = Serial.readString();
}
initDisplay(); // zeigt die Uhrzeit an
}