Forum: Mikrocontroller und Digitale Elektronik Atmega8 misst die Zeit nicht richtig


von Martin Zippel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo werte Forengemeinde,

ich habe ein altbekanntes Problem, komm aber auch nach langer Suche 
nicht auf einen grünen Zweig:
Ein Atmega8 soll jede Stunde für 5 Minuten ein Gerät anschalten. Den 
Grundaufbau habe ich so weit hinbekommen, geschaltet wird über einen 
MOSFET, als Display dient eine SSA mit vier Stellen.
Den Schaltplan hänge ich an.

Probleme bereitet mir aber die genaue Sekunde:
Ein Quarz der Frequenz 7372800 Hz soll's richten. Die Einstellungen 
Prescale = 64, Startwert Timer1 = 7936 sollten jeweils Schritte im Takt 
halber Sekunden sein, sind tatsächlich aber langsamer.
Die Einstellungen Prescaler = 256, Startwert Timer1 = 36736 sollten den 
Interrupt nach jeweils einer Sekunde auslösen, sind aber sehr viel 
langsamer (etwa halb so schnell, lösen also (in etwa) jede zweite 
Sekunde aus).

Als Kondensatoren am Quarz habe ich zwei 22pF-Kerkos verwendet, da ich 
auch nach langer Recherche nicht wusste, ob die beiden nun genau 
berechnet werden müssen, oder 22pF "schon ok" sind. Zu genau muss es 
auch gar nicht sein, reicht, wenn die Uhr pro Tag nicht mehr als 3 
Minuten falsch geht.

Die Fusebiteinstellungen lauten
1
CKSEL3 = 0
2
CKSEL2 = 0
3
CKSEL1 = 0
4
CKSEL0 = 0

Mein Quellcode in Bascom (ich verzichte auf die Unterprogramme, welche 
nur den Code für die SSA-Anzeige enthalten)
1
$regfile = "M8def.dat"
2
$crystal = 7372800                      'Frequenz des Kristalls
3
4
Config Portd = Output
5
Config Portb = Output
6
7
'Timer-Variablen
8
Ledrot Alias Portd.5
9
Ledrot = 1                              'Test-LED ist immer an
10
Testled Alias Portd.6                   'zeigt Status
11
Dim Anzahl As Integer                   'zaehlt die Sekunden
12
Dim Zaehler As Bit
13
14
'Timer-Einstellungen
15
Enable Interrupts                       'Interrupts aktivieren, damit Timer einen Interrupt auslösen kann
16
Config Timer1 = Timer , Prescale = 64   'welcher Timer soll verwendet werden, Prescaler einstellen
17
Enable Timer1                           'Timer1 aktivieren
18
On Timer1 Zaehlen                       'Was passiert bei Timer-Overflow (also Timer-Ereignis)
19
Timer1 = 7936                           'Startwert für Timer nach jedem Überlauf
20
21
'SSA-Variablen
22
Dim Onoff As Integer                    'Art der Anzeige
23
Dim Zeiton As Integer                   'Variable für Anzeit
24
Dim Zeitoff As Integer                  'Variable für Auszeit
25
Dim Zehner As Integer                   'Zehnerstelle
26
Dim Einer As Integer                    'Einerstelle
27
Dim Punkt As Bit                        'Doppelpunkt nach jeder Sekunde an/ausschalten
28
Const Wartezeit = 1                   'wie lange beim Multiplexen gewartet werden soll
29
30
'Subprogramme mit Parametern deklarieren
31
Declare Sub Zahl(l As Integer)
32
33
34
'Hauptprogramm
35
Do
36
Zehner = Anzahl \ 10                    'Zehnerstelle errechnen
37
Einer = Anzahl Mod 10                   'Einerstelle errechnen
38
39
Gosub Worton
40
Gosub Zehnerstelle                      'Zehnerstelle anzeigen
41
Gosub Einerstelle                       'Einerstelle anzeigen
42
Gosub Doppelpunkt                       'Doppelpunkt anzeigen
43
Loop
44
45
End
46
47
'Subprogramme
48
Zaehlen:                                'was passieren soll bei Timer-Überlauf
49
   Toggle Testled
50
   Toggle Punkt                         'Doppelpunkt an- oder ausschalten
51
52
   Toggle Zaehler
53
   If Zaehler = 1 Then Anzahl = Anzahl + 1
54
Return

Könnt ihr mir weiterhelfen? Es ist mein erster Versuch, eine Uhr mit dem 
Atmega zu bauen, weshalb ich, nachdem ich an Aufbau, Code und Fusebits 
keinen Fehler mehr finden kann, keine Idee mehr habe, woran es liegt.

Ich freue mich auf eure Antworten,
Martin

von holger (Gast)


Lesenswert?

>On Timer1 Zaehlen                       'Was passiert bei Timer-Overflow >Timer1 
= 7936                           'Startwert für Timer nach jedem >Überlauf

Vergiss Overflow und nimm CTC. Sonst wird das nie genau.

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

sollte das da,

Timer1 = 7936     'Startwert für Timer nach jedem Überlauf

nicht eher in der ISR stehen !!

Sascha

von Martin Zippel (Gast)


Lesenswert?

Sascha, du hast natürlich Recht.

Ich war in dem Glauben, dass der Befehl    Timer1 = 36736 zu Beginn des 
Programms dem Timer jedes Mal diesen Wert als Startwert vorgibt.
Nachdem ich den Befehl in die Interrupt-Routine schrieb, funktioniert es 
jetzt sehr gut.
Die CTC-Sache werde ich mir ansehen, sobald ich den Schaltplan etwas 
hübscher gezeichnet habe.

Vielen Dank an Euch,
Martin

von Martin V. (oldmax)


Lesenswert?

Hi
Ich kenn mich zwar mit Bascom nicht aus, aber die Zahl 7936 sieht mir um 
1 zu groß aus. Die Controller fangen an, bei 0 zu zählen, das ist auch 
der Grund, warum uns die Digitaltechnik 9 Finger gönnt. (0-9=10 Ziffern)
Ich denke, du wirst noch genauer, wenn dein Wert 7936-1 ist.
Gruß oldmax

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.