PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : config DCF77 +Sampleerklärung



bertl100
23.04.2007, 17:14
Hallo Forum,

kann mir jemand das Sample DCF77 aus der neuen Version von Bascom erklären?
Der Code ist nicht dokumentiert und ich kann die Schleifen nicht nachvollziehen.


MFG

Bertl

oe9vfj
23.04.2007, 20:13
Hallo Bertl,

Grundsätzlich ist die neue implementierte Funktion eine Interrupt-Routine, welche das an einem Input-Pin anliegende DCF77 Signal auswertet und damit eine Soft-Clock stellt (synchronisiert). Die Routine arbeitet nach dem gleichen Prinzip wie die von Albundy vorgestellte Library (verwendet aber einen anderen eigenen Code).
Die Routine wird durch einen Timer-Interrupt aufgerufen (möglich zwischen 32 und 128 mal pro Sekunden, idealerweise 40 mal pro Sekunde) und liest den Pegel des DCF-Signals ein.

Im CONFIG-Befehl können folgende Optionen eingestellt werden:

• invertiertes oder nicht invertiertes DCF77-Signal
• 3 Varianten zur Überprüfung des empfangenen DCF77 Zeit-Signals
• Fortlaufende, stündliche oder tägliche Zeit/Datum Synchronisation
• Einstellung der Minute/Stunde bei stündlicher/täglicher Synchronisation
• Abschalten der Spannungsversorgung des DCF77-Moduls in der synchronisationsfreien Zeit (bei stündlicher/täglicher Synch.)
• Zurückschalten des Timers auf einen ISR-Aufruf pro Sekunde in der synchronisationsfreien Zeit (bei 16Bit-Timern bzw. 32.768Hz Quarz an 8Bit Timer)

Zum Beispiel-Programm in der Hilfe:

Die Schleife ist so aufgebaut, dass zumindest einmal pro Sekunde eine Ausgabe erfolgt, falls auch der Timer nicht funktionert z.B. wenn der Interrupt deaktiviert ist.
Ändert sich _Sec (Soft-Clock Zeit) oder DCF_Sec (ausgewertetes DCF-Signal) wird die Schleife verlassen. Mit WAITMS 220 wird noch das Ende des Impulses (100 oder 200 mSec) abgewartet, damit auch dieser in der Ausgabe zur aktuellen DCF-Sekunden berücksichtigt wird.
Eine Ausgabe erfolgt, wenn sich die Soft-Clock Sekunde oder die DCF-Sekunden ändert. Nach Synchronisation fallen diese beiden Zeitpunkte zusammen. Sofern die Soft-Clock nicht synchron läuft, können pro Sekunden 2 Zeilen erscheinen.

Diese Bespiel dient lediglich dazu die Funktion zu überprüfen. In der Applikation genügt das CONFIG ..... Statement und alle Zeitfunktionen können wie von "CONFIG Clock = Soft" gewohnt verwendet werden.

bertl100
23.04.2007, 22:49
Danke für diese ausführliche Antwort!!!
Ich verwende bereits erfolgreich die Bundy lib, es scheint mir aber einfacher mit dem High Levelbefehl in Bascom zu arbeiten---Wenns funktioniert.
Andererseits find ich die Bundy lib und die Konfigurationen auch sehr gut, da hier alles angepasst werden kann.
Ich werds mal in meinem Programm implementieren.

Danke noch mal

Bertl

peter02
24.04.2007, 09:58
Hallo zusammen,

ich habe die Routine auch einmal ausprobiert. Die Softuhr wird nach einigen Minuten gestellt. Status-Bit 7 (DCF_Status.7) geht von 0 auf 1.
Jetzt passiert aber nichts mehr, die Softuhr geht jetzt stündlich 1 Sekunde nach und wird nie mehr gestellt. Ich hätte laut der Hilfe erwartet, dass die Softuhr automatisch gestellt wird. (Update=0). Muss man jetzt das Status-Bit 7 immer wieder zurücksetzen?


