Advertisement  

Monday, 26 June 2017
     
 
Main Menu
Home Home
Shop Shop
News News
BASCOM-AVR BASCOM-AVR
BASCOM-8051 BASCOM-8051
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-AVR Help BASCOM-AVR Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login
Username

Password

If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News
 
     
 

 
   
     
 
AN #43 - DCF-77 clock Print
DCF-77 clock

This application note was submitted by Roman Foltyn. The comment is in German.

Download source code


'---------------------------------------------------------------------------------------------------------
' (c) 2001 Roman Foltyn 29.12.2001
'---------------------------------------------------------------------------------------------------------
' DCF1.BAS Version 1.01
' DCF-77 Signal auf INT1 Pin 13 (P3.3) Impulse Low Activ [Conrad Empfänger + Inverter]
' Port 3.7 Low => Piepser ein (Volle stunde Pipser) 5 pipse letzte bei 00:00 lang 0.3 sek
'---------------------------------------------------------------------------------------------------------
'
' V1.01 3.01.2002 10ms Zähler koriegiert 0.99 sek zum 1s ,softwate uhr variable initialisiert
' Bei keine DCF signall nach 2,5 sek XTL meldung Beide DCF Zähler begrenz bis 250
'  Wenn keine DCF empfang parity war auch OK jetz wen kalender werte=0 dan auch keine synchro
' Fehler bei KW1 (negative Temp2) Beseitigt.
'---------------------------------------------------------------------------------------------------------
$crystal = 11059200
$large
Config Lcd = 16 * 2 'configure lcd display
Cursor Off

'---- Software Uhr Variablen -----------------------------------------------------------------------------
Dim Shsek As Byte , Ssek As Byte , Smin As Byte , Sstd As Byte , Etag As Byte
Dim Stag As Byte , Swta As Byte , Smon As Byte , Sjah As Byte

'---- DCF77 Dekoder Variablen ----------------------------------------------------------------------------
Dim Pointer As Byte , Dmin As Byte , Dstd As Byte, 'DCF Variable
Dim Dtag As Byte , Dwta As Byte , Dmon As Byte , Djah As Byte

Dim Dcf(60) As Byte 'array für dcf empfangene impulse
Dim Dcfs As Byte 'Variable für zeit zwischen zwei impulse von DCF empfänger
Dim Dcfl As Byte 'Variable für DCF impuls dauer in 10ms schritten

Dim Dcferm As Byte  'Parity error minuten
Dim Dcfers As Byte 'Parity error stunden
Dim Dcferd As Byte 'Parity errordatum
Dim Dcferr As Byte  'Parity error Globall

Dim I As Byte 'diverse temporare variablen
Dim Temp1 As Byte
Dim Wert As Byte
Dim Par As Byte

'--- Speicher NUR FÜR Piepstone - ---------------------------------------------------------------------
Dim Pipsen As Byte 'merker für erzeugte pipston - eliminiert doppel ton bei DCF synchronisation

'--- Speicher NUR FÜR KW und Jahrestag BERECHNUNG --------------------------------------------------------
Dim Jtag As Integer , Schalt As Byte
Dim Temp2 As Integer
Dim Temp3 As Integer
Dim Temp4 As Byte
Dim Kw As Byte
'---------------------------------------------------------------------------------------------------------
'---------------------------------------------------------------------------------------------------------

Dcf
(0) = 1 'Variablen initialisierung
Dcf
(10) = 0
Dcf
(20) = 1
Pointer
= 0
Dcferr
= 1
Shsek
= 0
Ssek
= 0
Smin
= 0
Sstd
= 0
Swta
= 0
Stag
= 0
Smon
= 0
Sjah
= 0

'Interrupt Configuration ---------------------------------------------------------------------------------

Config Timer2 = Timer , Gate = Internal , Mode = 0 'Reload 16 Bit Modus
On Int1 Int1_int
Set Tcon.2 'flanken steuerung
On Timer2 Timer_2_int
Load Timer2 , 9216 '9216 für 11.0592MHz 10 mS takt (Xtal/12/9216=>10ms)
Enable Interrupts 'enable interrupt
Enable Int1 'enable int1
Enable Timer2  'enable timer2
Priority Set Timer2 'highest priority
Start Timer2 'Timer starten



'#########################################################################################################
'--- Programm Anfang -------------------------------------------------------------------------------------
'#########################################################################################################

