/* 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 }