Gruß Peter

peter02
24.04.2007, 11:01
Hallo zusammen,

ich habe an meinem Mega32 gerade eine DS1307 RTC über I2C angeschlossen.
Das folgende Programm stellt die Softclock und auch die RTC.

1. Zeile Softclock
2. Zeile DCF77
3. Zeile dcf_status und dcf_bits
4. Zeile DS1307 Zeit und Datum und Wochentag


Gruß Peter




' LCD auf Port A
' RTC DS1307 Dallas Echtzeituhr auf I2E Portc.0 und Portc.1
' DCF77 Modul an Portd.3
' der DCF77 Empfänger stellt die Softuhr und die DS1307 Echtzeituhr
' V1.0 vom 24.04.07 by Peter Plischka
' Name: DCF77 Bascom mit DS1307 V1.0

$regfile = "m32def.dat"
$crystal = 16000000
$baud = 115200
$hwstack = 128
$swstack = 128
$framesize = 128
$lib "I2C_TWI.LBX"

'----------------- LCD Display an Port A
'Config Date = Dmy , Separator = .
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Porta.5 , Rs = Porta.7 ' Pinbelegung "LCD-Port)"
'Config Lcd = 20 * 4a , Chipset = Ks077 ' LCD 204 DIP 20x4
'Config Lcd = 16 * 2 , Chipset = Dogm163v5 , Contrast = &H702 ' EA DOGM162W-A
'Config Lcd = 16 * 2
Config Lcd = 20 * 4
Config Porta = Output
Config Lcdbus = 4
Initlcd
Deflcdchar 1 , 3 , 3 , 32 , 32 , 32 , 32 , 32 , 32 ' Grad
Deflcdchar 2 , 32 , 4 , 4 , 4 , 4 , 21 , 14 , 4 ' Pfeil runter
Deflcdchar 3 , 4 , 14 , 21 , 4 , 4 , 4 , 4 , 32 ' Pfeil rauf
Cls
Waitms 100
Cursor Off Noblink 'hide cursor
'----------------- Ende LCD

'----------------- Config DCF77
'Config Dcf77 = Pind.2 , Debug = 1 , Inverted = 0 , Check = 2 , Update = 0 , Updatetime = 30 , Switchpower = 0 , Secondticks = 50 , Timer1sec = 1 , Powerlevel = 1 , Timer = 1
Config Dcf77 = Pind.3 , Timer = 1 , Inverted = 1 , Timer1sec = 1 , Update = 0 , Check = 1, Debug = 1
Enable Interrupts
Config Date = Dmy , Separator = .

Dim I As Integer
Dim Sec_old As Byte , Dcfsec_old As Byte
Sec_old = 99 : Dcfsec_old = 99 ': DCF_Debug_Timer = 0
'----------------- Ende Config DCF77

'----------------- für die Uhr DS1307
' TWI init
Twcr = &B00000100 ' erstmal nur TWI aktivieren
Twsr = 0 ' Status und Prescaler Register
Twbr = 152 ' Bit Rate Register, 72 = 100kHz 152 = 50kHz(0 bis 255)
Config I2cdelay = 40

Config Scl = Portc.0
Config Sda = Portc.1
Config Twi = 100000

Dim Ds_weekday As Byte
Dim Ds_day As Byte
Dim Ds_month As Byte
Dim Ds_year As Byte
Dim Ds_sec As Byte
Dim Ds_min As Byte
Dim Ds_hour As Byte
Dim Minute_t As Byte
Dim Stunde_t As Byte
Dim Sekunde_t As Byte

Dim Ds1307w As Byte
Dim Ds1307r As Byte

Ds1307w = &B11010000
Ds1307r = &B11010001

'----------------- Uhr Ende

' Testroutine für die DCF77 Clock
Locate 1 , 1
Lcd "Test DCF77 V1.00"
Wait 1