Cls
Upperline
Lcd "DCF-77 UHR V1.01"
Lowerline
Lcd "(c) Roman Foltyn"
Wait 2

'____ Hauptprogramm ______________________________________________________________________________________

 
Do
 
If Shsek = 0 Then Gosub Displayuhr  'einmall pro sekunde ausgabe auf display
 
Loop

End


'#########################################################################################################
'Unterprogramme _-----------------------------------------------------------------------------------------
'Timer 2 Interrupt Routine (10ms) ------------------------------------------------------------------------
'bearbeitubgs zeit bei volle minute 1,13ms bei jede aufruf 140µs
'---------------------------------------------------------------------------------------------------------

Timer_2_int
:

Incr Dcfs
If Dcfs > 250 Then Dcfs = 250 'Zähler begrenzen bis 250
If P3.3 = 0 Then Incr Dcfl 'Dcfl impuls Länge zahler in 10ms step
If Dcfl > 250 Then Dcfl = 250 'Zähler begrenzen bis 250

'---- Software Uhr ---------------------------------------------------------------------------------------

Incr Shsek  '10 ms addieren

If Shsek = 100 Then 'und bei 1 sekunde ssek addieren
 Shsek
= 0
 
Incr Ssek
End If

If Ssek = 60 Then
 Ssek
= 0
 
Incr Smin
End If

If Smin = 60 Then
 Smin
= 0
 
Incr Sstd
End If

If Sstd = 24 Then
 Sstd
= 0
 
Incr Stag
 
Incr Swta
End If

Etag
= 32 'berechnung monat ende für softuhr
Schalt
= Sjah Mod 4

If Smon = 2 Then 'Februar bei schaltjahr berechnen
 
If Schalt = 0 Then
 Etag
= 30
 
Else
 Etag
= 29
 
End If
End If

If Smon = 2 Then Etag = 29
If Smon = 4 Then Etag = 31
If Smon = 6 Then Etag = 31
If Smon = 9 Then Etag = 31
If Smon = 11 Then Etag = 31

If Stag = Etag Then
 Stag
= 1
 
Incr Smon
End If

If Smon = 13 Then
 Smon
= 1
 
Incr Sjah
End If

'-- ACHTUNG NECHSTE ROUTINEN (JAHRESTAG-, KW-, UND PIEPSTONE ROUTINEN) KÖNNEN ENTFÄLEN ! ---------------

'-------------------------------------------------------------------------------------------------------
'---- Berechnung jahrestages und KW (bei keine synchronisation Jtag=0)----------------------------------
'-------------------------------------------------------------------------------------------------------

If Ssek = 0 Then
 
If Schalt = 0 Then '31.29.31.30.31.30.31.31.30.31.30.31

 
If Smon = 1 Then Jtag = Stag '0
 
If Smon = 2 Then Jtag = 31 + Stag '31
 
If Smon = 3 Then Jtag = 60 + Stag '31.29.
 
If Smon = 4 Then Jtag = 91 + Stag '31.29.31.
 
If Smon = 5 Then Jtag = 121 + Stag '31.29.31.30.
 
If Smon = 6 Then Jtag = 152 + Stag  '31.29.31.30.31.
 
If Smon = 7 Then Jtag = 182 + Stag '31.29.31.30.31.30.
 
If Smon = 8 Then Jtag = 213 + Stag '31.29.31.30.31.30.31.
 
If Smon = 9 Then Jtag = 244 + Stag '31.29.31.30.31.30.31.31
 
If Smon = 10 Then Jtag = 274 + Stag '31.29.31.30.31.30.31.31.30.
 
If Smon = 11 Then Jtag = 305 + Stag '31.29.31.30.31.30.31.31.30.31.
 
If Smon = 12 Then Jtag = 335 + Stag '31.29.31.30.31.30.31.31.30.31.30.

 
Else

 
If Smon = 1 Then Jtag = Stag '0
 
If Smon = 2 Then Jtag = 31 + Stag '31
 
If Smon = 3 Then Jtag = 59 + Stag '31.28.
 
If Smon = 4 Then Jtag = 90 + Stag '31.28.31.
 
If Smon = 5 Then Jtag = 120 + Stag '31.28.31.30.
 
If Smon = 6 Then Jtag = 151 + Stag '31.28.31.30.31.
 
