Forum: Mikrocontroller und Digitale Elektronik sleep bei 16F628


von marc989 (Gast)


Lesenswert?

Hi,
hänge seit einiger Zeit an folgendem Problem.
Zum stomsparen schicke ich den PIC in den sleep mode um über PIN B5 ihn 
wieder aufzuwecken.
Leider wacht er mir ununterbrochen auf, auch wenn ich das nicht möchte. 
Das heisst solange wie der Interrupt enable ist, schläft er nicht ein. 
Und wenn ich den Interrupt disable, wacht er nicht mehr auf.

hier ein stück test-code:

#include <16F628.h>
#use delay(clock=40000000)
#fuses NOWDT,XT, NOLVP, NOPROTECT

void main()
{
 enable_interrupts(int_rb);
 enable_interrupts(global);

 while(1)
 {
  output_high(Pin_A0);
   delay_ms(100);
  output_low(Pin_A0);
  sleep();
 }
}

von Franko P. (sgssn)


Lesenswert?

Hallo

das hier "enable_interrupts(int_rb);" enabled den Port change interrupt 
von PORTB und nicht nur von RB0, ich kenne deinen Compiler nicht, aber 
müsste es vielleicht heissen:

enable_interrupts(int_rb0); ?

Gerhard

von marc989 (Gast)


Lesenswert?

Hi Gerhard,

leider kann man keinen einzelnen Pin aktivieren. Kann man sowas 
vielleicht mit einem Inline Assembler realisieren?
An dem B Port (B4-B7) hängt nur der Programmer (B6+B7) sowie mein 
interruptpin B5 dran.
Das Oszilloskop zeigt an allen Pins ein LOW pegel. Trotzdem loopt das 
Programm permanent.
Wo ist der Fehler? Müsste ich alle Pins auf high pullen?
verwende den CCS compiler.

gruß marc989

von Schoaschi (Gast)


Lesenswert?

Hast du es schon mal mit den Tristate-Registern probiert?!

Was mich da nemlich etwas stört ist, dass du nie die Tris-Register 
setzt. Bei Output_high und Output_low ist es egal, da er es automatisch 
macht. Aber alle anderen sind weiters als Eingänge definiert. Dadurch 
sind keine definierten Potentiale an den Pins gegeben, wodurch 
einerseits der Pin Zerstört werden kann(wegen Querströmen im verbotenen 
Bereich) und andererseits eben keine fixe Aussage über den Portzustand 
getroffen werden kann(vl ist er High, vl auch low... und vl schwankt 
er).

Also... setz einmal die Trisregister so, dass alles auf Ausgang ist, bis 
auf deinen Eingang. SET_TRIS_A(xx); heisst der befehl.

Was sonst auch noch sein könnte ist, das das ISR-Flag gesetzt ist. Lösch 
dieses einmal ganz sicher bevor du ins sleep gehst. Ausserdem müsstest 
du ja dem PIC sagen, mit welchem Ereignis er aus dem sleep geholt 
wird... das sollte normal im OPTION Register stehen.

ich hoffe das bringt dir etwas weiter.

mfg Schoasch

von marc989 (Gast)


Lesenswert?

Hi,
hatte die Tris_Register auch schon gesetzt. Jedoch auf Eingang. Da die 
nichtbeschalteten Pins auf GND liegen. Könnte es aber zumindest für die 
programierpins mal mit output versuchen, das könnte ne Möglichkeit sein.
Um das Flag wer ich mich mal kümmern. Das setz ich wissentlich nie 
zurück. Müsste das dann hier wohl mit einem ASM befehl machen.
Hatte auch schon mal die ISR für den Interrupt eingebaut, da diese beim 
aufruf, so wie ich es verstanden hatte, den Flag automatisch cleared. 
Aber auch ohne erfolg.
Trotzdem Danke ich schau wegen dem Flag nochmal nach und berichte dann 
:-)

gruß Marc989

von marc989 (Gast)


Lesenswert?

Hi,

habe das Manual gelesen und da steht es drin. Schön wenn man internet 
hat. Jetzt hab ich es mal gespeichert damit ich es nachher zur hand hab. 
Man sollte also nicht aus dem Kopf programmieren :-)

- Um die RB pins gegen interrupt abzuschalten müssen sie als output 
geschaltet werden.
- den InterruptFlag kann/muss man in der ISR löschen durch lese/schreib 
zugriffe auf port B, oder durch direktes löschen des RBIF flags.

vielleicht klappts ja so.

Gruß Marc989

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.