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