Do
For I = 1 To 78
Waitms 10
If Sec_old <> _sec Then
Exit For
End If
If Dcfsec_old <> Dcf_sec Then
Exit For
End If
Next
Waitms 220
Sec_old = _sec
Dcfsec_old = Dcf_sec

Locate 1 , 1
Lcd Time$ ; " " ; Date$ ; " "

Locate 2 , 1
Lcd Time(dcf_sec) ; " " ; Date(dcf_day) ; " "

Locate 3 , 1
Lcd Bin(dcf_status) ; " " ; Bin(dcf_bits) ; " "

' Locate 4 , 1
' Lcd Bdcf_impuls ; " " ; Bdcf_pause ; " " ; Dcf77timezone() ; " " ; Dcf_status.7 ; " "

Gosub Show_clock

' Print Time$ ; " " ; Date$ ; " " ; Time(dcf_sec) ; " " ; Date(dcf_day) ; " " ; Bin(dcf_status) ; " " ; Bin(dcf_bits) ; " " ; Bdcf_impuls ; " " ; Bdcf_pause ; " " ; Dcf77timezone()

Loop

End

'Die Impulslänge sollte zwischen 2 und 8 liegen
'Die Pausenlänge sollte zwischen 70 und 90 liegen

' Dcf77timezone()
' 0 : when there is no valid DCF77 data yet
' 1 : When In "Middle Europe Normal Time"
' 2 : When In "Middle Europe daylight saving Time"

'----------------- Datum und Zeit holen und Anzeigen
Show_clock:
I2cstart
I2cwbyte Ds1307w
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte Ds1307r
I2crbyte Ds_sec , Ack
I2crbyte Ds_min , Ack
I2crbyte Ds_hour , Ack
I2crbyte Ds_weekday , Ack
I2crbyte Ds_day , Ack
I2crbyte Ds_month , Ack
I2crbyte Ds_year , Nack
I2cstop

Gosub 1307_stellen

Stunde_t = Makedec(ds_hour)
Minute_t = Makedec(ds_min)
Sekunde_t = Makedec(Ds_sec)

Locate 4 , 1
Lcd Bcd(ds_hour) ; ":" ; Bcd(ds_min) ; " " ; Bcd(ds_sec)

Locate 4 , 10
Lcd Bcd(ds_day) ; "." ; Bcd(ds_month) ; "." ; Bcd(ds_year) ; " " ; Lookupstr(ds_weekday , Wochentag)

Return
'----------------- Ende Datum und Zeit holen und Anzeigen

'----------------- Zeit setzen
Timeset:
Ds_sec = Makebcd(Ds_sec)
Ds_min = Makebcd(Ds_min)
Ds_hour = Makebcd(Ds_hour)
I2cstart
I2cwbyte Ds1307w
I2cwbyte 0
I2cwbyte Ds_sec
I2cwbyte Ds_min
I2cwbyte Ds_hour
I2cstop
Return
'----------------- Ende Zeit setzen

'----------------- Datum setzen
Dateset:
Ds_day = Makebcd(Ds_day)
Ds_month = Makebcd(Ds_month)
Ds_year = Makebcd(Ds_year)
Ds_weekday = Makebcd(Ds_weekday)
I2cstart
I2cwbyte Ds1307w
I2cwbyte 3
I2cwbyte Ds_weekday
I2cwbyte Ds_day
I2cwbyte Ds_month
I2cwbyte Ds_year
I2cstop
Return
'----------------- Ende Datum setzen

'----------------- RTC DS1307 nach DCF77 stellen
1307_stellen:

If Dcf_status.7 = 1 And Ds_sec <> Dcf_sec Then ' wenn die DCFsekunden und die RTCsekunden unterschiedlich sind, die RTC stellen
' Led2 = 0 'LED2
'Sound Portd.7 , 3500 , 140
Ds_hour = _hour
Ds_min = _min
Ds_sec = _sec
Gosub Timeset
Ds_weekday = _weekday
Ds_day = _day
Ds_month = _month
Ds_year = _year
Gosub Dateset

