Forum: Mikrocontroller und Digitale Elektronik PIC 16F946 RTC Uhr sleep mode timer1interrupt weckt nicht auf


von coray (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich habe gerade ein Projekt am laufen. Folgendes: An meinem PIC 16F946 
ist ein RTC Quarz mit 32.768kHz über T1OSO/RA6 und T1OSI/RA7 
angeschlossen.
Über den Timer1 lasse ich jede Sekunde einen Interrupt aufrufen, wo er 
jeweils eine Sekunde hinaufzählt. Die ganze Sache wird danach auf ein 
7Segment LCD ausgegeben. Da das Gerät Batteriebetrieben ist würde ich 
den PIC gerne in den sleep mode setzen wenn nichts zu verarbeiten ist. 
(Stromsparen).
Mein Problem ist nun das der PIC über den Interrupt nicht mehr aufweckt. 
Alle nötigen Interrupt Bits sind gesetz.

Anbei, die ganze Firmware funktioniert einwandfrei mit dem Timer1 
Interrupt, nur eben nicht mit dem sleep mode.
Hat jemand schon ein ähnliches Problem gehabt?

von Michael S. (rbs_phoenix)


Lesenswert?

Ich weiß jetzt nicht genau, woran es liegen könnte. Was mir in den Sinn 
kam:
Vielleicht ist ja die Interrupt-Routine noch nicht vorbei, wenn der 
nächste kommt. Also dass da irgendwo zu lange gewartet wird. Ansich soll 
ja ein Interrupt-Routine so schnell wie möglich beendet werden.

Was mir noch aufgefallen ist:
1
if(min_high > 5)
2
{
3
min_low=0;
4
hour_low++;
5
}
6
if(min_low > 9)
7
{
8
min_low=0;
9
min_high++;
10
}

das min_low wurde doch kurz vorher schon geprüft. Muss das dann hier 
nicht hour_low sein? Das wird nämlich noch nirgends auf > 9 geprüft.

von coray (Gast)


Lesenswert?

Danke für den Hinweis. Du hast recht ich hatte zweimal das gleiche 
abgefragt.
1
if(min_high > 5)
2
{
3
min_high=0;
4
hour_low++;
5
}
6
if(hour_low > 9)
7
{
8
hour_low=0;
9
hour_high++;
10
}

Ich schreibe jetzt ein kurzes Programm mit wenig Code und schaue ob dies 
evtl. einen Einfluss auf den Interrupt hat. Vlt. ist es schon von der 
Grösse des Codes abhängig.

von tt2t (Gast)


Lesenswert?

mach mal hinter //SLEEP(); noch 2x NOP: wenn ein PIC in den SLEEP geht, 
dann ist der nächste Befehl nach dem SLEEP schon im Kern und es kommt 
(allerdings sehr selten) vor, dass dieser Befehl dann nicht ausgeführt 
wird.

von tt2t (Gast)


Lesenswert?

BTW: Das Programm ist für den 16F887 statt für den 16F946 geschrieben. 
Und lass den 32768-Quarz am Oszillator des Timer1 laufen statt am 
Hauptsoszillator. Schalte den interene Oszillator ein (z.B. mit 4 MHz), 
sonst kommst Du mit dem abarbeiten Deiner ISR nicht rum.

von coray (Gast)


Lesenswert?

Er ist definitiv im sleep mode der Controller verbraucht nur noch 176uA 
@3V (gemessen). Im normal Zustand verbraucht er 275uA @3V
1
do
2
{
3
SLEEP();
4
NOP();
5
NOP();
6
}while(1);

Wenn ich beim ersten NOP() einen breakpoint setze, kommt er nicht an. 
Sprich er geht auf direktem wege in den sleep mode.

von tt2t (Gast)


Lesenswert?

Du hast da eine Fliesskommaarithmetik in der ISR (!) drin
1
temp = ((adc_value*0.0024414)/0.023) ;
Die wird bei 32.768 nie fertig, kaum setzt Du im Interrupt TMR1IE = 1 
(danach kommt ja noch einiges wie time_calculation und put_display) ist 
schon der nächste Interrupt da (und Du bist aus dem vorherigen noch gar 
nicht draussen).

Deine ISR ist viel zu lang und der µC viel zu langsam getaktet.

von coray (Gast)


Lesenswert?

tt2t schrieb:
> BTW: Das Programm ist für den 16F887 statt für den 16F946 geschrieben.

Stimmt, hatte ich vergessen umzuschreiben ist eh auskommentiert ;)

