333 lines
7.8 KiB
C++
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
|
|
|
|
}
|