' If Dcf_min = 1 Then : Reset Dcf_status.7 : End If 'einmal stündlich das Statusbit zurücksetzen
End If

Return
'----------------- Ende RTC DS1307 nach DCF77 stellen

'----------------- Daten für Wochentag
Wochentag:
Data " " , "Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So"
'----------------- Ende Daten für Wochentag

oe9vfj
24.04.2007, 14:01
Hallo Peter,

Zu dem Status-Bit 7: Dieses Bit wird auf 1 gesetzt, wenn die SOFT-Clock vom DCF-Teil synchronisiert wird. Der Anwender kann dieses Bit jederzeit wieder auf 0 setzen (aber nur dieses Bit verändern !!!) um feststellen zu können, wenn das nächste Mal die SOFT-Clock wieder synchronisiert wird. Auf den Ablauf der Routine selbst hat dieses Bit keinen Einfluss, sondern ist nur ein Hinweis, dass die SOFT-CLOCK gestellt wurde.

Du hast recht, bei Update=0 sollte permanent synchonisiert werden. Ich werde mir das heute oder morgen Abend mal anschauen.
Bei Update=0 macht der Parameter Timer1Sec=1 keinen Sinn, da ja bei permanenter Synchronisation der DCF-Part nicht in "Ruhestellung" gehen kann und damit auch ein Zurückschalten des Timer-Aufrufes auf 1 x pro Sekunde nicht möglich ist.

peter02
24.04.2007, 14:38
Hallo Josef,

Timer1Sec=1 hatte ich für den Fall genommen, falls das DCF77 Signal über längere Zeit nicht korrekt empfangen werden kann. Im meinem Wohnzimer habe ich manchmal stundenlang keinen DCF77 Empfang, hier sind natürlich auch viele Störungen durch atmegas und PCs.
Das Update der Softclock geht jetzt - seitdem ich den Parameter Update = 0 in die Configzeile aufgenommen habe. Laut Hilfe sollte er default drin sein.

Wofür ich das Status-Bit 7 nutzen kann weiss ich noch nicht so richtig. Es ist ja nach ein paar Minuten 1 und bleibt dann ewig auf 1.

Im Moment bin ich mit meinem Programm zufrieden, alle drei Clocks laufen absolut syncron. Ich werde jetzt noch 2 DS1820 Sensoren integrieren, dann ist mein Innen/Aussen Termometer mit DCF77 Uhr fertig.

Gruß Peter

oe9vfj
24.04.2007, 14:43
Mit dem Status-Bit 7 kann ich feststellen, ob die Soft-Clock schon einmal nach DCF77 gestellt wurde. Weiters kann ich dieses Bit jederzeit auf 0 zurücksetzen und zu jedem späteren Zeitpunkt wieder abfragen, ob in der Zwischenzeit die Soft-Clock wieder neu gestellt wurde.

peter02
24.04.2007, 14:52
Ja, das ist schon klar, ich weiss nur nicht ob ich das brauche, aber vielleicht ergibt sich später eine Möglichkeit dieses Bit einzusetzen.

Ich sehe gerade ein komisches Phänomen - in der Sekunde 28 schaltet die DCF Minute eine Minute weiter.
Softclock und RTC laufen wie gewünscht weiter.

Hast Du dafür eine Erklärung?

Gruß Peter

peter02
24.04.2007, 15:11
Hier mal ein Foto des Effektes:

http://plischka.at/Fotos/dcf1.jpg

Hier ist noch alles OK.

http://plischka.at/Fotos/dcf2.jpg

Beachte die Minute in der 2. Zeile

1. Zeile Softclock
2. Zeile DCF77
3. Zeile dcf_status und dcf_bits
4. Zeile DS1307 Zeit und Datum und Wochentag


Gruß Peter

