Ich habe eine Steuerung für einen Belichter entworfen. Ich würde gerne den PIC aus dem Sleep Mode aufwecken indem man 5V an GP3 legt. Also über eine positive Flanke. Wie geht das? Ich würde mich über Vorschläge freuen. list p=12f629 #include <p12f629.inc> ; MCLR aus Power on Timer, kein Watchdog, int-Oscillator, kein Brown out, Code Protection aus __CONFIG _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _CP_OFF ;----------------------------------------------------------------------- - D equ 0x20 ; Variable für Schleife CounterA equ 0x21 ; Variable für Schleife CounterB equ 0x22 ; Variable für Schleife CounterC equ 0x23 ; Variable für Schleife CounterD equ 0x24 ; Variable für Schleife org 0x00 ; prg. beginnt an adr. 00(hex) goto main ; sprung an hauptprogramm marke ;----------------------------------------------------------------------- - main bcf STATUS, RP0 ; Bank 0 clrf GPIO ; aus movlw 0x07 ; comparator aus movwf CMCON ; alle Pins digital (nicht Comparator) bsf STATUS, RP0 ; Bank 1 clrf TRISIO ; alle output bcf STATUS, RP0 ; Bank0 ; interner Taktgenerator bsf STATUS, RP0 ; Bank 1 call 0x3FF ; get the calibration value movwf OSCCAL ; 4-MHz-Kalibrierung bcf STATUS, RP0 ; Bank 0 ;----------------------------------------------------------------------- - loopmain btfss GPIO,3 ; GP3=5V? (Start) goto loopmain ; nein bsf GPIO,0 ; ja (GP0=5V) -> Belichter ein call Wait1 ; 60s warten bcf GPIO,0 ; GP0=0V -> Belichter aus ; LED an GP2 blinkt und Summer an GP1 ertönt bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V sleep goto loopmain ; Abfrage für Neustart ;----------------------------------------------------------------------- - ;PIC Time Delay = 60,0000010 s with Osc = 4 MHz Wait1 movlw D'2' movwf CounterD movlw D'51' movwf CounterC movlw D'146' movwf CounterB movlw D'18' movwf CounterA loop1 decfsz CounterA,1 goto loop1 decfsz CounterB,1 goto loop1 decfsz CounterC,1 goto loop1 decfsz CounterD,1 goto loop1 return ;----------------------------------------------------------------------- - ;PIC Time Delay = 0,5000020 s with Osc = 4 MHz Wait2 movlw D'3' movwf CounterC movlw D'140' movwf CounterB movlw D'83' movwf CounterA loop2 decfsz CounterA,1 goto loop2 decfsz CounterB,1 goto loop2 decfsz CounterC,1 goto loop2 return ;----------------------------------------------------------------------- - org 0x3ff retlw 0x20 end
Hallo, Ich hab mach das zwar mit C, aber wenn im Sleep-Mode an GP2 eine positive Flanke kommt wacht er automatisch auf! Bin mir nicht sicher ob man ihn auch von den anderen Ports aus dem Sleep holen kann!
Heißt das ich muss einfach an GP2 ein positive Flanke anlegen und der PIC arbeitet weiter. Ich denke nur da muss man doch im Programm was schreiben damit das auch wirklich funktioniert. Oder einfach nur ne pos. flanke anlegen und funzt
einfach ne pos. flanke anlegen funzt net ich denke man muss im programm definieren das ein interrupt ausgelöst wird ich kann eure hilfe echt gebrauchen
HAb ich aber heute gemacht! Und hat Gefunzt. Mach mal vor dem Sleep GIE=0 und nach dem Sleep GIE=1!
Ja, und ich arbeite mit C: Hier die Initialisierung für den Interrupt an GP2:
1 | //GP2 Interrupt Init
|
2 | INTEDG = 1; //Rising Edge |
3 | INTE = 1; //Enable |
4 | INTF = 0; //Flag = 0 |
5 | GIE = 1; //Global Interrupt Enable |
Und hier der Wesentliche Teil meiner main-Routine:
1 | while(1) |
2 | {
|
3 | if((led_on == 1) && (led_dimmmode == 0)) |
4 | GPIO1 = 1; |
5 | if(led_on == 0) |
6 | {
|
7 | GPIO1 = 0; |
8 | GIE = 0; |
9 | SLEEP(); |
10 | GIE = 1; |
11 | }
|
12 | if(touchtime >= 5) |
13 | led_dimmmode = 1; |
14 | |
15 | }
|
Ich hab jetzt das Programm raufgeprogt Der Pic geht schon in den sleep mode nur wenn ich ihm eine negative Flanke gebe tut sich nix er will nicht aufwachen list p=12f629 #include <p12f629.inc> ; MCLR aus Power on Timer, kein Watchdog, int-Oscillator, kein Brown out, Code Protection aus __CONFIG _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _BODEN_OFF & _CP_OFF ;----------------------------------------------------------------------- - D equ 0x20 ; Variable für Schleife CounterA equ 0x21 ; Variable für Schleife CounterB equ 0x22 ; Variable für Schleife CounterC equ 0x23 ; Variable für Schleife CounterD equ 0x24 ; Variable für Schleife org 0x00 ; prg. beginnt an adr. 00(hex) goto main ; sprung an hauptprogramm marke ;----------------------------------------------------------------------- - main bcf STATUS, RP0 ; Bank 0 clrf GPIO ; aus movlw 0x07 ; comparator aus movwf CMCON ; alle Pins digital (nicht Comparator) bsf STATUS, RP0 ; Bank 1 clrf TRISIO ; alle output bcf STATUS, RP0 ; Bank0 ; interner Taktgenerator bsf STATUS, RP0 ; Bank 1 call 0x3FF ; get the calibration value movwf OSCCAL ; 4-MHz-Kalibrierung bcf STATUS, RP0 ; Bank 0 ;----------------------------------------------------------------------- - loopmain btfsc GPIO,3 ; GP3=5V? (Start) goto loopmain ; nein bsf GPIO,0 ; ja (GP0=5V) -> Belichter ein call Wait1 ; 60s warten bcf GPIO,0 ; GP0=0V -> Belichter aus ; LED an GP2 blinkt und Summer an GP1 ertönt bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V bsf GPIO,2 ; GP2=5V call Wait2 ; 0.5s warten bsf GPIO,1 ; GP1=5V bcf GPIO,2 ; GP2=0V call Wait2 ; 0.5s warten bcf GPIO,1 ; GP1=0V sleep goto loopmain ; Abfrage für Neustart ;----------------------------------------------------------------------- - ;PIC Time Delay = 62,0000020 s with Osc = 4 MHz Wait1 movlw D'2' movwf CounterD movlw D'61' movwf CounterC movlw D'193' movwf CounterB movlw D'105' movwf CounterA loop1 decfsz CounterA,1 goto loop1 decfsz CounterB,1 goto loop1 decfsz CounterC,1 goto loop1 decfsz CounterD,1 goto loop1 return ;----------------------------------------------------------------------- - ;PIC Time Delay = 0,5000020 s with Osc = 4 MHz Wait2 movlw D'3' movwf CounterC movlw D'140' movwf CounterB movlw D'83' movwf CounterA loop2 decfsz CounterA,1 goto loop2 decfsz CounterB,1 goto loop2 decfsz CounterC,1 goto loop2 return ;----------------------------------------------------------------------- - org 0x3ff retlw 0x20 end
Hallo, im STATUS register, oder war es im OPTION, eher da, gibt es ein bit, mit dem du WAKE_UP_ON_CHANGE einschalten kannst. Das brauchst du, aber ich weiss im Moment nicht, welcher Pin das ist, jedenfalls glaube ich bei dem MCU nur 1 pin, bei anderen MCU´s können es mehr sein. Noch was, vergiss das mit dem Sleep, sondern mach sowas, das ist besser. dosleep: sleep main: ..... goto dosleep
Mal sehen ob ich es noch zusammen bekomme. Eines meiner ersten Proggs war ein Minilauflicht mit 5 LED (Batteriebetrieben). Ich hatte damals auch den GPIO3 als Eingang benutzt um das Lauflicht aus dem Sleep aufzuwecken. Du brauchst tatsächlich den Interrupt. Als erstes musst du im IOC-Register den entsprechenden Pin maskieren, damit der zugehörige Eingang überhaupt auf Interrupts regiert.
1 | MOVLW B'00001000' ;GP3 (Taster) für Int einschalten |
2 | MOVWF IOC |
Dann musst du im INTCON-Register den GPIE und den GIE einschalten
1 | MOVLW B'10001000' ;GIE und GPIE ein |
2 | MOVWF INTCON ;Interupt für Taster freigeben |
Vorher musst du natürlich ab Adresse 0x04 eine Interruptroutine schreiben. Also Register sichern, das GPIF-Bit im INTCON-Register abfragen um zu sehen ob der Interrupt durch einen Taster ausgelöst wurde. Wenn ja, dann deine Befehle ausführen. Am Ende GPIF wieder zurücksetzen, Register zurücksichern und aus der Routine springen. Das Programm macht dann bei dem Befehl nach dem SLEEP weiter. Probiers mal aus. Gruß Sven
Sehe gerade, dass es natürlich noch das INT-Pin (GP2) gibt. Hier musst du im INTCON-Register das INTE-Bit einschalten (und natürlich das GIE-Bit). Mit dem INTF-Bit fragst du dann in der Interruptroutine ab, ob es der INT-Interupt war, der auslöste. Der INT-Interrupt arbeitet nur auf einer Flanke. Ob der Interrupt bei steigender oder bei fallender Flanke ausgelöst werden soll stellst du mit dem INTEDG-Bit im OPTION_REG Register ein (1=steigend, 0=fallend). Den INT Interrupt gibt es nur am GP2-Pin. Da ich aber den GP3-Pin damals benutzen wollte (er kann nicht als Ausgang geschaltet werden) hatte ich mich für den Interrupt on Change (IOC) entschieden. Der löst bei jeder Flanke aus und kann für jeden Pin (GP0-GP5) eingeschaltet werden. Ciao
Hab gerade bei sprut dazu noch etwas gefunden: --------------------- Der Sleep-Befehl versetzt den Prozessor in den stromsparenden stand-by-Mode. Durch die einige bestimmte Interrupts wird der PIC wieder geweckt. Falls das zum Interrupt zugehörige Interrupte-Enable-Bit gesetzt ist, läuft der PIC einfach im Programm weiter. Ist auch noch das GIE-Bit gesetzt, wird zusätzlich noch die Interruptbehandlungsroutine aufgerufen. --------------------- Heist also, dass das Programm einfach nach dem SLEEP weitermachen müsste, wenn man das GIE-Bit nicht setzt. Dann müsste man sich auch die ISR sparen können. Hab ich selbst aber noch nicht so ausprobiert. Sven
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.