Forum: Mikrocontroller und Digitale Elektronik ATmega32 DCF77 / Sekundentakt


von Hans F. (Gast)


Lesenswert?

Guten Tag!

Habe mit einem ATmega32 und einem DCF Empfänger die Uhrzeit und das 
Datum auf einem LCD ausgegeben. Gibt es irgendeine möglichkeit den 
Sekundentakt an einem Pin abzugreifen? Würde damit gerne Schieberegister 
füllen für eine große Uhr.

Hier mal mein bisheriger Code:
1
' Bascom-AVR DCF77 Beispiel
2
    '
3
    ' Copyright (c) 2011 Peter Tuch, crycode.de
4
    ' Lizenz/License: GNU General Public License version 3
5
    ' siehe/see: http://crycode.de/files/gnu_gpl_3.html
6
    '
7
    $regfile = "m32def.dat"
8
    $crystal = 16000000
9
    '$baud = 57600
10
    '$hwstack = 100
11
    '$swstack = 100
12
    '$framesize = 100
13
    $lib "mcsbyte.lbx"
14
15
    'LCD initialisieren
16
17
18
19
20
21
22
    ' DCF77 auf PinB.0 einstellen
23
    Config Dcf77 = Pinb.0 , Timer = 1 , Debug = 1 , Check = 1 , Inverted = 1 , Gosub = Sectic
24
25
    'LCD initialisieren
26
27
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
28
    Config Lcd = 16 * 2
29
30
    Initlcd
31
    Cursor Off
32
    Cls
33
34
    ' Interrupts müssen aktiviert werden
35
    Enable Interrupts
36
37
    ' Datumsformat festlegen
38
    Config Date = Dmy , Separator = .
39
40
    'Print "Synchronisiere die Uhrzeit mit dem DCF77 Zeitsignal..."
41
    Locate 1 , 1
42
    Lcd "Sync. DCF77"
43
44
    ' Auf die Synchronisierung der Uhrzeit mit dem DCF77 Zeitsignal warten
45
    While Dcf_status.7 = 0
46
    ' Dcf_status.7 wird auf 1 gesetzt sobald die Zeit erfolgreich synchronisiert wurde
47
    ' aktuelle Zeiten (intern und DCF) sowie den Status zum Terminal ausgeben
48
    'Print "DCF: " ; Time$ ; " " ; Date$ ; " " ; Time(dcf_sec) ; " " ; Date(dcf_day) ; " " ; Bin(dcf_status) ; " " ; Bin(dcf_parity) ; " " ; Bin(dcf_bits) ; " " ; Bdcf_impuls ; " " ; Bdcf_pause
49
    Locate 1 , 1
50
    Lcd " ABW DCF77 Uhr "
51
    Locate 2 , 1
52
    Lcd "      Sync      "
53
    Waitms 50
54
    Wend
55
56
    'Print "Uhrzeit erfolgreich synchronisiert! " ; Time$ ; " " ; Date$
57
58
    ' Hauptschleife des Programms
59
    ' (kann weitere Anweisungen enthalten)
60
    Do
61
    Locate 1 , 1
62
    Lcd "Time: " ; Time$ ;
63
    Locate 2 , 1
64
    Lcd "Date: " ; Date$ ;
65
    'NOP
66
    Loop
67
68
    ' Programmende
69
    End
70
71
    ' Sectic-Programmteil
72
    ' wird durch den internen Timer automatisch jede Sekunde einmal aufgerufen
73
    Sectic:
74
    'Print Time$ ; " " ; Date$
75
    Return

Danke schonmal im Vorraus.

MfG

von Karl H. (kbuchegg)


Lesenswert?

Hans F. schrieb:

> Habe mit einem ATmega32 und einem DCF Empfänger die Uhrzeit und das
> Datum auf einem LCD ausgegeben. Gibt es irgendeine möglichkeit den
> Sekundentakt an einem Pin abzugreifen?

Direkt am DCF Empfänger gibt es keine Möglichkeit. Das folgt daraus, 
dass im DCF Signal der MInutenanfang durch ein fehlendes Sekundensignal 
signalisiert wird.


Aber wo liegt das Problem?
Du hast doch in deinem Programm eine Routine, die jede Sekunde 
aufgerufen wird. Toggle dir dort einen Pin (oder erzeug dir einen Puls) 
und du hast das gewünschte Signal? Oder stimmt der Kommentar hier nicht?
1
    ' Sectic-Programmteil
2
    ' wird durch den internen Timer automatisch jede Sekunde einmal aufgerufen
3
    Sectic:
4
    'Print Time$ ; " " ; Date$
5
    Return

von Hans F. (Gast)


Lesenswert?

Okay, hab nun mal

    Config Pinb.5 = Output
    Dim Sekunden As Byte
    Sekunden = 0

und

Sectic:

    Portb.5 = 1
    Waitms 5
    Portb.5 = 0
    Sekunden = Sekunden + 1


Ich gebe die Sekunden nun mit auf dem LCD aus. Ist es irgendwie möglich 
das er nur synchron zu den dcf sekunden bis 60 hochzählt und auch erst 
anfängt, wenn ein DCF Signal (Dcf_status.7 = 1) anliegt?

So zählt er ja schon los, wenn ich einschalte.

MfG

von Volkmar D. (volkmar)


Lesenswert?

Hans F. schrieb:
> Ist es irgendwie möglich
> das er nur synchron zu den dcf sekunden bis 60 hochzählt