oe9vfj
24.04.2007, 15:13
Ob Du das Status-Bit 7 für Dich als Informationsquelle verwendest, bleibt Dir überlassen.
Im DCF-Signal wird die Zeit-Information für die nächste volle Minute übertragen. Daher ist die Minuteninformation nicht diejenige der laufenden Minute, sondern der nächsten. Mit der 28. Sekunde ist die Minuteninformation komplett und wird in die entsprechende Variable DCF_Min geschrieben. Das gleiche "Phänomen" wirst Du bei DCF_Hour beim Stundenwechsel bei der Sekunde 35 feststellen. Die Variable DCF_Sec ... DCF_Year sind interne Variablen zum Zwischenspeichern der empfangenen Zeitinformation und haben für die Applikation selbst keinen unmittelbaren Wert.
In der Test-Stellung kann hier die empfangene Zeit-Information beobachtet werden.

peter02
24.04.2007, 15:24
Hallo Josef,

danke, das wußte ich überhaupt nicht.
Also kann ich DCF_Sec ... nicht für Anzeigezwecke gebrauchen, sondern muß die Soft oder RCT Zeit dafür benutzen.

Gut, wenn man es weiß, kann man damit leben. Ich dachte ich hätte einen Fehler gemacht oder entdeckt.

Gruß Peter

oe9vfj
24.04.2007, 15:44
Das Verhalten ist kein Bug, mit dem man "leben muss", sondern ergibt sich aus der Konzeption der Programmes. Das ganze besteht ja aus zwei Teilen:

- einer eigenständigen Soft-CLOCK
- einer DCF-Signal-Auswertung, welche bei korrekter Zeitinformation die Soft-Clock stellt.

Im Programm sollte daher nur mit den Variablen aus der Soft-Clock gearbeitet werden.
Dagegen, die DCF_... Variablen im Programm zu verwenden spricht nur das vorher angeführte systembedingte Verhalten. Auch gibt es für DCF_Sec keine Sekunde 59, da diese ja nicht gesendet wird. Die Pause von 2 Sekunden zwischen 58 und 00 ist ja die Minutenmarke. Weiters wird in den Variablen DCF_Sec .... DCF_Year bei gestörtem Empfang auch nur Schrott zu finden sein, weil dort die Informationen ja wie empfangen eingeschrieben werden. Mit dem kompletten Zeittelegramm in der Sekunde 58 wird die gespeicherte Zeitinformation je nach dem CHECK-Parameter geprüft. Falls diese als richtig erkannt wird und eine Minutenmarke unmittelbar darauf folgt, wird die SOFT-CLOCK gestellt.

peter02
24.04.2007, 16:56
Hallo Josef,

danke für die Infos.

Das Testprogramm verführte dazu auch die Zeit aus den DCF Variablen zu beobachten. Bei "normaler" Anwendung hätte ich das Verhalten wohl gar nicht bemerkt. Aber gut zu wissen.
Ich würde bei meinem fertigen Innern/Aussen Termometer auch nur die RTC Zeit verwenden. Die hatte heute ca. 2 sec Abweichung, obwohl die Schaltung schon seit 2 Monaten hier im Schrank liegt.

Gruß Peter

bertl100
24.04.2007, 19:35
Hallo Leute!!

Hab gerade die Routine config dcf77 in meinen Quellcode integriert und ich muß sagen, es geht sehr gut. Noch während der Auswertung der Sekundenzeiten werden die einzelnen Werte schon geupdated.
Ich finde es sehr gelungen.

MFG

Bertl

mat-sche
27.04.2007, 11:55
@ Peter,

Hallo!

ich möchte gern Deinen Code zum probieren zu Hilfe ziehen. Nur leider kenne ich mich noch nicht so recht mit der soft_clock aus.
Das Programm will ich wie Du auf einem Mega32 laufen lassen.
Meine Frage ist nun:
1. wie sieht es mit den Fusebit für den mega aus, wie müssen diese richtig gestellt werden
2. benötige ich für die soft_clock den 32kHz Quarz?

Könntest Du mir kurz Deine Hardwarekonfiguration darstellen?