If Smon = 7 Then Jtag = 181 + Stag '31.28.31.30.31.30.
 
If Smon = 8 Then Jtag = 212 + Stag '31.28.31.30.31.30.31.
 
If Smon = 9 Then Jtag = 243 + Stag '31.28.31.30.31.30.31.31
 
If Smon = 10 Then Jtag = 273 + Stag '31.28.31.30.31.30.31.31.30.
 
If Smon = 11 Then Jtag = 304 + Stag '31.28.31.30.31.30.31.31.30.31.
 
If Smon = 12 Then Jtag = 334 + Stag  '31.28.31.30.31.30.31.31.30.31.30.

 
End If

 Temp2
= Jtag - Swta
 
If Temp2 < 0 Then Temp2 = 0 'Bei negativen werten problemm
 Temp3
= Temp2 / 7 'Volle wochen seit jahres anfang
 Kw
= Temp3
 Temp3
= Temp3 * 7 'genaue tagesanzahl für volle wochen
 Temp4
= Temp2 - Temp3 'Tage in erste KW neues jahr (>4) oder letzte KW altes jahr (<5)

 
If Temp4 > 4 Then 'wenn tages in jahresanfangswoche >4 dann erste KW in neue Jahr
 Kw
= Kw + 2 'addieren erste woche und aktuelle woche
 
End If

 
If Temp4 < 5 Then 'wenn Tages in jahresanfangswoche <5 dann alle diese tage in letzte KW altes Jahr
 Kw
= Kw + 1
 
End If

 
If Schalt = 0 Then
 Temp2
= Jtag - Swta 'wenn in altes jahr letzte woche noch bis mittwoch dann 1 KW
 
If Temp2 > 362 Then Kw = 1
 
Else
 Temp2
= Jtag - Swta 'wenn in altes jahr letzte woche noch bis mittwoch dann 1 KW
 
If Temp2 > 361 Then Kw = 1 'letzte Jahres tage können auch in neue Jahr 1 woche eintretten
 
End If
End If

'Jtag => Jahrestag ab Jahresanfang
'Kw => Berechnete KW (Kalender Woche)

'---------------------------------------------------------------------------------------------------------
'--- PIPSTONE BEI VOLLE STUNDE 56 bis 59 Kurz und bei 00 Lang -------------------------------------------
'---------------------------------------------------------------------------------------------------------

If Ssek > 55 And Ssek < 60 Or Ssek = 0 Then
 
If Ssek = 0 Then
 
If Smin = 0 Then
 
If Shsek > 0 And Shsek < 30 Then
 
If Pipsen = 0 Then
 P3
.7 = 0
 Pipsen
= 1 'blokiert null sekunden piepsen (Bei DCF übernahme)
 
End If
 
Else
 P3
.7 = 1
 
End If
 
End If
 
Else
 
If Smin = 59 Then
 
If Shsek > 0 And Shsek < 10 Then
 P3
.7 = 0
 Pipsen
= 0  'schaltet null skunden piepsen wieder an
 
Else
 P3
.7 = 1
 
End If
 
End If
 
End If
Else
 P3
.7 = 1 'Bei andere falle Piepston abschalten
End If

'---------------------------------------------------------------------------------------------------------

Return

'---------------------------------------------------------------------------------------------------------
'---- Interrupt1 Routine (DCF77 Empfanger INPUT LOW=>125 bis131ms INPUT HIGH=>227 bis 229ms --------------
'---- Interrupt Dauer 51 µs und bei DCF Decodieren (Volle minute) 8,5ms ----------------------------------
'---------------------------------------------------------------------------------------------------------

Int1_int
:

If Dcfs < 202 And Dcfs > 196 Then 'Minutensprung finden und DCF Dekodieren
 
'ACHTUNG bei andere empfänger eventuell anpassen
 
If Dcfl > 17 Then 'Signall low oder high in DCF Array speichern
 Dcf
(60) = 1 'wert von parity Date "58"bit noch speichern
 
Else
 Dcf
(60) = 0
 
End If
 Shsek
= 0
 Ssek
= 0
 
Gosub Dcfdecode 'DCF signall decodieren
 Pointer
= 0
End If

Incr Pointer

 
'Kleiner 170ms => LOW Grösser 170ms => High
If Dcfl > 17 Then 'Signall low oder high in DCF Array speichern
 Dcf
(pointer) = 1
Else
 Dcf
