Sida 1 av 2
Interrupt problem PIC16F690
Postat: 28 juli 2009, 14:53:56
av The_ChOsen
Hej!
Jag kör Asm i MPLAB på en PIC16F690 och försöker få igång ett interrupt från en knapp med pull-up motstånd.
Knappen är kopplad till RB4(pin 13).
Efter att bara fått knas när jag skickar programmet till PICen försöker jag med stimulus i MPLAB.
Init koden för interruptet:
Kod: Markera allt
banksel trisc
clrf trisa
clrf trisc
movlw b'01110000'
movwf TRISB
movlw b'10001000' ;Sätt GIE och RABIE
movwf INTCON
banksel IOCB ;Interrupt on change
movlw b'00010000' ;sätt för RB4
movwf IOCB
banksel option_reg
bsf OPTION_REG, INTEDG ; interupt on positive
Jag kör en mainloop men ett par NOPar som ligger och snurrar.
När jag simulerar en ändring på RB4 hoppar programmet till följande interrupt rutin:
Kod: Markera allt
INT_VECTOR CODE 0x004 ; interrupt vector location
nop
nop
clrf intcon ;Låt oss kalla denna A
; bcf INTCON, 0 ;Låt oss kalla denna B
nop
nop
retfie
När jag gör som i fall A går rutinen färdigt och hamnar i mainloopen igen. MEN det går inte att köra interruptet igen.
Gör jag som på sätt B så kommer man inte ur interrupt-rutinen alls.
Det verkar inte som INTCON vill ta emot förändringar i interrupt-rutinen.(förutom när man kör clrf)
Har letat och läst i databladet för 16F690, men inte hittat något som kan lösa problemet.
Det är säkert något enkelt som jag har missat...
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 15:21:12
av sodjan
> clrf intcon ;Låt oss kalla denna A
Varför ?
Och vad betyder kommentaren ??
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 15:33:10
av The_ChOsen
Eftersom INTCON inte förändrades när jag gjorde "bcf INTCON, 0" provade jag med clrf och då hände något iaf.
Men det är troligen för att någon annan bit(GIE?) inte är satt som det inte går att köra igen...
Kommentaren var för att enklare kunna hänvisa till koden i texten.
Bit noll i INTCON ska enl. databladet vara RABIF. Flaggan som sätts vid ett interrupt.
Eftersom jag kör med "Change Interrupt".
Måste man återställa något annat register när man hoppar ur interrupt-rutinen?
Kan det ha något med att jag simulerar att göra?
Ska testa att skicka programmet till pic igen...
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 15:40:13
av JockeE
clrf INTCON kommer ju att stänga av interrupt helt och hållet (GIE), så det är inte konstigt att interrupt ej fungerar efter detta.
Interrupt-on-change-funktionen kommer att fortsätta generera interrupt tills du läst av PORTB. Det räcker inte med att släcka RBIF.
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 15:44:50
av sodjan
Min fråga var varför du gör som du gör med INTCON, speciellt GIE.
Det verkar lite underligt, men ville veta om du hade någon speciell
anledning att göra som du gör...
> Eftersom INTCON inte förändrades när jag gjorde "bcf INTCON, 0"
Nej, självklart, GIE är redan "0" i det läget.
Sen, skriv *ALDRIG* INTCON, 0, använd de definierade symbolerna.
Speciellt i kod som du visa för andra...

Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 15:55:13
av JockeE
> Nej, självklart, GIE är redan "0" i det läget.
Det beror inte på det. Jag gissar att sodjan inte riktigt förstått problemet/frågeställningen. Anledningen till att "bcf INTCON, 0" inte föreföll att ändra något, var att ett nytt interrupt triggades igen direkt efter RETFIE-instruktionen. Detta eftersom PORTB inte lästs av.
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 16:00:52
av sodjan
> Anledningen till att "bcf INTCON, 0" inte föreföll att ändra något,
Inte bara föreföll, den ändrade faktiskt ingenting alls...
GIE = "0" innan RETFIE och den visade instruktion ändrade ingenting, exakt så som jag skrev.
Det hade inte heller med grundproblemet att göra, men det är ju en helt annan sak
och beror bara på att hanteringen av IOC inte har förståtts riktigt. Men som sagt,
det är en helt annan sak...
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 16:01:57
av The_ChOsen
JockeE: Mmm, det var som jag trodde, inte så konstigt.
Hittade ett avsnitt i databladet:
This interrupt can wake the device from Sleep. The user,
in the Interrupt Service Routine, clears the interrupt by:
a) Any read or write of PORTB. This will end the
mismatch condition.
b) Clear the flag bit RABIF.
A mismatch condition will continue to set flag bit RABIF.
Reading or writing PORTB will end the mismatch
condition and allow flag bit RABIF to be cleared. The latch
holding the last read value is not affected by a MCLR nor
Brown-out Reset. After these Resets, the RABIF flag will
continue to be set if a mismatch is present.
Var det det du menade?
Jag provade med att läsa PORTB till W. Vilket jag tolkade ur texten skulle göra skillnad.
Koden ser nu ut:
Kod: Markera allt
INT_VECTOR CODE 0x004 ; interrupt vector location
nop
nop
call send_my_text3
nop
nop
bcf INTCON, RABIF
movfw PORTB
nop
nop
retfie
Nu verkar det funka...

Gjorde tabben nyss att sätta goto istf call. Konstigt att det inte funka då
Ska prova att föra över till pic också...
sodjan: Det var ett desperat "try and error"

