PDA

View Full Version : Toggle program branch ussing interrupot by button?



CuriousOne
- 24th August 2013, 06:48
The idea is as follows.

When launched, the LOOP1 in program is working and doing something. If user presses the button, interrupt is generated and LOOP2 engaged. When button pressed again, LOOP2 terminates and LOOP1 starts.

Any example code?

HenrikOlsson
- 24th August 2013, 07:47
Have a flag (bit variable) which you toggle in the ISR.
In the main program you poll the flag and decide which subroutine (loop) to execute.
This will have the potential drawback of always finishing the current subroutine (loop) before switching, is that a problem?

/Henrik.

Acetronics2
- 24th August 2013, 09:24
with PBP "on interrupt" it looks this figure is covered in the manual @ $ 5.66 ( RESUME xxx ) : you can choose the "return" adress xxx as you want ... so LOOP2 always completes.

- also note if you do not clear the interrupt flag ( With a DEFINE ) you automatically re-enter the ISR when completed !

- For DT interrupts ... I didn't check if the resume address can be freely chosen ... ;)

- last idea is simply to overwrite the interrupt return address on the stack ... ( with asm "push" and "pop" macros see midrange manual, interrupts chapter ), depending on the button state.

Alain

CuriousOne
- 24th August 2013, 13:01
I don't want to include the button status check routine in the loops, since whole program works with microsecond delays and high accuracy. This is why I wanted to use interrupt. LOOP1 and LOOP2 are totally independent tasks, they don't use same variables, timings or whatsoever.

LinkMTech
- 24th August 2013, 19:00
That's a good question...

I wonder if something like this would work?




x VAR BIT

;----------------------- Setup Interrupts --------------------------------
INCLUDE "DT_INTS-18.bas" ; Darrel Taylor's Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT0_INT, Button_ISR, PBP, yes

endm
INT_CREATE ; Creates the interrupt processor
ENDASM

;----------------------[Initialise Interrupts]-----------------------
@ INT_ENABLE INT0_INT ; Enable Button interrupt input
x = 0 ' Clear button status flag bit

PAUSE 100
GOTO loop1 ' Start at loop1 routine

' ---------------- Independent program routines -------------------------
loop1_start:
@ INT_RETURN ; Reset the ISR

loop1:
' Perform one type of "time critical" function
GOTO loop1


loop2_start:
@ INT_RETURN ; Reset the ISR

loop2:
' Perform a different type of "time critical" function
GOTO loop2

;--------------------[Program routine selector ISR]----------------------
; make sure button signal debounced

Button_ISR:
x = !x ' Toggle x status flag bit

IF !x THEN
GOTO loop1_start ' Go here when x=0
ELSE
GOTO loop2-start ' Go here when x=1

@ INT_RETURN


Like Henrick said, the routines could be cut short anytime the button is pushed though.

CuriousOne
- 24th August 2013, 20:11
Thanks. As I can see, the code is for PIC18xxx family. Will it work on 12xx or 16xx ?

LinkMTech
- 25th August 2013, 01:19
Not for PIC12's or 16's.
You'll have to download DT's Interrupts for them here (http://darreltaylor.com/DT_INTS-14/intro.html)and replace entry with:


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


I was kinda hoping someone would point out my errors in my suggestion, if any, before you went too far into a possible dead end.

If you haven't tried DT's INTS, you're missing out on some awesome timing control when it comes to sequence of events. It took me a little while to understand but finally got some handle on it when I monitored two interrupts taking turns to run their routines, especially when one occurs while the other ISR is taking care of business.

HenrikOlsson
- 25th August 2013, 08:42
Hi,

I was kinda hoping someone would point out my errors in my suggestion, if any, before you went too far into a possible dead end.
Ok Louie, I'll take a stab at that if you wish... :-)

If the program is looping around in Loop2 (x=1) when the interrupt occurs the ISR will toggle x to 0 and then GOTO Loop1_Start.
At Loop1_Start there's an @INT_RETURN which will send it back into Loop2 since that's where it was when the interrupt occured.

/Henrik.

LinkMTech
- 25th August 2013, 16:45
Thanks Henrik, I stand corrected.

CuriousOne, I tried to do something like this in the past and thought I came up with a better idea all of a sudden, but to avail.

CuriousOne
- 25th August 2013, 16:51
I found a sample code here:

http://darreltaylor.com/DT_INTS-14/hello.html

The code is OK for me, since I also need a selected loop indication via led. What if I mod it a like this:



'---[INT - interrupt handler]---------------------------------------------------
ToggleLED1:
TOGGLE LED1
IF LED1=1 then goto LOOP1 ELSE GOTO LOOP2

LOOP1:

LOOP2:
@ INT_RETURN

LinkMTech
- 27th August 2013, 23:52
Sorry for the delay, but I don’t think that would be a good solution since the ISR should only spend enough time in there to update values, take readings, turn things ON/OFF, etc.. Pretty much just get in and get out.

Your example is like the one Henrik suggested but within the ISR.

But got another wild idea if your tight loop can sacrifice just a little time to test the ISR flag bit:


INT VAR BIT

INT = 0
'------------------------

loop1:
code
IF INT THEN GOTO loop2 ' Jump to loop2 after loop1 finished if interrupt triggered
GOTO loop1

loop2:
more code
IF !INT THEN GOTO loop1 ' Jump to loop1 after loop2 finished if interrupt triggered
GOTO loop2


; -------------- ISR toggles a flag bit ----------
Button_ISR:

INT = !INT

@ INT_RETURN


This way, I'm thinking, any one of the loops can complete it's mission before jumping to the other routine should an interrupt happen. Or just continue in it's loop until the button is pushed.

CuriousOne
- 28th August 2013, 17:02
LOL, I already did in the same way, just it became necessary to rise clock frequency to 32mhz. But I don't use any interrupts, and it works just fine.

LinkMTech
- 29th August 2013, 05:06
Hehe, that is funny.
Glad you got it going.

CuriousOne
- 14th September 2013, 09:58
Yes, but I still want to get with interrupts, because I have more choices to do with button, and putting many IF THENs slows down code considerably (it should run with 100 microsecond accuracy).