(pointer) = 0
End If

Dcfs
= 0
Dcfl
= 0

Return

'---------------------------------------------------------------------------------------------------------
'--- DCF77 DEKODIER SOFTWARE ----------------------------------------------------------------------------
'---------------------------------------------------------------------------------------------------------

Dcfdecode
:

Dmin
= 0 'DCF minuten info
Dstd
= 0 'DCF Stunden info
Dtag
= 0  'DCF Tag info
Dwta
= 0 'DCF Wochen Tag info
Dmon
= 0 'DCF Monat info
Djah
= 0  'DCF Jahr info

Dcferm
= 0 'Minuten Patity error löschen
Dcfers
= 0 'Stunden Patity error löschen
Dcferd
= 0  'Datum Patity error löschen

Par
= 0 'Parity=0
For I = 1 To 8 'scann Array für minuten
 Pointer
= I + 22
 
If Dcf(pointer) = 1 Then

 
If I = 1 Then
 Dmin
= Dmin + 1
 Par
= Par + 1
 
End If

 
If I = 2 Then
 Dmin
= Dmin + 2
 Par
= Par + 1
 
End If

 
If I = 3 Then
 Dmin
= Dmin + 4
 Par
= Par + 1
 
End If

 
If I = 4 Then
 Dmin
= Dmin + 8
 Par
= Par + 1
 
End If

 
If I = 5 Then
 Dmin
= Dmin + 10
 Par
= Par + 1
 
End If

 
If I = 6 Then
 Dmin
= Dmin + 20
 Par
= Par + 1
 
End If

 
If I = 7 Then
 Dmin
= Dmin + 40
 Par
= Par + 1
 
End If

 
If I = 8 Then
 Par
= Par + 1
 
End If

 
End If

 Dcferm
= Par Mod 2 'parity minuten test

Next I

Par
= 0
For I = 1 To 7 'scann Array für Stunden
 Pointer
= I + 30
 
If Dcf(pointer) = 1 Then

 
If I = 1 Then
 Dstd
= Dstd + 1
 Par
= Par + 1
 
End If

 
If I = 2 Then
 Dstd
= Dstd + 2
 Par
= Par + 1
 
End If

 
If I = 3 Then
 Dstd
= Dstd + 4
 Par
= Par + 1
 
End If

 
If I = 4 Then
 Dstd
= Dstd + 8
 Par
= Par + 1
 
End If

 
If I = 5 Then
 Dstd
= Dstd + 10
 Par
= Par + 1
 
End If

 
If I = 6 Then
 Dstd
= Dstd + 20
 Par
= Par + 1
 
End If

 
If I = 7 Then
 Par
= Par + 1
 
End If

 
End If

 Dcfers
= Par Mod 2 'parity stunden test

Next I

Par
= 0
For I = 1 To 23 'scann Array für Tag bis Jahr
 Pointer
= I + 37
 
If Dcf(pointer) = 1 Then

 
If I = 1 Then
 Dtag
= Dtag + 1
 Par
= Par + 1
 
End If

 
If I = 2 Then
 Dtag
= Dtag + 2
 Par
= Par + 1
 
End If

 
If I = 3 Then
 Dtag
= Dtag + 4
 Par
= Par + 1
 
End If

 
If I = 4 Then
 Dtag
= Dtag + 8
 Par
= Par + 1
 
End If

 
If I = 5 Then
 Dtag
= Dtag + 10
 Par
= Par + 1
 
End If

 
If I = 6 Then
 Dtag
= Dtag + 20
 Par
= Par + 1
 
End If

 
If I = 7 Then
 Dwta
= Dwta + 1
 Par
= Par + 1
 
End If

 
If I = 8 Then
 Dwta
= Dwta + 2
 Par
= Par + 1
 
End If

 
If I = 9 Then
 Dwta
= Dwta + 4
 Par
= Par + 1
 
End If

 
If I = 10 Then
 Dmon
= Dmon + 1
 Par
= Par + 1
 
End If

 
If I = 11 Then
 Dmon
= Dmon + 2
 Par
= Par + 1
  
End If

 
If I = 12 Then
 Dmon
= Dmon + 4
 Par
= Par + 1
 
End If

 
If I = 13 Then
 Dmon
= Dmon + 8
 Par
= Par + 1
 
End If

 
If I = 14 Then
 Dmon
