PDA

View Full Version : Help! My 'interupt', erhm ...only interupts the one time?!!!



HankMcSpank
- 2nd November 2009, 01:37
Ok, I've spent a good couple of hours trying to revise hos the whole DT interupt fits together (I never really got it the first time, still haven't but hey - the world loves a trier!)

Ok, I have my interupt working - of a sort. By this I mean my program reacts to the button I have wired to the 'INT' EXT interupt pin on my 16F690 (pin 17) ...but my program only responds to the associated button being pressed the once?!

No matter how many times (Or for how long I hold down) I press the button connected to th4e INT pin - I don't get anymore interupts.

I'm puzzled.

My program is a little unwieldly (so is my programming!), but here (I think!) are the relevant extracts..



@MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
@MyConfig = MyConfig & _MCLRE_OFF & _BOR_OFF
@ __config MyConfig

INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts


OSCCON = %01100000 ' 4MHz internal osc
ANSEL = %11000000 ' AN2 &AN7 = Analogue (for AtoD), the rest digital
ANSELH = 0
ADCON0 = %10001001 ' Right justify, channel AN2, A/D enabled
CM1CON0 = 0
CM2CON0 = 0
VRCON = %00000000 ' turns the Vref Module OFF by CLEARING bit7, 6, 4
INTCON.0 = 0 ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
RCSTA.7 = 0 ' clears the SPEN bit ( SETTING SPEN DISABLES RB7 AS GENERAL PURPOSE! )
OPTION_REG.6 = 0 ' this allows interupts on falling edge (high to low transitions)

TRISA = %00000100 ' RA2 input, rest out
TRISC = %00001100 ' RC3, RC4 inputs, rest outputs
sustainer_state VAR BYTE

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _OnOff_Switch, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE INT_INT ; enable external (INT) interrupts

sustainer_state = 0

Sustainer_on:

(my program does stuff here - not relevant to the question I'm posing!)


Sustainer_off:
Pause 500
Goto sustainer_off ' just keep looping until we get another interupt



'---[INT - interrupt handler]---------------------------------------------------
OnOff_Switch:
sustainer_state = sustainer_state +1
IF sustainer_state = 1 then GOTO sustainer_on
if sustainer_state !=1 then
SUSTAINER_STATE = 0
goto sustainer_off
endif
@ INT_RETURN




Any top tips greatfully received?

or even a more elegant way of trying to crack this meagre nut! I just want a simple push button interupt to stop my program (& just loop) until the next 'interupt (button press) comes in.

Jerson
- 2nd November 2009, 02:05
Your interrupt code CANNOT afford to loop. You have to exit the interrupt for the next one to be recognized. For this, you need to have all your interrupt code exiting via the INT_RETURN statement. You may use a flag to decide whether you got the first switch press or the second and accordingly allow your processing function.

This is what I would think your code should be doing.



On switch press interrupt, do switch press ISR code
main:
If AllowSustain then
gosub DoSustainCode ' if AllowSustain says, do it!!!
endif
goto main

SwitchPressISR:
' toggle the AllowSustain (bit) flag everytime the switch is pressed
if AllowSustain then
AllowSustain = 0
else
AllowSustain = 1
endif
@ INT_RETURN ' always return from the interrupt

HankMcSpank
- 2nd November 2009, 07:49
Many thanks for the reply.

I understand what you are saying - ie that the interupt, must not loop......therefore when the interupt button/switch is pressed, the program must jump to the interupt service routine, do something non loopy & return to the main program cleanly?

This is causing me real headaches!

As I say, I am new to programming... if the interupt service routine only allows say the changing of a status bit (or the contents of a variable), then that must mean my main program needs to check (poll) the status bit (or variable) at regular intervals to see if anything has changed - which surely kind of negates the purpose of an interupt?!

To strip this back to the barebones ....all I seek is an interupt driven on off switch .....ie 'on' & my program runs, 'off' & my program waits. I can't be the first to want such basic functionality....has anyone done/seen some example code they can link me to?

Jerson
- 2nd November 2009, 07:58
You understood the concept very well. Now, whether you use a RTOS or just plain vanilla coding with interrupts, you will almost always end up using signals(messages in rtos) to indicate occurance of events. Now, that said, the microcontroller executes several instructions every second and appear to happen nearly in synch with your input (unless you are superhuman ;) ) Due to that, even though you are polling for an event in the main loop, you will capture it within a few 100uS of your switch operating. You might even be able to capture the switch bounce if your code is optimum. So, do not fear, give it a roll and let us know if it helped.

Another option is to use the BUTTON command of PBP in a tight main loop to decide if you need to run your routine. Use no interrupts at all.

HankMcSpank
- 2nd November 2009, 08:35
Many thanks Jerson

(btw I used your ISR - much easier on the eye & it works a treat!)


One other quick question (to the forum in general) - I have the need for two more external momentary push switches to interface with my program ...I'd also like to use interupts with these - what other input pins can I use? (I've now used the INT_INT pin ...which is an external interupt), but to my untrained eye, it's not easy to establish which other PIC pins would be good contenders.

I'm using a 16F690.

Kamikaze47
- 2nd November 2009, 12:49
Many thanks Jerson

(btw I used your ISR - much easier on the eye & it works a treat!)


One other quick question (to the forum in general) - I have the need for two more external momentary push switches to interface with my program ...I'd also like to use interupts with these - what other input pins can I use? (I've now used the INT_INT pin ...which is an external interupt), but to my untrained eye, it's not easy to establish which other PIC pins would be good contenders.

I'm using a 16F690.

You could use the PORTB change interrupt which will trigger any time PORTB is changed, and have code in the interrupt handler that checks to see which pin(s) were pulled low (or high depending on if you are using pull up or pull down resistors).

Is it extremely time dependant that you need an interrupt? I almost never use interrupts for buttons because polling is generally just as good because of the fact that a human is pushing the button and therefore exact timing is out the window anyway.