Vielen Dank und Gruß MAT

peter02
02.05.2007, 08:49
Hallo MAT,
sorry ich war weg, deshalb die späte Antwort.

Ich nutze ein selbstgebautes MEGA32 Board. Am I2C Bus habe ich den 1307, als die Echtzeituhr angeschlossen. Der Baustein nutzt den 32 kHz Quarz und eine 3V Batterie.

Bei den Fusebits habe ich Fusebit KLA987 auf 111111 gesetzt. (für den 16MHz Quarz) und Fusebit H auf 1 (JTAG aus)

Das Programm stellt die Softuhr über die DCF77 Routine, wenn diese gestellt ist wird der 1307 gestellt. In einer echten Anwendung würde man nur die 1307 Zeit zeigen, weil diese "immer" stimmen sollte.

Gruß Peter

mat-sche
02.05.2007, 15:44
Hallo Peter!

Danke für Deine Antwort! Zur zeit läuft meine DCF77 nun endlich.
Jetzt habe ich schon in Forenbeiträge nach einer Lösung gesucht, mit der ich bei einer bestimmten Zeit eine Aktion auslösen kann.
Hast Du ne Lösung zur Hand?

Das wäre schön!

CU & Gruß MAT

peter02
02.05.2007, 18:50
Hallo MAT,

nimm sowas wie:

If _Hour = 23 .AND. _Min = 0 then
deine Aktion
End if

Gruß Peter

wanderer
02.05.2007, 18:58
Einfach inner Schleife mit ner If-Abfrage ueberpruefen ob die gewuenschte zeit da ist sollte doch gehen...
Also so:
if minute_t = 5 and stunde_t = 13 then
*machwas du willst*
end if

weiss nich ob das die richtigen variablen sind, hab mit dem code noch nich gearbeitet, sollte aber tun.

edit: peter war schneller -_- ich haette nich zwischendurch essen solln^^

mat-sche
02.05.2007, 19:02
Jo,

habe es anders gelöst.
Habe eine Stringvariable dem Time$ Wert zugewiesen und dann die if schleife genommen.

Hat jemand nen Plan wie die Wochentage als Wort ausgegeben werden können?

Gruß MAT

peter02
03.05.2007, 12:09
Hallo MAT,
die Wochentage kannst Du genau wie in meinem Beispielcode ausgeben.

Aber das wurde dir ja schon in einem anderen Betrag gesagt.

Gruß Peter

mat-sche
03.05.2007, 17:16
Hallo Peter,

jup, jetzt hat es klick gemacht! :)

Hin und Herprobiert und jetzt sehe ich auch den Wochentag *freu*

Danke nochmals, wieder eine Hürde genommen!

MAT

NickiW
18.05.2007, 12:42
Hallo zusammen,

ich benutze einen PIC16F876A Prozessor mit einer über I2C-Bus angeschlossenen DS1307 RTC. Bis jetzt muss man die RTC mit einer Folientastatur stellen. Ich möchte, dass sie RTC von einem DCF77 Empfänger synchonisiert wird. Hat jemand schon mal Erfahrungen mit dem PIC und dem DCF sammeln können? Ich hab die Funktionsweise des DCF Empfängers und die Datenauswertung noch nicht ganz durchschaut, vielleicht kann mir jemand von euch helfen.

Vielen Dank.

Dirk
18.05.2007, 13:24
Hallo NickiW,


Hat jemand schon mal Erfahrungen mit dem PIC und dem DCF sammeln können?

Auch für den PIC gibt es DCF77-Assembler Lösungen oder fertige Bauanleitungen, z.B.: http://www.ra.informatik.uni-mannheim.de/pages/lectures/fss07/mst/prak_anl_dcf77.pdf

Gruß Dirk

MST_NRW
06.07.2007, 17:54
Hallo Josef,

ich habe die Routine auch einmal ausprobiert und bin wirklich begeistert,
super einfach und schnell einzubinden.

Einfach spitze..!