= Dmon + 10
 Par
= Par + 1
 
End If

 
If I = 15 Then
 Djah
= Djah + 1
 Par
= Par + 1
 
End If

 
If I = 16 Then
 Djah
= Djah + 2
 Par
= Par + 1
 
End If

 
If I = 17 Then
 Djah
= Djah + 4
 Par
= Par + 1
 
End If

 
If I = 18 Then
 Djah
= Djah + 8
 Par
= Par + 1
 
End If

 
If I = 19 Then
 Djah
= Djah + 10
 Par
= Par + 1
 
End If

 
If I = 20 Then
 Djah
= Djah + 20
 Par
= Par + 1
 
End If

 
If I = 21 Then
 Djah
= Djah + 40
 Par
= Par + 1
 
End If

 
If I = 22 Then
 Djah
= Djah + 80
 Par
= Par + 1
 
End If

 
If I = 23 Then
 Par
= Par + 1
 
End If

 
End If

 Dcferd
= Par Mod 2 'parity test für letzte daten block

Next I
Dcferr
= Dcferm + Dcfers 'Globale Parity error erzeugen
Dcferr
= Dcferr + Dcferd

If Djah = 0 Then Return 'bei keine empfang parity ist auch OK aber
If Dwta = 0 Then Return 'DCF signall ist auch faisch
If Dmon = 0 Then Return
If Dtag = 0 Then Return

If Dcferr = 0 Then 'wenn daten ok dann softuhr setzen
 Shsek
= 0 '0.01s und sekunden synchronisieren
 Ssek
= 0
 Smin
= Dmin  'Alle DCF dekodierte werte in softuhr übernemen
 Sstd
= Dstd
 Stag
= Dtag
 Swta
= Dwta
 Smon
= Dmon
 Sjah
= Djah

End If
Return



'---------------------------------------------------------------------------------------------------------
'--- LCD DISPLAY ANZEIGE ROUTINE --- KANN DURCH USER BELIEBIG GEENDERT WERDEN ----------------------------
'---------------------------------------------------------------------------------------------------------

Displayuhr
:  'softuhr anzeigen

If Dcfs > 240 Then Dcferr = 1 'wenn keine impulse von DCF empfanger auch Parity error setzen

Upperline 'uhr zeit zeigen
 
If Sstd < 10 Then
 
Lcd "0" ; Sstd ; ":" ;
 
Else
 
Lcd Sstd ; ":" ;
 
End If

 
If Smin < 10 Then
 
Lcd "0" ; Smin ; ":" ;
 
Else
 
Lcd Smin ; ":" ;
 
End If

 
If Ssek < 10 Then
 
Lcd "0" ; Ssek ;
 
Else
 
Lcd Ssek ;
 
End If
 
'Wochentag decodieren
 
If Swta = 0 Then 'wenn noch keine daten dann Synchro
 
Lcd " SYNCHRO";
 
End If

 
If Swta = 1 Then
 
Lcd " MO";
 
End If

 
If Swta = 2 Then
 
Lcd " DI";
 
End If

 
If Swta = 3 Then
 
Lcd " MI";
 
End If

 
If Swta = 4 Then
 
Lcd " DO";
 
End If

 
If Swta = 5 Then
 
Lcd " FR";
 
End If

 
If Swta = 6 Then
 
Lcd " SA";
 
End If

 
If Swta = 7 Then
 
Lcd " SO";
 
End If

 
If Dcferr = 0 Then
Lcd " DCF "; 'DCF OK
Else
Lcd " XTL "; 'Wenn keine DCF synchro dann Quarz UHR Modus
End If

Lowerline

 
If Stag < 10 Then
 
Lcd "0" ; Stag ; "." ;
 
Else
 
Lcd Stag ; "." ;
 
End If

 
If Smon < 10 Then
 
Lcd "0" ; Smon ; "." ;
 
Else
 
Lcd Smon ; "." ;
 
End If

 
If Sjah < 10 Then
 
Lcd "200" ; Sjah ;
 
Else
 
Lcd "20" ; Sjah ;
 
End If

If Jtag > 0 Then
 
If Kw > 9 Then
 
Lcd " KW" ; Kw ;
 
Else
 
Lcd " KW0" ; Kw ;
 
End If
Else
 
Lcd " QUARZ"
End If

Return

'---------------------------------------------------------------------------------------------------------