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
Druckbare Version
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
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.
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
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
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
Code:' 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
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.
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
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.
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