$crystal = 3686400 $regfile = "m8def.dat" Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2 Config Pinb.2 = Input Config Pinb.1 = Output ' Set Portb.1 'will set the MS bit to +5V Verzögerung Pollin-DCF Waitms 1250 Reset Portb.1 ' Wert des Prescaler durch Testen ermittelt. 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 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 Laenge 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 ' Checker = 0 : Start ' Checker = 1 : Aktuelle Messung nicht erfolgreich ' Checker = 2 : Daten schenen in Ordnung zu sein Config Int0 = Falling '-> bei negiertem DCF-Signal, 'sonst Config Int0 = Rising !!! Enable Interrupts Enable Int0 Enable Timer0 'enable the interrupt On Int0 Zaehle Nosave On Ovf0 Tim0_isr 'Überlauf alle 10ms Cls Cursor Off Lcd "-- --.--.-- --:--:--" ' Display bei Start Do 'endless loop nop Loop End 'end program ' Routine zaehlt Sekunden und wertet Impuls- und Pausenzeit aus. Zaehle: 'Für Debug eingebaut: (zeigt Impuls und Pausenlänge) Locate 2 , 1 : Lcd "Imp: " ; Impuls Locate 2 , 10 : Lcd "Pau: " ; Pause Incr Sekunde If Sekunde > 18 Then K = Sekunde - 18 If Impuls > 17 Then Minute(k) = 1 Else Minute(k) = 0 End If End If Locate 1 , 19 Wert = Makebcd(sekunde) ' Umweg ueber BCD, dann fuehrende 0 Lcd Bcd(wert) ' Sekunde anzeigen If Pause < 300 And Pause > 200 Then 'Minutenanfang If Checker = 0 Then ' Checker-Flag setzen Checker = 1 Else Checker = 2 Gosub Check_parity End If Sekunde = 0 ' Sekunde 0 setzen Locate 1 , 19 Lcd "00" ' und anzeigen End If If Checker = 2 Then Gosub Dekoder Checker = 1 End If Impuls = 0 Pause = 0 Return ' Timer incrementiert die Zaehler Tim0_isr: Load Timer0 , Startwert If Pinb.2 = 0 Then Incr Impuls Set Portb.2 Else Incr Pause Reset Portb.2 End If Return ' Ueberprufung der empfangenen Daten Check_parity: Locate 4 , 1 Lcd Sekunde ' Debug-Ausgabe bei schlechtem Empfaenger ' Stimmt die Zahl der Sekunden? If Sekunde <> 59 Then Checker = 1 End If 'pruefe Minutenparitaet Paritaet = 0 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 'pruefe Stundenparitaet For I = 12 To 17 Paritaet = Paritaet + Minute(i) Next I Paritaet = Paritaet And 1 If Paritaet <> Minute(18) Then Checker = 1 End If 'Lcd Checker 'pruefe Rest Paritaet = 0 For I = 19 To 40 Paritaet = Paritaet + Minute(i) Next I Paritaet = Paritaet And 1 If Paritaet <> Minute(41) Then Checker = 1 End If 'Lcd Checker Return ' Daten im Minuten-Array dekodieren und ausgeben. Dekoder: ' Schleife, weil kompakter For K = 1 To 6 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 ' Wochentag aus String schneiden. K = Minute(25) * 2 K = K - 1 Temp = Mid(wochentag , K , 2) ' Raus damit, aufs LCD Locate 1 , 1 Lcd Temp ; " " ; Bcd(minute(19)) ; "." ; Bcd(minute(28)) ; "." ; Bcd(minute(33)) Lcd " " ; Bcd(minute(12)) ; ":" ; Bcd(minute(4)) Return