Files
Funkuhr/Uhr_DCF77_5Volt_V3.ino
cederbach 055f270397 In der Variante 3 hat die Funkuhr zwei Controller,
einen für die flimmerfreie Anzeige und einen für
die störungsfreie Erfassung des DCF Signals.
Die Datenübertragung erfolg seriell von TX nach RX
2025-05-03 18:14:09 +02:00

334 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
03.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 int dcf77MinuteEiner = 0;
volatile int dcf77MinuteZehner = 0;
volatile int dcf77HourEiner = 0;
volatile int dcf77HourZehner = 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;
volatile bool parityStat = 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);
// 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;
if (parityStat == 0) {
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;
}
}
einerStunden = noSignalStundenCounter % 10; // zerlegt die Zahl in Einer
zehnerStunden = (noSignalStundenCounter / 10) % 10; // und Zehner
einerMinuten = noSignalMinutenCounter % 10;
zehnerMinuten = (noSignalMinutenCounter / 10) % 10;
}
else {
einerMinuten = dcf77MinuteEiner;
zehnerMinuten = dcf77MinuteZehner;
einerStunden = dcf77HourEiner;
zehnerStunden = dcf77HourZehner;
parityStat = 0;
}
}
}
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()){
dcf77HourZehner = Serial.parseInt();
dcf77HourEiner = Serial.parseInt();
dcf77MinuteZehner = Serial.parseInt();
dcf77MinuteEiner = Serial.parseInt();
String(DCFzeit) = Serial.readString();
parityStat = 1;
}
initDisplay(); // zeigt die Uhrzeit an
}