fb:porticula NoPaste
DCF-77 Auswertung in PowerBasic
Uploader: | Volta |
Datum/Zeit: | 07.11.2008 19:43:21 |
' Program Title: DCF77
' Signaldecodierung des Zeitzeichensenders DCF77
'
' Der Zeitzeichensender DCF77 in Mainflingen bei Frankfurt/Main
' sendet im L„ngstwellenbereich auf 77500Hz st„ndig die amtliche
' Uhrzeit der BRD aus. Diese Amtliche Uhrzeit wird aus einem
' Atomfrequenznormal in der Physikalisch-Technischen Bundesanstalt
' Braunschweig gewonnen. Gesendet wird zu jeder Sekunde ein
' l„ngencodierter Impuls durch absenken der Sendeleistung.
' In digitaler Form erh„lt man so innerhalb einer Minute 59 Bit,
' die decodiert Uhrzeit und Datum enthalten. Dauert ein Impuls
' 0,1sek. entspricht das der Bitinformation "0" , 0,2sek.
' entsprechen der "1". In der 59. Sekunde entf„llt der Impuls,
' dadurch wird das Ende der Datenbertragung und der Beginn
' der neuen Minute gekennzeichnet.
'
' Kodetabelle zum DCF77 - Signal
' Bit
' 1 - 15 Kennbit ("0" - Signal)
' 16 Betrieb mit Reserveantenne
' 17 Ankndigung eines Jahreszeitwechsels
' 18 Sommerzeit
' 19 Winterzeit
' 20 Ankndigung Schaltsekunde (1 Minute <> 60 Sekunden!)
' 21 Startbit ("1" - Signal)
' 22 - 59 (BCD kodiert)
' (Die Summe der Bit-Werte bei "1"-Signal errechnen)
' Bit Wert 1 2 4 8 10 20 40 80 Parit„tsbit
'
' Bit
' Minuten 22 23 24 25 26 27 28 29
' Stunden 30 31 32 33 34 35 36
' Tag 37 38 39 40 41 42
' Wochentag 43 44 45
' Monat 46 47 48 49 50
' Jahr 51 52 53 54 55 56 57 58 59
' (Jahr + 1900)
'
' 60 Pause zum Minutenwechsel
'
' Das folgende Programm wertet die Bits fr Sommer-/Winterzeit,
' Start, Minuten, Stunden, Tag, Monat, Jahr und Pause aus.
' Unbercksichtigt bleiben die Kennbit, Reserveantenne,
' Ankndigungen und Parit„tsbits.
DEFINT A - Z 'alle Variablen als Integer definieren
'In z() werden die Z„hltakte pro Sekundenimpuls gespeichert
DIM z( 60 )
SHARED tag, mon, jahr
SHARED std, minute
SHARED stdb, minb, som
SHARED tagb, monb, jahrb
SHARED schwelle
SHARED port%, mask%
'Auslesen der Taktz„hlers im BIOS-Datensegment (40:6CH)
FUNCTION TZeit%
DEF SEG = &H40
temp% = PEEKI( &H6C )
DEF SEG
TZeit% = temp%
END FUNCTION
'Auswerten der Sekundenz„hlung nach Uhrzeit, Datum in dezimalen Werten
FUNCTION DCFwert( a%, b% )
c% = 1
d% = 0
FOR i = a% TO a% + b% - 1
IF z( i ) > schwelle THEN d% = d% + c%
c% = c% + c%
IF c% = 16 THEN c% = 10
NEXT
DCFwert% = d%
END FUNCTION
'Auswerten der Sekundenz„hlung nach Uhrzeit, Datum in BCD-Werten
FUNCTION DCF2BCD( a%, b% )
c% = 1
d% = 0
FOR i = a% TO a% + b% - 1
IF z( i ) > schwelle THEN d% = d% + c%
c% = c% + c%
NEXT
DCF2BCD% = d%
END FUNCTION
SUB Synchron
Ti = TZeit%() + 6
'nur zur Synchronisation auf 1-Signal warten
WHILE Ti > TZeit%()
IF ( INP( port% ) AND mask% ) THEN EXIT LOOP
WEND
END SUB
SUB DCFSignal
SHARED trigger%, zaehler%, port%, mask%
'Maximal 1,2sek auf 0-Signal warten
trigger% = 0
Ti = TZeit%() + 21
WHILE Ti > TZeit%()
IF ( INP( port% ) AND mask% ) = 0 THEN
trigger% = 1
EXIT LOOP
END IF
WEND
zaehler% = 1
'Maximal 0,3sek die L„nge des Impulses z„hlen
Ti = TZeit%() + 6
WHILE Ti > TZeit%()
IF ( INP( port% ) AND mask% ) THEN EXIT LOOP
INCR zaehler%
'Eine Verz”gerung ist erst ab 386-Rechnern notwendig
' Verzoegern
WEND
END SUB
START4DCF77:
port% = &H379: mask% = &H20
'Prfen ob Signale vom DCF77-Baustein kommen
zaehler% = 0: trigger% = 0
CALL Synchron
temp = 0
FOR i = 1 TO 3
CALL DCFSignal
IF trigger% = 1 THEN INCR temp%
NEXT
IF temp% < 2 THEN
Fehler = 255
GOTO Labende
END IF
CLS
LOCATE 5, 14
PRINT "111111111122222222223333333333444444444455555555556"
LOCATE 6, 5
PRINT "123456789012345678901234567890123456789012345678901234567890"
LOCATE 7, 5
a$ = "/"
sekunde = 1
trigger% = 0
'Max. 2 Minuten auf eine komplette Zeit- und Datumsinformation warten
CALL Synchron
Tm = TZeit%() + 2200
WHILE TM > TZeit%()
CALL DCFSignal
z( sekunde ) = zaehler%
IF sekunde = 59 THEN EXIT LOOP 'wenn alle 59 Sekundenimpulse empfangen
'wurden die While-Schleife verlassen
IF trigger% = 0 THEN 'trigger%=0 bedeutet das eine Impulslcke >1.2sek
sekunde = 0 'erkannt wurde. Also beginnt eine Neue Minute.
temp% = ASC( a$ )
a$ = CHR$( temp% - 1 )
LOCATE 7, 5
END IF
PRINT a$;
INCR sekunde
WEND
Fehler = 0
IF sekunde < 59 THEN 'Sind innerhalb 2 Minuten 59 Impulse erkannt worden?
Fehler = 1
GOTO Labende
END IF
PRINT a$
'Auswertung
LOCATE 9, 1
Fehler = 0
eins = 0
null = z( 21 ) 'die 21 Sekunde sollte "1"-Signal haben
FOR i = 1 TO 59 'Suche Max. und Min. Taktimpulse
IF z( i ) > eins THEN eins = z( i ) 'Max. Taktimpulse "1" Signal
IF z( i ) < null THEN null = z( i ) 'Min. Taktimpulse "0" Signal
NEXT
schwelle = ( null + eins ) \ 2 'im Mittel liegt der Erkennungswert
IF schwelle > z( 21 ) THEN INCR Fehler 'das Startbit muá "1" sein.
som = - 1
IF Z( 18 ) > schwelle THEN
IF Z( 19 ) < schwelle THEN som = 1
ELSE
IF Z( 19 ) > schwelle THEN som = 0
END IF
IF som = - 1 THEN INCR Fehler
std = 0: minute = 0
tag = 0: mon = 0: jahr = 0
minute = DCFwert( 22, 7 )
std = DCFwert( 30, 6 )
tag = DCFwert( 37, 6 )
mon = DCFwert( 46, 5 )
jahr = DCFwert( 51, 8 ) + 1900
'sind Datum und Uhrzeit plausibel?
IF std > 24 THEN INCR Fehler
IF minute > 59 THEN INCR Fehler
IF tag > 31 THEN INCR Fehler
IF mon > 12 THEN INCR Fehler
PRINT "DCF77 Zeit: "; std; ":"; minute
PRINT " Datum: "; tag; "."; mon; "."; jahr
PRINT "PC-Uhrzeit: "; TIME$
PRINT " Datum: "; DATE$
IF Fehler > 0 THEN
INCR Fehler
GOTO Labende
END IF
minb = DCF2BCD( 22, 7 )
stdb = DCF2BCD( 30, 6 )
tagb = DCF2BCD( 37, 6 )
monb = DCF2BCD( 46, 5 )
jahrb = DCF2BCD( 51, 8 )
print stdb,minb
print tagb,monb,jahrb
Labende:
LOCATE 23, 1
IF Fehler = 0 THEN
PRINT "Zeit und Datum fehlerfrei ermittelt!";
ELSEIF Fehler = 1 THEN
PRINT "Impulse des DCF77-Empf„ngers nicht fehlerfrei!!";
ELSEIF Fehler < 8 THEN
PRINT "Unzul„ssige Werte fr Zeit und Datum!";
ELSEIF Fehler = 8 THEN
PRINT "Batterie fr interne Uhr leer?";
ELSEIF Fehler = 9 THEN
PRINT "? "
ELSEIF Fehler = 10 THEN
PRINT "?? "
ELSEIF Fehler = 255 THEN
PRINT "Keine Zeitzeichen empfangen!";
END IF
PRINT " ---> ENDE"
END