Problem mit DCF77 und I2c

    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!

    • Problem mit DCF77 und I2c

      Hallo Zusammen,

      aktuell habe ich ein Problem mit DCF 77 , I2C und einer 7 Segment Anzeige.

      Im Einzelnen: ich steuere 2 7 Segment Displays an, die jeweils durch einen PCF 8574N getrieben werden. Die PCF werden über I2C angesteuert. Daserste 7 Segm. ist für die Einer-Stelle zuständig, das zweite für die Zehner-Stelle.

      Das Programm läuft auf einem Tiny 85. Es wird eine DCF77 Uhr ausgewertet mit der entsprechenden Bascom Routine. Dabei wird die Sekunde in Einer und Zehner zerlegt und dann per I2C übertragen. Die Rechenmethode habe ich zuvor mit einem Tiny 2313 erprobt und funktioniert. Da der 2313 aber nicht genügend Speicherkapa hat für LCD Display Anzeige und 7 Segment, bin ich dann auf Tiny 85 umgestiegen. (Einen Tiny 4313 habe ich aktuell nicht vorrätig)

      Das Problem ist folgendes : Die Sekundenanzeige läuft viel zu schnell. Sie durchläuft in ca. 5 sec (geschätzt) den Bereich von 0 bis 60, d.h. es läuft ca. Faktor 12 zu schnell. Gleiches geschieht übrigens auch, wenn ich einen Tiny 45 verwende.

      Wenn ich aber den DCF77 Eingang als Tastereingang verwende, und den Befehl Debounce etc. anwende wird sauber rauf gezählt. ( Der ganze DCF77 Teil ist dann natürlich inaktiv gesetzt)

      Kann bitte mal jemand über mein Programm schauen, und mir ggf. sagen/ zeigen wo mein Fehler liegt. Mein aktuelles Programm habe ich unten angehängt.

      Vielen Dank für Eure Mühe.

      Gruss

      Theo

      Quellcode

      1. $regfile = "Attiny85.dat"
      2. $crystal = 8000000 ''8 Mhz int. Generator
      3. $swstack = 40
      4. $hwstack = 20
      5. $framesize = 8
      6. '######### Eingänge definieren
      7. Declare Sub Sekunde_stellen()
      8. 'Array für Segmente einreichten
      9. 'Daten müssen in der Reihenfolge : =&B P7 P6 P5 P4...... im Array stehen
      10. '0= Segment an ; 1= Segment aus
      11. 'Die Reihenfolge der Bits ist angepasst an das Layout der Platine
      12. Dim Array_D(12) as Byte
      13. Array_D(1)= &B00101000 'ist 0
      14. Array_D(2)= &B10101111 'ist 1
      15. Array_D(3)= &B01001010 'ist 2
      16. Array_D(4)= &B00001110 'ist 3
      17. Array_D(5)= &B10001101 'ist 4
      18. Array_D(6)= &B00011100 'ist 5
      19. Array_D(7)= &B00011001 'ist 6
      20. Array_D(8)= &B10101110 'ist 7
      21. Array_D(9)= &B00001000 'ist 8
      22. Array_D(10)= &B10001100 'ist 9
      23. Array_D(11)= &B11111111 'alle Segmente aus incl. DP
      24. Array_D(12)= &B00000000 'alle Segmente an incl DP --> lamp test
      25. 'Adressen der einzelnen PCF 8574 in Array setzen
      26. Dim Array_Adr (2) as Byte
      27. Array_Adr(1)= &B01000000 'Adresse Sekunden Einer
      28. Array_Adr(2) =&B01000010 'Adresse Sekunden Zehner
      29. 'I2C einrichten
      30. Config SCL=Portb.2
      31. Config SDA=Portb.0
      32. 'Const AdrSec_E= &B01000000'Adresse Sekunden Einer
      33. 'Const AdrSec_Z= &B01000010 'Adresse Sekunden Zehner
      34. '############################## LCD komplett inaktiv setzen #################
      35. '######### LCD definieren
      36. 'Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , E = Porta.0 , Rs = Porta.1
      37. 'Config Lcd = 16 * 2
      38. 'Cls
      39. 'Cursor = 0ff
      40. 'Wait 1
      41. 'Cursor=off
      42. '#################################################################################
      43. '### DCF 77 konfigurieren '#######
      44. Config Dcf77 = Pinb.3 , Inverted = 1 , Timer = 1 , Update = 0 , Debug = 0 , Check = 1 , Gosub = Sectic
      45. Config Date = Dmy , Separator = .
      46. Enable Interrupts
      47. Portb.3 = 1 'Eingang für DCF77 Signal; Pullup einschalten
      48. Dim Sync_Uhr as Byte
      49. Dim Neue_sekunde As Byte
      50. Dim Sek as Byte 'Wert der aktuellen Sekunde
      51. Dim Sek_E as Byte 'Sekunde Einer
      52. Dim Sek_Z as Byte ' Sekunde Zehner
      53. Dim Sek_alt as Byte
      54. Sek_E=0
      55. Sek_Z =0
      56. Sek=0
      57. Sek_alt=0
      58. Do
      59. 'Signal_kontroll_led = Dcf_status.0
      60. Sync_Uhr=Dcf_status.7 '=0 wenn nicht synchronisiert; =1 wenn synchronisiert
      61. If Neue_sekunde = 1 Then
      62. Neue_sekunde = 0
      63. If Dcf_status.7 = 0 Then'Uhr nicht synchronisiert
      64. 'Locate 1 , 1 ' LCD Inaktiv
      65. 'Lcd Time$ LCD inaktiv
      66. Elseif DCF_status.7 <> 0 then 'Uhr sychronisiert
      67. 'Locate 1 , 1'LCD inaktiv
      68. 'Lcd Time$'Lcd inaktiv
      69. End if
      70. End If
      71. Sek=_sec
      72. if Sek<> Sek_alt then
      73. Sekunde_stellen
      74. End if
      75. Loop
      76. End
      77. Sectic:
      78. Neue_sekunde = 1
      79. Return
      80. Sub Sekunde_stellen
      81. if Sek<10 then
      82. Sek_E =Sek
      83. Sek_Z=0
      84. elseif Sek>9 then
      85. sek_E= Sek Mod 10
      86. Sek_Z=Sek/10
      87. End if
      88. Sek_alt=Sek
      89. '####### inaktiv########
      90. 'Sekunden Einer und Zehner anzeigen
      91. 'Locate 2,1 LCD inaktiv
      92. 'Lcd "Zehn: "; Sek_Z ;" Ein: ";Sek_E LCD Inaktiv
      93. '############################
      94. 'hier Daten per I2C senden
      95. 'Sekunden Einer senden
      96. I2Cstart
      97. I2Cwbyte Array_Adr(1)
      98. I2Cwbyte Array_D(Sek_E+1)
      99. I2CStop
      100. 'Waitms 100
      101. 'Sekunden Zehner senden
      102. I2Cstart
      103. I2cwbyte Array_Adr(2)
      104. I2Cwbyte Array_D(Sek_Z+1)
      105. I2CStop
      106. End Sub
      Alles anzeigen
    • Theo schrieb:

      Config SCL=Portb.2
      Config SDA=Portb.0
      Mir fehlt hier danach das I2CInit. Sollte auf jeden Fall mit rein.

      Theo schrieb:

      Sek=_sec
      Warum nutzt du die interne Variable _sec nicht direkt? Warum der Umweg über eine weitere Variable?

      Probier mal das (leicht abgeändert):

      BASCOM-Quellcode

      1. $regfile = "Attiny85.dat"
      2. $crystal = 8000000 ''8 Mhz int. Generator
      3. $swstack = 40
      4. $hwstack = 20
      5. $framesize = 8
      6. '######### Eingänge definieren
      7. Declare Sub Sekunde_stellen()
      8. 'Array für Segmente einreichten
      9. 'Daten müssen in der Reihenfolge : =&B P7 P6 P5 P4...... im Array stehen
      10. '0= Segment an ; 1= Segment aus
      11. 'Die Reihenfolge der Bits ist angepasst an das Layout der Platine
      12. Dim Array_D(12) as Byte
      13. Array_D(1)= &B00101000 'ist 0
      14. Array_D(2)= &B10101111 'ist 1
      15. Array_D(3)= &B01001010 'ist 2
      16. Array_D(4)= &B00001110 'ist 3
      17. Array_D(5)= &B10001101 'ist 4
      18. Array_D(6)= &B00011100 'ist 5
      19. Array_D(7)= &B00011001 'ist 6
      20. Array_D(8)= &B10101110 'ist 7
      21. Array_D(9)= &B00001000 'ist 8
      22. Array_D(10)= &B10001100 'ist 9
      23. Array_D(11)= &B11111111 'alle Segmente aus incl. DP
      24. Array_D(12)= &B00000000 'alle Segmente an incl DP --> lamp test
      25. 'Adressen der einzelnen PCF 8574 in Array setzen
      26. Dim Array_Adr (2) as Byte
      27. Array_Adr(1)= &B01000000 'Adresse Sekunden Einer
      28. Array_Adr(2) =&B01000010 'Adresse Sekunden Zehner
      29. 'I2C einrichten
      30. Config SCL=Portb.2
      31. Config SDA=Portb.0
      32. I2cinit
      33. 'Const AdrSec_E= &B01000000'Adresse Sekunden Einer
      34. 'Const AdrSec_Z= &B01000010 'Adresse Sekunden Zehner
      35. '############################## LCD komplett inaktiv setzen #################
      36. '######### LCD definieren
      37. 'Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , E = Porta.0 , Rs = Porta.1
      38. 'Config Lcd = 16 * 2
      39. 'Cls
      40. 'Cursor = 0ff
      41. 'Wait 1
      42. 'Cursor=off
      43. '#################################################################################
      44. '### DCF 77 konfigurieren '#######
      45. Config Dcf77 = Pinb.3 , Inverted = 1 , Timer = 1 , Update = 0 , Debug = 0 , Check = 1 , Gosub = Sectic
      46. Config Date = Dmy , Separator = .
      47. Enable Interrupts
      48. Portb.3 = 1 'Eingang für DCF77 Signal; Pullup einschalten
      49. Dim Sync_Uhr as Byte
      50. Dim Neue_sekunde As Byte
      51. Dim Sek_e As Byte 'Sekunde Einer
      52. Dim Sek_Z as Byte ' Sekunde Zehner
      53. Dim Sek_alt as Byte
      54. Sek_E=0
      55. Sek_z = 0
      56. Sek_alt = 0
      57. Do
      58. 'Signal_kontroll_led = Dcf_status.0
      59. 'Sync_Uhr=Dcf_status.7 '=0 wenn nicht synchronisiert; =1 wenn synchronisiert
      60. If Neue_sekunde = 1 Then
      61. Neue_sekunde = 0
      62. If Dcf_status.7 = 0 Then'Uhr nicht synchronisiert
      63. 'Locate 1 , 1 ' LCD Inaktiv
      64. 'Lcd Time$ LCD inaktiv
      65. Else 'Uhr sychronisiert
      66. 'Locate 1 , 1'LCD inaktiv
      67. 'Lcd Time$'Lcd inaktiv
      68. End if
      69. 'If _sec <> Sek_alt Then
      70. Call Anzeige
      71. 'End If
      72. End If
      73. Loop
      74. End
      75. Sectic:
      76. Neue_sekunde = 1
      77. Return
      78. Sub Anzeige
      79. If _sec < 10 Then
      80. Sek_e = _sec
      81. Sek_z = 0
      82. Else
      83. Sek_e = _sec Mod 10
      84. Sek_z = _sec / 10
      85. End if
      86. 'Sek_alt = _sec
      87. '####### inaktiv########
      88. 'Sekunden Einer und Zehner anzeigen
      89. 'Locate 2,1 LCD inaktiv
      90. 'Lcd "Zehn: "; Sek_Z ;" Ein: ";Sek_E LCD Inaktiv
      91. '############################
      92. 'hier Daten per I2C senden
      93. 'Sekunden Einer senden
      94. I2Cstart
      95. I2Cwbyte Array_Adr(1)
      96. I2Cwbyte Array_D(Sek_E+1)
      97. I2CStop
      98. 'Waitms 100
      99. 'Sekunden Zehner senden
      100. I2Cstart
      101. I2cwbyte Array_Adr(2)
      102. I2Cwbyte Array_D(Sek_Z+1)
      103. I2CStop
      104. End Sub
      Alles anzeigen
      Eine Lösung habe ich nicht, aber mir gefällt Ihr Problem.
    • Hallo Theo,
      der Tiny85 (genau wie der Tiny45) hat die Besonderheit, dass der Timer1 nur ein 8-bit Timer ist. Bei allen anderen hat er 16-bit Breite. Da Config DCF77 nur den Timer1 mag, gehe ich davon aus, dass der Compiler einen 16-bit Timer voraussetzt. Daher befürchte ich, dass Config DCF77 auf einem Tiny85 nicht funktioniert. Du wirst dir bei diesem Prozessor also eine eigene Routine machen müssen. Hier im Forum wurden auch schon einige vorgestellt. Ansonsten einen anderen Controller nehmen.
    • Wobei, wenn ich mir das recht überlege, sollte es mit seiner Datei und deinen Werten (allerdings eher OCR1A=194) tatsächlich funktionieren, solange der Compiler die 24999 nicht doch versucht irgendwie in Register unterzubringen. Compare1a ist ja nur 8-bit breit.
      Allerdings ist die Sekunde dann recht ungenau und wirkt sich über längere Zeit vielleicht aus. Kommt darauf an, wie Sectic aufgerufen wird.
    • Er scheint es nur beim Start ein zu tragen. Woanders wich die Zeit zwischen den Syschronisierungen zu weit ab. Da half es ein eigenen Wert zuzuweisen. (ich denke nur einmalig ? ) Falls das nicht reicht kanns auch in die Sectic eingetragen werden.
      Die geänderte dat sollte keine Register verdoppeln? Die vom Tiny45 jedoch auch Fehler melden?
      Es muß (und Z.65) TCCR1=139 heißen und noch eine Zeile mit Ocr1c = 195 (oder 194 s.Franz)
      sonst wird er zu langsam.
      Der Hw-Stack ist zu klein, min 40 ($hwstack = 40)

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

    • Hallo Zusammen,
      vielen Dank für Eure Kommentare. @djmsc: natürlich muss das I2cinit dahin, bewirkt aber keine Besserung. Das Problem ist nach wie vor da. Ich schliesse mich der Meinung von Franz an, man braucht einen Timer1 mit 16 Bit breite. Also, alles umschreiben auf einen anderen uC. Das werd ich auch machen.
      Ich Danke Euch für Eure Kommentare.

      Gruss
      Theo