PDA

View Full Version : 16f688 interrupt



RHS_electronics
- 6th March 2009, 19:03
We are trying to set up a button interrupt on port Ra.5 on the 16f688 chip to light a led, this is the first time that we have worked with the innterrupt command, any suggestions? Will post the program that we have so far if necessary.

RHS_electronics
- 9th March 2009, 17:43
Trisa = 32
Trisc = 0

ioca=%10000000
a Var porta
c var portc

t1 var word
t1=200
start:

on interrupt goto buttonpressed
INTCON = %10000000
one:
gosub left:


goto one:

buttonpressed:
gosub All_on:


goto buttonpressed:
resume



'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''
'SUBROUTINES
left:
a=4:c=36
pause t1
a=0: c=0
pause t1
return

all_on:
a=7:c=63
pause t1
return

Here is the code, If i will help at all.

Darrel Taylor
- 9th March 2009, 18:53
Got a few problems there ...

For Interrupt on change with RA5, you need to set bit 5 of the IOCA register. You have bit 7 set.
ioca=%00100000
Then the PortA change interrupt needs to be enabled (RAIE)...
INTCON = %10001000In the interrupt handler (buttonpressed), you MUST read PORTA to end the mismatch condition, and clear the interrupt flag before exiting the handler. And it must exit the handler. You have a continuous loop in there, remove the goto.
buttonpressed:
gosub All_on:
dummy = PORTA ; clear mismatch condition
INTCON.0 = 0 ; reset interrupt flag
resume
Keep in mind that you will get an interrupt on both the Press and Release of the button. You will eventually need to change the interrupt handler to determine which Edge occurred.

RA5 is also a main oscillator pin. I assume you are using the internal oscillator .. just checking.

You should turn off the Analog functions when using Digital signals.
ANSEL = 0

And disable the comparators.
CMCON0 = 7

RHS_electronics
- 10th March 2009, 17:49
dummy = PORTA What do you mean by this?



Also we are trying to make the button, when pressesd, toggle between two subroutines, Exe: one press is the first one, then when you press it again it will go to the next program.

ps: yes we are using the internal oscillator

Darrel Taylor
- 10th March 2009, 20:16
dummy=PORTAWhat do you mean by this?
You'll need to have a BYTE variable
dummy VAR BYTE
At this point the variable isn't used for anything.
But by simply reading PORTA, it resets the Latches used to detect the change on the Port.

Without clearing the "Mismatch" condition, there's no way to reset the interrupt flag.
So as soon as you RESUME from the interrupt handler, it would jump right back into the interrupt again.
<br>

RHS_electronics
- 11th March 2009, 17:57
Trisa = 32
Trisc = 0


a Var porta:c var portc
x var word:t1 var word
dummy var byte

x=0
t1=200

ANSEL = 0
ioca=%00100000
CMCON0 = 7
start:

on interrupt goto buttonpressed
INTCON = %10001000
one:

gosub left


goto one

buttonpressed:
gosub All_on
dummy=porta ; clear mismatch condition
INTCON.0 = 0 ; reset interrupt flag


resume




'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''
'SUBROUTINES
left:
a=4:c=36
pause t1
a=0: c=0
pause t1
return

all_on:
a=7:c=63
pause t1
return

This is the code we have now and it still isn't working, the only thing it is doing is stopping the program where it is, What is wrong?

Darrel Taylor
- 11th March 2009, 20:42
Add DISABLE/ENABLE around the interrupt handler, and any subroutines called from the handler.
Without them, the interrupt handler will continuously interrupt itself.

DISABLE
buttonpressed:
gosub All_on
dummy=porta ; clear mismatch condition
INTCON.0 = 0 ; reset interrupt flag
resume
ENABLE

...

DISABLE
all_on:
a=7:c=63
pause t1
return
ENABLE

RHS_electronics
- 12th March 2009, 18:29
thank you for all of your help, but is there a way to make it so that when you press the button it loops one program continously then, when pressed again goes to another program?

Archangel
- 13th March 2009, 01:59
thank you for all of your help, but is there a way to make it so that when you press the button it loops one program continously then, when pressed again goes to another program?
Untested but worth a try:


Button_Flag VAR BIT
DUMMY VAR BYTE
Trisa = 32
Trisc = 0


a Var porta:c var portc
x var word:t1 var word


x=0
t1=200

ANSEL = 0
ioca=%00100000
CMCON0 = 7
start:

on interrupt goto buttonpressed
INTCON = %10001000
DISABLE
buttonpressed:
IF Button_Flag = 1 THEN
gosub All_on
ELSE
gosub LEFT
endif
dummy=porta ; clear mismatch condition
INTCON.0 = 0 ; reset interrupt flag

resume
ENABLE

'...

DISABLE
all_on:
a=7:c=63
Button_Flag = 1
pause t1
return
ENABLE

DISABLE
LEFT:
A=4 : c=36:
Button_Flag = 0
pause t1
a=0: c=0
pause t1
return
ENABLE

RHS_electronics
- 17th March 2009, 18:27
Trisa = 32
Trisc = 0


a Var porta:c var portc
x var word:x1 var word:x2 var word: x3 var word:t1 var word:

dummy var byte


t1=200

ANSEL = 0
ioca=%00100000
CMCON0 = 7
start:

on interrupt goto flag
INTCON = %10001000

one:


gosub left
goto one

two:

gosub all_on

goto two

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''
'SUBROUTINES
disable
flag:
x=1+x
x1=x//2
if x1=0 then
x2=1+x2
x3=x2//2
branch x3,[one_reset,two_reset]
endif
dummy=porta ; clear mismatch condition
INTCON.0 = 0 ; reset interrupt flag
resume
enable

disable
left:
a=4:c=36
pause t1
a=0: c=0
pause t1
return
enable

disable
all_on:
a=7:c=63
pause 100
return
enable

one_reset:
x=0
goto one

two_reset:
x=0
goto two



We finally got it working! Thanks for all of your help, it was greatly appreciated.