Har ändrat från "0" i koden nu. Förstår att det blir mer svårläst.
Ville bara vara säker på att jag ändrade rätt bit. RABIF ska det alltså vara.
Typ edit: Men bit "0" är väll RABIF?
Re: Interrupt problem PIC16F690
Postat: 28 juli 2009, 19:31:34
av sodjan
> Typ edit: Men bit "0" är väll RABIF?
Tja, du ser varför numeriska bitnamn inte är bra...

Re: Interrupt problem PIC16F690
Postat: 29 juli 2009, 02:56:14
av bos
Är det ingen mer än jag som reagerar över att det saknas kod för context save i författarens ISR?
Re: Interrupt problem PIC16F690
Postat: 29 juli 2009, 07:57:13
av The_ChOsen
bos: ISRen är lite fattig just nu. Främst för att jag ville få den att fungera över huvudtaget. Ska fixa "context save" under dagen när jag får tid.
Vad bör man spara undan? W och STATUS enl. nått exempel jag hitta...
Tack för hjälpen sodjan och JockeE!
Hade jag lusläst texten i databladet lite mer hade jag kanske hittat det.
Re: Interrupt problem PIC16F690
Postat: 29 juli 2009, 13:06:44
av sodjan
> Vad bör man spara undan? W och STATUS enl. nått exempel jag hitta...
Jag har för mig att alla datablad har ett komplett exempel för detta.
Re: Interrupt problem PIC16F690
Postat: 29 juli 2009, 14:20:07
av vfr
Det beror också på vad du använder dig av i avbrottsrutinerna. FSR är också ett lämpligt register att spara. Men använder man sig aldrig av det under avbrott, så kan man strunta i det. Men det är bra att ha så jag sparar det alltid.
Re: Interrupt problem PIC16F690
Postat: 31 juli 2009, 11:12:45
av The_ChOsen
Nu har jag frågor av lite annan karraktär.
Det är så att jag försöker bygga ett menysystem med 3 val och 2 knappar för att stega sig genom menyn.
"Menyval 1->Menyval 2->Menyval 3"
När man går förbi val3 ska man hamna på val1 igen och vise versa.
Det verkar funka klockrent i simuleringen. Det funkar även i PICen, fast inte lika klockrent.
Man hoppar runt lite hur som helst i menyn. Antar att detta har något med interrupt och timing att göra.
"Minska"-knappen funkar relativt bra. Men "Öka"-knappen hoppar nästan varje gång från val1 till val3 direkt.
Med lite teknik och timing går det att komma till val2 med denna också

(kan bero på att de behandlas olika i koden)
Finns det några generella tips när det gäller "Menyer"?
Eller det kanske tom. är något fel med min metod.
Jag har en variabel "MenyVal" som jag ökar eller minskar beroende på knapp.
ISR-kod:
Kod: Markera allt
INT_VECTOR CODE 0x004
;*** SAVE CONTEXT ***
movwf w_temp
movf STATUS,w
movwf status_temp
movf PCLATH,w
movwf pclath_temp
;SAVE END
movfw PORTB ;Buffra knapp tryckn.
movwf KnappVekt
movfw MenyVal ;Minska ej om val=0
btfsc STATUS,Z
goto $+3
btfss KnappVekt,4 ;Knapp 4? -> Minska val
decf MenyVal
nop
movfw MenyVal ;Öka ej om val=4
sublw h'04'
btfsc STATUS,Z
goto $+3
btfss KnappVekt,6 ;Knapp 6? -> Öka val
incf MenyVal
nop
movlw h'FF' ;Annars går inter. 2ggr(?!)
movwf PORTB
bcf INTCON, RABIF
;*** LOAD CONTEXT ***
movf pclath_temp,w
movwf PCLATH
movf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
;LOAD END
retfie
Mainloopen:
Kod: Markera allt
loop
movfw MenyVal ;Skriv menyval 1
sublw h'01'
btfsc STATUS,Z
call send_menyval1
movfw MenyVal ;Skriv menyval 2
sublw h'02'
btfsc STATUS,Z
call send_menyval2
movfw MenyVal ;Skriv menyval 3
sublw h'03'
btfsc STATUS,Z
call send_menyval3
movfw MenyVal ;Rotera menyn "upp->ner"
sublw h'04'
btfss STATUS,Z
goto $+3
movlw h'01'
movwf MenyVal
nop
movfw MenyVal ;Rotera menyn "ner->upp"
btfss STATUS,Z
goto $+3
movlw h'03'
movwf MenyVal
nop
goto loop
Jag kör med sodjans HD44780 kod som grund.
Kan man dela upp projektet i MPLAB så att man får makron och subs för LCDn i egna filer som man bara "includar"?
Och en sak till. Går det att få mplab att förstå att knapparna är aktivt låga? För när jag simulerar måste jag ändra från "btfss KnappVekt,6" till "btfsc KnappVekt,6".
Re: Interrupt problem PIC16F690
Postat: 31 juli 2009, 11:23:06
av sodjan
Jag tror inte att det har med menyerna i sig att göra.
Det låter mer som att du inte har en debounce-kod som passar dina knappar.
> Går det att få mplab att förstå att knapparna är aktivt låga?
Det är ju något som du så att säga bestämer själv. Om du vill
ha hög i vila och låg vid tryck, så är det bara att skriva koden
(och köra simuleringen) på det sättet.
> Kan man dela upp projektet i MPLAB så att man får makron och subs för LCDn i egna filer som man bara "includar"?
Inkludera fungerar, men det är inte så snyggt och det ger inga direkta fördelar.
Du kan ha subrutinerna i en egen fil och sedan kopplar du ihop det med "GLOBAL" och "EXTERN".
Kolla lite på dom så finns det säkert exempel. Lägg bara till alla filer till projektet så fixar
make-funktionen i MPLAB resten.