tt2t schrieb:
> Schalte den interene Oszillator ein (z.B. mit 4 MHz),
> sonst kommst Du mit dem abarbeiten Deiner ISR nicht rum.

Es ist mir klar dass das ganze System langsam läuft. Ohne den sleep hat 
er ja genügend Zeit alles abzuarbeiten, zeigt einwandfrei aufs LCD an. 
Die Zeit ist acuh genau. Braucht die sleep Funktion zusätzliche 
Geschwindigkeit?
Danke

von tt2t (Gast)


Lesenswert?

Datenblatt 16F946 Page 259 (für den 16F887 sind es wenige µA mehr):

Bei 3 Volt sind 176 µA für SLEEP viel zu viel, das dürften höchstens 6-8 
µA sein, typisch wären nur 2-3 µA! Also kein SLEEP! Auch wenn der µC 
nicht im SLEEP ist, düfte er bei 3 Volt nur etwa 20-25 µA verbrauchen.

von tt2t (Gast)


Lesenswert?

Ich habe mal etwas genauer in Dein Programm geguckt.

Im SLEEP geht der Haupt-Oszillator aus, Dein Timer1 läuft also nicht 
weiter, weil Du den Takt für Timer1 aus dem Haupt-Oszillator holst und 
der PIC wacht nie mehr auf. Häng den Quarz an Timer1 (der hat einen 
eigenen Oszillator) und betreibe den µC sonst aus dem internen 
Oszillator.

von coray (Gast)


Lesenswert?

tt2t schrieb:
> Ich habe mal etwas genauer in Dein Programm geguckt.
>
> Im SLEEP geht der Haupt-Oszillator aus, Dein Timer1 läuft also nicht
> weiter, weil Du den Takt für Timer1 aus dem Haupt-Oszillator holst und
> der PIC wacht nie mehr auf. Häng den Quarz an Timer1 (der hat einen
> eigenen Oszillator) und betreibe den µC sonst aus dem internen
> Oszillator.

Oke, vielen Dank für deine wertvollen Tipps. Sind alles Sachen an die 
ich nicht gedacht habe(Geschwindigkeit). Bei der Stommessung war das LCD 
und der Debugger ICD3 auch noch dabei, daher der höhere Verbrauch.
Also kann ich den Quartz einfach auf den PIN RC5/T1CKI/CCP1/SEG10 und 
RA6/OSC2/CLKO/T1OSO verbinden? Intern natürrlich als Systemtakt nehmen 
(4MHz)

von tt2t (Gast)


Lesenswert?

Quarz und 2 Last-C an T1OSI und T1OSO (=RA6 und RA7), T1OSCEN setzen, 
TMR1ON setzen, TMR1CS setzen, ggf. TMR1GE (meist nicht), ggf. T1SYNC 
(meist nicht), ggf. Prescaler, internen Oscillator einstellen, bei den 
CONFIG-Bits INTOSC bzw. INTOSCIO setzen, den Rest hast Du schon gemacht 
(schau Dir die Bits/Register im Datenblatt Page 102 ff an).

von coray (Gast)


Angehängte Dateien:

Lesenswert?

tt2t schrieb:
> Quarz und 2 Last-C an T1OSI und T1OSO (=RA6 und RA7), T1OSCEN setzen,
> TMR1ON setzen, TMR1CS setzen, ggf. TMR1GE (meist nicht), ggf. T1SYNC
> (meist nicht), ggf. Prescaler, internen Oscillator einstellen, bei den
> CONFIG-Bits INTOSC bzw. INTOSCIO setzen, den Rest hast Du schon gemacht
> (schau Dir die Bits/Register im Datenblatt Page 102 ff an).

Hallo

Ist zwar schon eine Weile her, doch der Code funktioniert nun mit SLEEP 
mode einwandfrei..
Evtl. kann jemand den Code gebrauchen ;)

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.