Code:
'*******************************************************************************
'* DCF77 - 7 Segment Uhr mit Anzeige-Platine CD 4094, dadurch das die
'* 8 register des CD 4094 nicht mit Register 1 mit Segment A und Reg 2
'* mit Segment b usw verbunden sind, muss mit der Code angepaast werden
'*
'* Die Steckerbelegung ist wie folgt
'* Pin1=Plus, Pin2=Minus, Pin3=Enabel Output, Pin4=Strobe, Pin5=Takt, Pin6=Daten
'*
'* Erstellt am 17.02.2008 durch Mike Köppl
'* Bascom: 1.11.9.0.
'*******************************************************************************
$crystal = 4000000
$regfile = "m8def.dat"
$framesize = 128
Config Pind.2 = Input
Config Pind.5 = Output
Set Portd.2
Set Portd.5
Config Timer0 = Timer , Prescale = 256 '4000000 / 256 = 15625 Hz
Const Startwert = 100 'Überlauf 256 - Startwert 100 = 156 ( 15625 Hz / 156 = 100,1 Hz ) => 10ms
Load Timer0 , Startwert
Dim Zahl As Byte
Dim Minute1 As Byte
Dim B1 As Byte
Dim A As Word
Dim B As Word
Dim C As Word
Dim Count As Byte
Dim I As Byte
Dim J As Byte
Dim K As Byte
Dim Impuls As Byte
Dim Pause As Integer
Dim Sekunde As Byte
Dim Wert As Byte
Dim Paritaet As Byte
Dim Checker As Byte
Dim Wochentag As String * 14
Dim Temp As String * 2
Wochentag = "MoDiMiDoFrSaSo" ' String mit Kuerzel der Wochentage
Dim Werte_bit(6) As Byte
Dim Werte_start(6) As Byte
Dim Minute(42) As Byte ' Enthaelt die Sekunden-Impulse 0 und 1
'**** Arrays für Startposition und Länge der Daten im Array Minute() **********
Werte_start(1) = 4 'Minuten
Werte_bit(1) = 6
Werte_start(2) = 12 'Stunden
Werte_bit(2) = 5
Werte_start(3) = 19 'Tag
Werte_bit(3) = 5
Werte_start(4) = 25 'Wochentag
Werte_bit(4) = 2
Werte_start(5) = 28 'Monat
Werte_bit(5) = 4
Werte_start(6) = 33 'Jahr
Werte_bit(6) = 7
Impuls = 0
Pause = 0
Sekunde = 0
Checker = 0
Config Int0 = Rising
Enable Interrupts
Enable Int0
Enable Timer0 'enable the interrupt
On Int0 Zaehle Nosave
On Ovf0 Tim0_isr
'*******************************************************************************
Do
nop
Loop
End
'*******************************************************************************
'***** Routine zählt Sekunden und wertet Impuls- und Pausenzeit aus ***********
Zaehle:
Disable Interrupts
Stop Timer0
If Pind.2 = 1 Then ' Pruefen, ob Signal 0 oder 1. 0=aktiv
Set Portd.5
Incr Sekunde
If Sekunde > 18 Then
K = Sekunde - 18
If Impuls > 10 Then
Minute(k) = 1
Else
Minute(k) = 0
End If
End If
Config Int0 = Falling ' Interrupt regiert auf fallende Flanke
Else
Wert = Makebcd(sekunde) ' Umweg ueber BCD, dann fuehrende 0
Reset Portd.5
If Pause > 100 Then ' Wenn die Pause groesser 100 war, dann wars der Minutentrenner
If Checker = 0 Then ' Checker-Flag setzen
Checker = 1
Else
Checker = 2
Gosub Check_parity
End If
Sekunde = 0 ' Sekunde 0 setzen
End If
Config Int0 = Rising
If Checker = 2 Then ' wenn Daten korrekt scheinen, dann Dekodieren und Anzeigen
Gosub Dekoder
Checker = 1
End If
End If
Start Timer0
Enable Interrupts
Impuls = 0
Pause = 0
Return
'*******************************************************************************
Tim0_isr: ' Timer incrementiert die Zaehler
Incr Impuls
Incr Pause
Return
'*******************************************************************************
Check_parity: ' Ueberprufung der empfangenen Daten
If Sekunde <> 59 Then ' Stimmt die Zahl der Sekunden?
Checker = 1
End If
Paritaet = 0 'pruefe Minutenparitaet
For I = 4 To 10
Paritaet = Paritaet + Minute(i)
Next I
Paritaet = Paritaet And 1
If Paritaet <> Minute(11) Then
Checker = 1
End If
Paritaet = 0
For I = 12 To 17 'pruefe Stundenparitaet
Paritaet = Paritaet + Minute(i)
Next I
Paritaet = Paritaet And 1
If Paritaet <> Minute(18) Then
Checker = 1
End If
Paritaet = 0
For I = 19 To 40 'pruefe Rest
Paritaet = Paritaet + Minute(i)
Next I
Paritaet = Paritaet And 1
If Paritaet <> Minute(41) Then
Checker = 1
End If
Return
'*******************************************************************************
Dekoder: ' Daten im Minuten-Array dekodieren und ausgeben.
For K = 1 To 6 ' Schleife, weil kompakter
Wert = 0
J = Werte_start(k) + Werte_bit(k)
For I = J To Werte_start(k) Step -1
Shift Wert , Left
Wert = Wert + Minute(i)
Next I
J = Werte_start(k)
Minute(j) = Wert
Next K
K = Minute(25) * 2 ' Wochentag aus String schneiden.
K = K - 1
Temp = Mid(wochentag , K , 2)
'*******************************************************************************
'********* Minutenauswertung und Umwandlung ************************************
Minute1 = Bcd(minute(4))
Minute1 = Makedec(minute(4))
A = Minute1 / 10
B = A * 10
C = Minute1 - B
Zahl = C
Gosub Zahlendaten
Shiftout Portb.0 , Portb.1 , B1 , 1 , 8 , 1
Zahl = A
Gosub Zahlendaten
Shiftout Portb.0 , Portb.1 , B1 , 1 , 8 , 1
'*******************************************************************************
'******* Stundenauswertung und Umwandlung ***************************************
Minute1 = Bcd(minute(12))
Minute1 = Makedec(minute(12))
A = Minute1 / 10
B = A * 10
C = Minute1 - B
Zahl = C
Gosub Zahlendaten
Shiftout Portb.0 , Portb.1 , B1 , 1 , 8 , 1
Zahl = A
Gosub Zahlendaten
Shiftout Portb.0 , Portb.1 , B1 , 1 , 8 , 1
Reset Portb.2
Waitms 10
Set Portb.2
Return
'*******************************************************************************
'**** Daten der Zahlendarstellung Zahlen aussuchen *****************************
Zahlendaten:
Restore Dta1
For Count = 0 To Zahl
Read B1
Next
Return
'***** Zahlen Darstellungsdaten ***********************************************
Dta1:
Data &B00001010 , &B00111111 , &B10101000 , &B00111000 , &B00011101 , &B01011000 , '0,1,2,3,4,5
Data &B01001000 , &B00111110 , &B00001000 , &B00011000 , &B11111111 , &B11110111 , 0, '6,7,8,9,alles-aus,d-punkt
Lesezeichen