Hi,
ich bin Anfänger und brauch da mal eure Hilfe.
Ich möchte gerne über ein interupt (RB0)den PIC in sleep setzten und
dann wieder aufwecken.
Interupt auslösen und in den sleep mode geth aber er wacht nihct mehr
auf.
Habt ihr irgendwelche ideen?
hier der code:
org 0
goto RESET
org 4 ;interupt on/off routine
inter
movf TMR0,0 ;TMR0
subwf 0x40,0
BTFSS STATUS,2
goto inter
BCF STATUS,2
movlw D'0'
movwf out
clrw
clrf TMR0
BSF INTCON,4
BSF INTCON,7
BCF INTCON,0
;btfss out,0 ;????
sleep
nop
RETFIE
nop
goto captime
RESET MOVLW B'00001111' ;
MOVWF CMCON
init bsf STATUS, RP0 ;
movlw B'00000001' ;
movwf TRISB
movlw B'11000111' ;
movwf OPTION_REG
bcf STATUS, RP0 ;
movlw B'10010000'
movwf INTCON ;
movlw B'00110001' ;
movwf T1CON
und wie gelangt er in den Interrupt: auch durch RB0 (das vermute ich mal
aufgrund der Programmierung des INTCON)?
Wie checkst Du, ob er überhaupt in den Interrupt gelangt. Checkst Du, ob
er aus der Schleife
1
inter
2
...
3
goto inter
herauskommt? (ich mache das immer mit diversen LEDs).
Noch ein paar Tips zur Lesbarkeit: Kommentare, Kommentare, Kommentare,
sonst weisst Du in 3 Wochen nicht mehr, was Du Dir dabei gedacht hast
(und wir sowieso nicht). Und schreib nicht INTCON, 4 sondern INTCON,
INTE bzw. nicht INTCON, 7 sondern INTCON, GIE, dann weiss man
leichter, was sich hinter dem Bit verbirgt.
Naja,
wenn der interrupt ausgelöst wird, springt er ja zu zeile 4.
das währe dieser part:
org 4 ;interupt on/off routine
inter
movf TMR0,0 ;TMR0
subwf 0x40,0
BTFSS STATUS,2
goto inter
BCF STATUS,2
movlw D'0'
movwf out ; alle LED aus
clrw
clrf TMR0
BSF INTCON,4 ;
BSF INTCON,7 ;interupt erlauben
BCF INTCON,0 ;flag zurücksetzen.
sleep
nop
RETFIE
nop
goto captime
hier werden dann alle ausgänge auf null gesetzt und der interrupt wieder
erlaubt.
leider wacht er dann aber (nach signal an RBO) niht wieder auf. habe
schon das manual gewälzt bin aber wohl zu blöd ihn aufzuwecken.
Werde mit eine andere schreibweise angwöhnen und die Kommentare mit
posten ;-)
Mach ich das so richtig oder kannst du mir nen tip geben?
ach ja die erste schleife ist zum "entprellen des tasters" an RB0
nter
movf TMR0,0 ;TMR0
subwf 0x40,0
BTFSS STATUS,2
goto inter
BCF STATUS,2
habe nen festen wert in 0x40 stehen den ich subtrahiere.
Hallo Dixi,
der Interrupt wird aufjedenfall ausgelöst jedoch geht der
Mikrocontroller in der Interrupt Routine selbst gleich wieder in den
Sleep-Modus ohne das diese korrekt beendet wurde! Somit ist ein zweites
Aufwecken schon unmöglich. Desweiteren ist nicht erkennbar wo deine
Register gerettet werden, Die Initialisierung sieht auch sehr kurz aus
und deine Leds im Programm angeschalten werden!
Mein Tip:
1. verwende die mitgelieferten zurgehörige INC-Datei in dieser stehen
alle Registernamen, welcher der Registeradresse bereits zugeordnet sind.
Dies erleichtert dir das programmieren erheblich und anderen die
Kontrolle ebenso.
2. Immer den ganzen Programmcode posten, damit man Initialisierung,
Eingabe, Verarbeitung und Ausgabe prüfen kann.
3. Ein kleine Beschreibung was genau das Programm tun soll ist immer gut
;).
Hier findest alles was du brauchst um den Interrupt erfolgreich zu
realisieren.
>>http://www.sprut.de/electronic/pic/int/int.htm
Im Interrupt wird das GIE ausgeschaltet, und durch das RETFIE
wieder eingeschaltet. Man kann es natürlich wieder einschalten,
um z.B. nested interrupts zu realisiseren, wenn man sich genug auskennt,
bringt aber auch Problematiken mit sich.
Um es kurz zu machen, setz ein Flag und im Hauptprogramm, check das Flag
und gehe dann in Sleep, vom Hauptprogramm, aber nie von einem Interrupt,
denn normalerweise sind dann die Interrupts ausgeschalten, und der
Prozessor
hat dann keine Möglichkeit mehr, nur mit Interrupts aufzuwachen, da
diese
ja ausgeschalten wurden. Andererseits, wenn du sie vor dem Sleep wieder
einschaltest, dann hast du einen kaputten Return-Stack.
Also merk dir, SLEEP niemals !!! im Interrupt verwenden.