Dazu mußt Du in der Interrupt-Routine eben nur bis 59 zählen und danach 
Deine interne Uhr anhalten bis ein neues DCF-Signal kommt.

Hans F. schrieb:
> und auch erst
> anfängt, wenn ein DCF Signal (Dcf_status.7 = 1) anliegt?

Ähnlich, warte mit der Freischaltung des internen Uhren-Interrupts bis 
das DCF-Signal vorhanden ist.

von Hans F. (Gast)


Lesenswert?

Sooo, habs nun so:

     If Dcf_status.7 = 1 Then


    If Sekunden >= 59 Then
    Sekunden = 0
    Else
    Sekunden = Sekunden + 1
    End If
    End If

Leider gehen die Sekunden nach 59 immer auf 255. Warum ist das so?

MfG

von Volkmar D. (volkmar)


Lesenswert?

Ich denke, da wird zur Beurteilung der gesamte Code benötigt. Ich kenne 
mich jedoch mit Basic nicht aus.

von Alex (Gast)


Lesenswert?

Frage mal deinen Debugger.

von Hans F. (Gast)


Lesenswert?

Soooo, habs nun einigermaßen zum laufen gebracht. Allerdings habe ich 
nun das Problem, das die DCF Minute nicht mehr bei Sekunde 00 umspringt 
sonder mittendrin in der Minute. Und das Urzeit/Datum wird nun so 3-4min 
angezeigt, danach dreht das LCD voll durch und zeigt nur noch 
Sonderzeichen etc. an! Am LCD liegts nicht, habe grad schon ein zweites 
getestet.

Hier mal der Code:
1
    ' Bascom-AVR DCF77 Beispiel
2
    '
3
    ' Copyright (c) 2011 Peter Tuch, crycode.de
4
    ' Lizenz/License: GNU General Public License version 3
5
    ' siehe/see: http://crycode.de/files/gnu_gpl_3.html
6
    '
7
    $regfile = "m32def.dat"
8
    $crystal = 16000000
9
    '$baud = 57600
10
    '$hwstack = 100
11
    '$swstack = 100
12
    '$framesize = 100
13
    $lib "mcsbyteint.lbx"
14
    $lib "mcsbyte.lbx"
15
16
    'LCD initialisieren
17
18
19
    Config Pinb.5 = Output
20
    Dim Sekunden As Integer
21
    'Dim Sekunden2 As Byte
22
    'Dim Minuten As Byte
23
    Sekunden = -1
24
25
26
27
28
    ' DCF77 auf PinB.0 einstellen
29
    Config Dcf77 = Pinb.0 , Timer = 1 , Debug = 1 , Check = 1 , Inverted = 1 , Gosub = Sectic
30
31
32
33
    'LCD initialisieren
34
35
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.5 , Rs = Portd.4
36
    Config Lcd = 20 * 2
37
38
    Initlcd
39
    Cursor Off
40
    Cls
41
42
    ' Interrupts müssen aktiviert werden
43
    Enable Interrupts
44
45
    ' Datumsformat festlegen
46
    Config Date = Dmy , Separator = .
47
48
    'Print "Synchronisiere die Uhrzeit mit dem DCF77 Zeitsignal..."
49
    'Locate 1 , 1
50
    'Lcd "Sync. DCF77"
51
52
    ' Auf die Synchronisierung der Uhrzeit mit dem DCF77 Zeitsignal warten
53
    While Dcf_status.7 = 0
54
    ' Dcf_status.7 wird auf 1 gesetzt sobald die Zeit erfolgreich synchronisiert wurde
55
    ' aktuelle Zeiten (intern und DCF) sowie den Status zum Terminal ausgeben
56
    'Print "DCF: " ; Time$ ; " " ; Date$ ; " " ; Time(dcf_sec) ; " " ; Date(dcf_day) ; " " ; Bin(dcf_status) ; " " ; Bin(dcf_parity) ; " " ; Bin(dcf_bits) ; " " ; Bdcf_impuls ; " " ; Bdcf_pause
57
    Locate 1 , 1
58
    Lcd " ABW DCF77 Uhr "
59
    Locate 2 , 1
60
    Lcd "      Sync      "
61
    Waitms 50
62
    Wend
63
64
65
66
    'Print "Uhrzeit erfolgreich synchronisiert! " ; Time$ ; " " ; Date$
67
68
    ' Hauptschleife des Programms
69
    ' (kann weitere Anweisungen enthalten)
70
    Do
71
    Locate 1 , 1
72
    Lcd "Time: " ; Time$ ;
73
    Locate 2 , 1
74
    Lcd "Date: " ; Date$ ;
75
    'NOP
76
77
    Locate 2 , 17
78
    Lcd Sekunden
79
80
81
82
    Loop
83
    ' Programmende
84
    End
85
86
    ' Sectic-Programmteil
87
    ' wird durch den internen Timer automatisch jede Sekunde einmal aufgerufen
88
    Sectic:
89
90
    Portb.5 = 1
91
    Waitms 5
92
    Portb.5 = 0
93
    'Sekunden = Sekunden + 1
94
95
    If Dcf_status.7 = 1 Then
96
97
98
    If Sekunden >= 59 Then
99
    Sekunden = 0
100
    Cls
101
    Else
102
    Sekunden = Sekunden + 1
103
    End If
104
    End If
105
106
107
108
109
    'Print Time$ ; " " ; Date$
110
    Return

MfG

von sBronco (Gast)


Lesenswert?

Da kommt dir ein Interrupt während der LCD Anzeige in die Quere,
niemals ans LCD was schicken wenn ein Interrupt kommen könnte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.