Forum: Mikrocontroller und Digitale Elektronik Timer1 läuft nicht an bei Uhrenquarz


von Jens (Gast)


Lesenswert?

Hallo Leute,

ich baue gerade mit dem PIC16F27A eine Uhr. In einem anderen Thread 
(Beitrag "Uhrenquarz und PIC16F627A") wurde mir nahegelegt, das 
mit dem Timer1 und einem 32kHz Uhrenquarz zu versuchen. Also gut.

Ich habe den Quarz an RB6 und RB7 mit 15pF-Kondensatoren angeschlossen, 
und im Code den Timer so initialisiert:
1
// einschalten
2
TMR1ON = 1;
3
4
// Vorteiler auf 1:8
5
T1CKPS0 = 0b1;
6
T1CKPS1 = 0b1;
7
8
// arbeite als Timer und NICHT als Counter
9
TMR1CS = 0;
10
11
// verwende externen Takt von RB6, RB7
12
T1OSCEN = 0b1;
13
14
// erzwinge Interrupt
15
TMR1IE = 0b1;
16
17
// global Interrupts aktivieren
18
GIE = 0b1;

Ansonsten nutze ich im Code noch Software-PWM (das aber unabhängig vom 
Timer1 ist, und ein paar Zeilen weiter oben initialisiert wird).

Meine ISR sieht so aus:
1
void interrupt isr (void) {
2
3
  if (TMR1IF) {
4
    t++;
5
    if (t >= 4096) {
6
        t = 0;
7
        Sekunden++;
8
    }
9
    TMR1IF = 0;
10
  }
11
12
}

Aber nix passiert. Die ISR wird nicht aufgerufen. Habe testweise die 
Variable Sekunden in der Main über einen Taster erhöht, und da 
funktionierte es. Wenn die Initialisierung OK ist (ist sie?) liegt es 
wohl daran, dass der Uhrenquarz nicht schwingt. Was könnte ich da tun?

Gruß
Jens

von Icke (Gast)


Lesenswert?

Quarz ungleich externer Takt.

von Jens (Gast)


Lesenswert?

Hallo!

Icke schrieb:
> Quarz ungleich externer Takt.

Du meinst wahrscheinlich diesen Teil:

Jens schrieb:
> // verwende externen Takt von RB6, RB7
> T1OSCEN = 0b1;

Damit sage ich dem PIC nur, dass er die interne Oszillatorschaltung 
nicht ausschalten soll, d.h. er soll damit rechnen, dass an  RB6 und RB7 
ein Quarz angeschlossen wird. Ist da ein Gedankenfehler?

Gruß
Jens

von Jens (Gast)


Lesenswert?

Mir wurde anderweitig geholfen, aber ich dachte, ich erwähne mal die 
Lösung:

Das Bit PEIE war noch nicht gesetzt. Ohne den wird der Interrupt beim 
Überlauf des Timer1 nicht wirksam. Hier der funktionierende Code, der 
mit einem 32768Hz Uhrenquarz mit zwei 15pF nach GND 0.5Hz produziert:
1
// Vorteiler auf 1:1
2
T1CKPS0 = 0;
3
T1CKPS1 = 0;
4
5
// verwende externen Takt von RB6, RB7
6
TMR1CS = 1;
7
T1OSCEN = 1;
8
9
// erzwinge Interrupt
10
TMR1IE = 1;
11
12
// periphere Interrupts aktivieren
13
PEIE = 1;
14
15
// global Interrupts aktivieren
16
GIE = 0b1;
17
18
// einschalten
19
TMR1ON = 1;

Die ISR wird nun also mit 32768Hz  255  255 = 0.5Hz aufgerufen. 
Schöner wären 1Hz, weiß jemand, wie das geht? Ich müsste dem Timer1 
sagen, dass er bei der Hälfte aufhören soll zu zählen, oder bei der 
Hälfte anfangen soll.

Gruß
Jens

von holger (Gast)


Lesenswert?

>Schöner wären 1Hz, weiß jemand, wie das geht? Ich müsste dem Timer1
>sagen, dass er bei der Hälfte aufhören soll zu zählen, oder bei der
>Hälfte anfangen soll.

Datenblatt Kapitel: Resetting Timer1 using a CCP Trigger Output

von Jens (Gast)


Lesenswert?

Ja aber CCP kann ich nicht mehr nehmen weil ich das auf PWM konfiguriert 
habe.

Gruß
Jens

von holger (Gast)


Lesenswert?

>Ja aber CCP kann ich nicht mehr nehmen weil ich das auf PWM konfiguriert
>habe.

Dann ändere das. Du könntest Timer1 zu Fuss in der ISR auf 32768 setzen,
aber dann läuft die Uhr nicht mehr genau. Sieh zu das du das PWM in
Software machst.

von Jens (Gast)


Lesenswert?

Hmm, auf Software-PWM umzusteigen ist doch auch irgendwie Murks. Da kann 
ich lieber den Timer manuell setzen und mir ein zwei Takte Zeitfehler 
einhandeln...

Jens

von holger (Gast)


Lesenswert?

>Hmm, auf Software-PWM umzusteigen ist doch auch irgendwie Murks. Da kann
>ich lieber den Timer manuell setzen und mir ein zwei Takte Zeitfehler
>einhandeln...

Wenn du meinst. Musst halt sehen wie falsch deine Uhr damit läuft
und ob du damit leben kannst.

von Jens (Gast)


Lesenswert?

Naja, fürs Erste wird sie sowieso nur Stunden und Minuten anzeigen, und 
dann ist es egal. Mal gucken..

Gruß
Jens

von Hans W. (stampede)


Lesenswert?

@Holger: Die CCP Variante geht zwar, bringt aber nix. Das (Vor-)Laden 
des Timers ist besser und man handelt sich auch keinen Fehler ein, denn:
Nach dem Ueberlauf springt der Timer von 0xffff auf 0x0000 um. Die ISR 
wird aufgerufen, bis dahin ist der Timer vllt bei 0x0001 oder 0x0002. 
Mit dem Befehl
>TMR1H |= 0x80;
Wird nun einfach das MSB gesetzt, sprich die Zaehlperiode halbiert ohne 
dass die LSBs angefasst werden. Und voila, alles ist gut!

>Dann ändere das. Du könntest Timer1 zu Fuss in der ISR auf 32768 setzen,
>aber dann läuft die Uhr nicht mehr genau. Sieh zu das du das PWM in
>Software machst.
Software PWM wenn man ein Hardwaremodul hat... ja nee ist klar! Die 
Resourcenverschwendung kannste doch keinem verkaufen!
Zudem: Selbst WENN man sich paar Takte Fehler einfangen wuerde (was ja 
nicht der Fall ist), dann waere der Fehler konstant und laesst sich 
rauskalibieren.

Gruss
Stampede

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.