Atxmega und DCF77

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Hallo,
      danke für Deine Antwort.
      Ich wollte erst mal grundsätzlich danach fragen, unabhängig vom Quellcode.
      Es scheint, daß die config DCF77 nicht richtig funzt. Die Gosub Sectic von der Kommandozeile wird nicht angesprungen. Ohne diesen Eintrag in der Do...Loop Schleife wird keine Uhrzeit ausgegeben.
      Die Anzeige "MEZ" nehme ich als erste Reaktion, daß eine Synchronisation bevorsteht. Das funktioniert hie und da auch mit dem Eintrag in der Schleife. Die Synchronisation ist eher Zufall.
      Im übrigen, der DS1307 funktioniert bei 3,3V. Kann natürlich auch sein, daß dieser im Grenzbereich betrieben wird und so die Sync nicht immer klappt. Da aber mit Eintrag in der Schleife die Uhrzeit angezeigt wird und ohne diesen Eintrag nicht, liegt es wohl eher an der DCF Routine.
      Ohne Interruptroutine gleiches Ergebnis.
      Hier der Quellcode...abgespeckt vom eigentlichen Projekt, aber genauso getestet.

      BASCOM-Quellcode

      1. $regfile = "xm128a1def.dat"
      2. $crystal = 32000000
      3. $hwstack = 200
      4. $swstack = 200
      5. $framesize = 300
      6. $lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
      7. Config Osc = enabled , 32mhzosc = Enabled
      8. Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
      9. Config Priority = Static , Vector = Application , Lo = Enabled , Med = Enabled
      10. Config Com5 = 9600 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
      11. Open "COM5:" For Binary As #1
      12. Config Dcf77 = PinD.1 , Inverted = 0 , Timer = TCd1 , Debug = 1 , Check = 1, Gosub = Sectic
      13. Config Date = Dmy , Separator = .
      14. Dim Twi_start As Byte 'This Variable is used by the I2C functions
      15. Dim Weekday As Byte 'Day of Week
      16. Open "TWIc" For Binary As #2 'Pull-Up resistor (4K7) on SDA and SCL to Vcc = 3,3V
      17. Config Twic = 100000 'Set TWI Baud Rate and Enable TWI Master
      18. I2cinit #2 'set i2c pins to right state , open collector , pull up activated
      19. Dim bDCF_Pause_str As string * 10
      20. Dim bDCF_Impuls_str As string * 10
      21. Dim Tz As Byte
      22. Dim Ds_weekday As Byte
      23. Dim Ds_day As Byte
      24. Dim Ds_month As Byte
      25. Dim Ds_year As Byte
      26. Dim Ds_sec As Byte
      27. Dim Ds_min As Byte
      28. Dim Ds_hour As Byte
      29. Dim Minute_t As Byte
      30. Dim Stunde_t As Byte
      31. Dim Sekunde_t As Byte
      32. Dim Ds1307w As Byte
      33. Dim Ds1307r As Byte
      34. Ds1307w = &B11010000
      35. Ds1307r = &B11010001
      36. 'config pinc.0= input
      37. 'config pinc.1= input
      38. 'PortC_pin0ctrl = &B00_010_000 ' Pulldown
      39. 'PortC_pin1ctrl = &B00_010_000 ' Pulldown
      40. config Pind.1 = input
      41. Idcf Alias Pind.1
      42. Reset Portd.1
      43. Oled Alias PortE.1
      44. Config Oled = Output
      45. Const Isc0 = 0 'Input/Sense Configuration 0
      46. Const Isc1 = 1 'Input/Sense Configuration 1
      47. Const Isc2 = 2 'Input/Sense Configuration 2
      48. Const Opc0 = 3 'Output and Pull Configuration 0
      49. Const Opc1 = 4 'Output and Pull Configuration 1
      50. Const Opc2 = 5 'Output and Pull Configuration 2
      51. Const Inven = 6 'Inverted I/O Enable
      52. Const Srlen = 7 'Slew Rate Limit Enable
      53. Portcfg_mpcmask = &B00000010 'nachfolgende Konfiguration eines Pins gilt hier nur für F.0
      54. Portd_pin1ctrl = Bits(opc1 , Opc0 , Isc0) 'opc[0..2] = 011 --> Totempole Pull-up (on input)
      55. 'isc[0..2] = 010 --> FALLING Sense falling edge
      56. Portd_int1mask = &B00000010
      57. Dim Int_portd_1_flag As Bit
      58. On Portd_int1 Port_d_interrupt
      59. Enable Portd_int1 , lo
      60. Enable Interrupts
      61. Declare Sub Showtime_lcd()
      62. Declare Sub Init
      63. do
      64. gosub sectic 'normalerweise nicht notwendig - ohne wird aber sectic nicht angesprungen
      65. waitms 100
      66. loop
      67. Port_d_interrupt:
      68. Set Int_portd_1_flag
      69. Return
      70. Sectic:
      71. Gosub Show_clock
      72. Return
      73. Show_clock:
      74. I2cstart #2
      75. I2cwbyte Ds1307w,#2
      76. I2cwbyte 0,#2
      77. I2cstop #2
      78. I2cstart #2
      79. I2cwbyte Ds1307r, #2
      80. I2crbyte Ds_sec , Ack, #2
      81. I2crbyte Ds_min , Ack, #2
      82. I2crbyte Ds_hour , Ack, #2
      83. I2crbyte Ds_weekday , Ack, #2
      84. I2crbyte Ds_day , Ack, #2
      85. I2crbyte Ds_month , Ack, #2
      86. I2crbyte Ds_year , Nack,#2
      87. I2cstop #2
      88. bDCF_Pause_str=Str(bDCF_Pause)
      89. bDCF_Impuls_str=Str(bDCF_Impuls)
      90. Print #1 , Chr(27) ; "[1;1f";
      91. Print #1 , Chr(27) ; "[J";
      92. Print #1 , BCD(DS_day) ;".";BCD(DS_month);".";"20";BCD(DS_year);" ";BCD(ds_hour) ; ":" ; Bcd(ds_min) ; ":" ; Bcd(ds_sec)
      93. If Tz = 1 Then
      94. Print #1 , "MEZ"
      95. waitms 100
      96. Else
      97. Print #1 , "MESZ"
      98. waitms 100
      99. End If
      100. Gosub 1307_stellen
      101. Stunde_t = Makedec(ds_hour)
      102. Minute_t = Makedec(ds_min)
      103. Sekunde_t = Makedec(Ds_sec)
      104. Tz = Dcf77timezone()
      105. Return
      106. '----------------- Ende Datum und Zeit holen und Anzeigen
      107. '----------------- Zeit setzen
      108. Timeset:
      109. Ds_sec = Makebcd(Ds_sec)
      110. Ds_min = Makebcd(Ds_min)
      111. Ds_hour = Makebcd(Ds_hour)
      112. I2cstart #2
      113. I2cwbyte Ds1307w,#2
      114. I2cwbyte 0,#2
      115. I2cwbyte Ds_sec,#2
      116. I2cwbyte Ds_min,#2
      117. I2cwbyte Ds_hour,#2
      118. I2cstop #2
      119. Return
      120. '----------------- Ende Zeit setzen
      121. '----------------- Datum setzen
      122. Dateset:
      123. Ds_day = Makebcd(Ds_day)
      124. Ds_month = Makebcd(Ds_month)
      125. Ds_year = Makebcd(Ds_year)
      126. Ds_weekday = Makebcd(Ds_weekday)
      127. I2cstart #2
      128. I2cwbyte Ds1307w,#2
      129. I2cwbyte 3,#2
      130. I2cwbyte Ds_weekday,#2
      131. I2cwbyte Ds_day,#2
      132. I2cwbyte Ds_month,#2
      133. I2cwbyte Ds_year,#2
      134. I2cstop #2
      135. Return
      136. '----------------- Ende Datum setzen
      137. '----------------- RTC DS1307 nach DCF77 stellen
      138. 1307_stellen:
      139. If Dcf_status.7 = 1 And Ds_sec <> Dcf_sec Then ' wenn die DCFsekunden und die RTCsekunden unterschiedlich sind, die RTC stellen
      140. reset Oled ' LED an,wenn Synchronisation
      141. Ds_hour = _hour
      142. Ds_min = _min
      143. Ds_sec = _sec
      144. Gosub Timeset
      145. Ds_weekday = _weekday
      146. Ds_day = _day
      147. Ds_month = _month
      148. Ds_year = _year
      149. Gosub Dateset
      150. else
      151. Set Oled ' nach ca. 3 Minuten geht LED aus
      152. 'If Dcf_min = 1 Then : Reset Dcf_status.7 : End If 'einmal ?stündlich? das Statusbit zurücksetzen
      153. End If
      154. Return
      155. '----------------- Ende RTC DS1307 nach DCF77 stellen
      156. '----------------- Daten für Wochentag
      157. Wochentag:
      158. Data " " , "Montag" , "Dienstag" , "Mittwoch" , "Donnerstag" , "Freitag" , "Samstag" , "Sonntag"
      159. Monat:
      160. Data " " , "Januar" , "Februar" , "Maerz" , "April" , "Mai" , "Juni" , "Juli" , "August" , "September" , "Oktober" , "November" , "Dezember"
      Alles anzeigen
    • Hallo Richie69,

      wenn Du beim Erstellen eines Beitrags über dem Editorfenster auf </> klickst und anschließend in dem sich öffnenden Fenster auf "Bascom- Quellcode" klickst, wird Dein Programmcode so dargestellt wie in Deinem letzten Beitrag hier (Dort habe ich das für Dich geändert).

      Gruß Christian
      Wenn das die Lösung ist, möchte ich mein Problem wieder haben.
    • Hi, du kannst ja mal dcf_status.0 an einem Ausgang ausgeben. Damit sollte man erkennen können, ob die DCF77 Routine läuft.
      Aus der Hilfe:
      The DCF decoding routines use a status byte. This byte can be examined as in the example.
      The bits have the following meaning.
      Bit
      Explanation
      0
      The last reading of the DCF pin.
      1
      This bit is reserved.
      2
      This Bit is set, if after a complete time-stamp at second 58 the time-stamp is checked and it is OK. If after a minute mark (2 sec pause) this bit is set, the time from the DCF-Part is copied to the Clock-Part and this bit reset too. Every second mark also resets this bit. So time is only set, if after second 58 a minute mark follows. Normally this bit is only at value 1 from Second 58 to second 60/00.
      3
      This Bit indicates, that the DCF-Part should be stopped, if time is set. (at the option of updating once per hour or day).
      4
      This Bit indicated that the DCF-Part is stopped.
      5
      This bit indicates, that the CLOCK is configured the way, that during DCF-Clock is stopped, there is only one ISR-Call in one second.
      6
      This Bit determines the level of the DCF input-pin at the pulse (100/200 mSec part).
      7
      This bit indicates, that the DCF-Part has set the time of the Clock-part.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo,
      vielen Dank für das rege Interesse und Eure Antworten.
      Beim Kompilieren gibt es keine Fehler.
      Die lib zu benutzen ist natürlich naheliegender als eine extra Timerroutine zu implementieren.
      Enable Interrupts werde ich testen. Ebenso dcf_status.0.
      Die Adressen von dem RTC nebst Konfiguration als Variable hatte ich von einem anderen Quellcode übernommen. Vielen Dank für den Hinweis.
    • Ergänzend möchte ich noch anmerken: ich verwende immer eine Kontrollled in der Treiberstufe nach dem Dcfmodul. Damit kann man sehr gut die Empfangsqualität abschätzen. Es ist nicht so, dass man immer guten Empfang hat, wenn ein Aufbau mal funktioniert hat. Ein ungeeignetes Netzteil kann alles zunichte machen, oder ein Multiplexbetrieb von Anzeigen.


      Richie69 schrieb:

      1307_stellen:



      If Dcf_status.7 = 1 And Ds_sec <> Dcf_sec Then ' wenn die DCFsekunden und die RTCsekunden unterschiedlich sind, die RTC stellen

      reset Oled ' LED an,wenn Synchronisation
      Du musst das DCF_STATUS.7 danach wieder auf =0 setzen. Das wird nur automatisch gesetzt aber nicht automatisch resettet.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von tschoeatsch ()

    • Hallo,
      danke für den Tipp. Das DCF Signal beobachte ich mit Oszi. Habe mir auch die hier im Forum existierende Schaltung zum generieren eines DCF Signals nachgebaut. Ziemlich hilfreich, da das Signal sauber und störungsfrei ist.
      Signal wird von der lib auch verarbeitet, da das dcf_status.0 Signal ausgegeben wird. Enable Interrupt war bereits gesetzt...unterhalb der Routine von D.1. Diese Routine habe ich mal komplett weggelassen. Hat keine Auswirkung hinsichtlich der Signalausgabe. Es scheint, als ob das Programm ab und zu mal ein Impuls auslässt. Dadurch auch keine Synchronisation. Print #1 Time(dfc_sec) zählt hoch, manchmal zeigen sich sogar Minuten und Stunden. Kann sich ja nur noch um ein timing Problem handeln, Impuls und Pausenlänge liegen im Bereich 4-5 und 26-72. Den dcf_status.7=0 habe ich beim Atmega328 auch weggelassen. Synchronisiert zumindest trotzdem nach 3 Minuten, was beim Atxmega nicht mal ansatzweise funktioniert. Komischerweise wird die Timezone nach einer Minute angezeigt.
      Habe schon im Internet nach möglichen funktionierenden Beispielen für den Xmega gesucht. Leider vieles in C.
      Es gab da mal von einem Anbieter einen fertigen Attiny für das DCF Modul, welcher per UART an einen AVR angeschlossen werden kann. Leider ist dieser nicht mehr verfügbar. Wäre auch noch ein Ansatz.
    • Wenn du ein bisschen experimentieren willst, ich hab' mal mit einer anderen Lib dcf zum Laufen gebracht. dcf77 lib und der timer1 bei dieser Version kann man den timer frei wählen, muss ihn aber configurieren, was nicht schlimm ist. Das dcf_status byte ist auch anders belegt! Aber bei mir (kein atxmega) hat es funktioniert.

      Ach ja, der Pegel deines Signals passt mit der Einstellung 'Inverted'?

      Noch was, in der Hilfe steht
      In the XMEGA, you must enable HI, LO or MED interrupts before you can use them.
      When you enable an interrupt you also must specify the priority.
      For example : Enable Usartc0_rxc , Lo
      This would enable the USARTC0_RX interrupt and would assign it a low priority.

      Vielleicht musst du das mit deinem in der config dcf verwendeten timer auch machen
      (Ich rätsel jetzt, weil ich noch nix mit atxmega gemacht hab' und völlig unbeleckt bin)
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von tschoeatsch ()

    • Hallo,
      danke für die schnelle Antwort.
      Wenn die lib das Signal generiert, und das macht es, scheint die Einstellung 'inverted' zu stimmen.
      Die Anweisung der Priorität für den Interrupt habe ich im Programm:


      1. On Portd_int1 Port_d_interrupt
      2. Enable Portd_int1 , lo
      3. Enable Interrupt


      Ok. Kannst Du mir bitte Deinen Code für den Timer 1 vom Atmega schicken? Mal sehen, was ich daraus machen kann.

      Mfg
    • Diese alternative lib hat bei nichtatxmega den Vorteil nicht den timer1 zu verwenden, was die bascomeigne lib zwingend macht. Ich hab' zwar trotzdem in meinem Fall timer1 verwendet, konnte den aber noch für andere Zwecke verwenden. Diese alternative lib braucht nur einen Aufruf einer sub alle 25 mSec. Mit welchem timer ist egal und man kann mehr 'fummeln', zB einen pin wackeln lassen, dann weiß man, die sub wird aufgerufen. Musst mal den Text bei rn durchlesen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Hallo,
      es funktioniert mit der DCF77.lib. Seperate Interruptanweisung ist nicht notwendig.
      Mittels der time(dcf_sec) als Indikator sieht man schnell, ob die Uhrzeit korrekt empfangen wird. Nach kurzer Zeit erfolgt dann die Synchronisation.
      Der Fehler lag am Laptop, welches mit der USB - Stromversorgung am Testgerät verbunden ist. Es treten ab und zu ein paar kurze Nadelimpulse auf, welche die time(dcf_sec) wieder auf "00" stellt. Da das innerhalb von 3 Minuten ein paar Mal auftritt, kommt nie eine korrekte Zeit zusammen.
      Für den Atmega328 habe ich ein seperates Netzteil...für den Atxmega128 jetzt auch.
      Nochmals vielen Dank für die Tipps.
      Ich hänge hier mal noch ein Foto dran. Es handelt sich um eine Hausüberwachung. Temperaturen sind fiktiv - sie werden von einem Testsender geliefert. Der eigentliche Sender hat ein watchdog von 10 Minuten. Zu lang für schnell mal was umprogrammieren.

      image.jpeg