Forum: Mikrocontroller und Digitale Elektronik PIC18F14K50 - seltsames Verhalten bei Wake-up aus Sleep


von Alex H. (aheppis)


Lesenswert?

Servus zusammen,

ich habe einen PIC18F14K50.
Über den Timer 0 habe ich mir einen Grundtakt von ca. 10 ms gebaut und 
erledige dort mein Ablaufprogramm. Hier wird regelmäßig Timer 3 
zurückgesetzt, wenn Inputs erfolgen.
Bei längerem Ausbleiben von Inputs wird Timer 3 nicht zurückgesetzt und 
veretzt den PIC in den Sleep-Mode. Dies funktioniert auch so weit.
Aufgeweckt werden soll das ganze über den externen Interrupt INT0 an Pin 
16.
Den habe ich mit 10k auf Masse gezogen und will bei einer steigenden 
Flanke weitermachen.
So weit so gut.
Allerdings reagiert der PIC nach dem Sleep-Befehl ca. 7 bis 8 Sekunden 
auf gar nichts mehr. Die Zeit ist immer gleich.
Ab und an kommt der Interrupt direkt nach dem Sleep-Befehl durch - 
allerdings nur, wenn ich das Programm zum ersten Mal starte und auch nur 
das eine Mal. Danach habe ich dann immer die 7 bis 8 Sekunden Wartezeit.

Hat jemand eine Idee, was hier passiert? Ich stehe gerade total auf dem 
Schlauch...
Danke euch schon mal, für eure Hilfe!

von Jens M. (schuchkleisser)


Lesenswert?

Das liegt am Signal an Int0, und/oder am Quarz.
Entweder löst der Int nicht aus weil die Flanken zu luschig sind, oder 
du nutzt einen langsamen Quarz, der so lange braucht um hochzukommen.
Bei manchen PICs kann es vorkommen, das der erste Int den Quarz startet, 
aber wenn der Proz läuft ist der Int weg und nichts passiert. Der zweite 
Vogel fängt dann den Wurm weil der Quarz schon läuft.

Versuchs mal mit IntRC und poste deine Beschaltung am Int.

von Alex H. (aheppis)


Angehängte Dateien:

Lesenswert?

Danke schon mal für die Antwort.

Ich tu mir noch schwer vorzustellen, daß es daran liegt.
Ich nutze den internen Takt mit 250 kHz.
Die Beschaltung habe ich mal angehängt. Also recht simpel.
Und das Signal an INT0 ist eine ganz normale steigende Flanke, auf die 
ich reagiere - und davon gebe ich zum Versuch jede Menge ab. Die 
Reaktion erfolgt aber immer nach genau der gleichen Zeit.
Gegen den zu langsamen Quarz spricht doch, daß es manchmal funktioniert 
- warum ist er da dann schnell? Und wir reden ja immer von 7 bis 8 
Sekunden.

von Alex H. (aheppis)


Lesenswert?

Vielleicht noch kurz ergänzt.
Wenn die 7 bis 8 Sekunden nach dem Sleep-Befehl abgelaufen sind, dann 
kommt er sofort nach dem ersten Interrupt zurück.

von neuer PIC Freund (Gast)


Lesenswert?

Aus DS30000684B (45K50):

"However, a fixed delay of interval T_CSD following the wake event is 
still required when leaving Sleep and Idle modes ..."

Drinnen?

von Alex H. (aheppis)


Lesenswert?

Was meinst Du mit drinnen?

Aber 7 bis 8 Sekunden? Und warum manchmal sofort?

von neuer PIC Freund (Gast)


Lesenswert?

> Was meinst Du mit drinnen?

In dem unsichtbaren Sourcecode vorhanden?

> Aber 7 bis 8 Sekunden? Und warum manchmal sofort?

Die CPU braucht wohl ein paar Takte, bevor sie ordnungsgemäß 
Funktioniert.

von Alex H. (aheppis)


Lesenswert?

Ich hab mal nachgeschaut. Er braucht 1024 Takte plus 2 ms.
Bei 250 kHz entspricht das ca. 4 ms plus 2 ms. Damit bin sehr weit von 7 
bis 8 Sekunden entfernt.

Und das erklärt ja auch nicht, warum es nur manchmal passiert.

von Alex H. (aheppis)


Lesenswert?

Hab mal die Taktfrequenz auf 1 MHz erhöht - also Faktor 4.
Das ganze braucht immer noch ca. 8 Sekunden bis es da ist...

von Alex H. (aheppis)


Lesenswert?

Ok, bin ein Stück weiter.
Scheint ein Watchdog-Problem zu sein.
Hab den mal deaktiviert.

Jetzt klappt's aber immer noch nicht so ganz.
Der PIC geht in SLEEP und läßt sich durch den Interrupt aufwecken.
Allerdings nur einmal. Wenn er das nächste Mal in SLEEP geht, kommt er 
nicht mehr zurück.
Nach dem Interrupt setze ich folgende Bits und schalte den Interrupt 
wieder aus:

INTCONbits.INT0IF = 0;  // reset INT0
INTCONbits.INT0IE = 0;  // INT0 interrupt off for wake-up

Vor dem Sleep-Befehl setze ich das folgende und schalte den Interrupt 
wieder an. Habe ich da was vergessen? Es klappt nämlich nur beim ersten 
Mal.

INTCONbits.INT0IE = 1;  // INT0 interrupt on for wake-up

Danke euch schon mal :-)

: Bearbeitet durch User
von Alex H. (aheppis)


Lesenswert?

Ok, bin wieder weiter, aber nicht schlauer :-D

Ich hatte in der Interrupt-Routine die folgende Abfrage für den INT0 
drin:
if (INTCONbits.INT0IE && INTCONbits.INT0IF)

Das geht beim ersten Interrupt durch, beim zweiten aber nicht mehr.
Die Abfrage nach INT0IE macht Probleme. Das Bit ist beim zweiten 
Interrupt nicht mehr gesetzt, obwohl er kommt.
Jemand eine Idee warum?

Hab jetzt mal die Abfrage geändert - so funktioniert es:
if (INTCONbits.INT0IF)

von Florian P. (ol1cr0n)


Lesenswert?

Hallo,

welcher Befehl steht denn direkt hinter dem SLEEP?

Wenn ich das richtig im Kopf habe, wird auch bei aktiviertem GIE der 
nächste Befehl nach SLEEP ausgeführt. Erst dann springt der Controller 
in die ISR.

Gruß


EDIT:

Schau mal unter Kapitel "17.1.6 INTERRUPTS" im Datenblatt. Da stehts 
drin.

: Bearbeitet durch User
von Alex H. (aheppis)


Lesenswert?

Da steht an sich nichts mehr.
SLEEP() ist der letzte Befehl in der ISR-Routine des Timer 3.

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.