Shop OBEX P1 Docs P2 Docs Learn Events
How do I call subroutines from an Interrupt? — Parallax Forums

How do I call subroutines from an Interrupt?

T&E EngineerT&E Engineer Posts: 1,396
edited 2007-09-23 01:56 in General Discussion
I have an sx·program very much like the basic stamp 74HC595 #23 (I beleive) that simple turns 1 LED on in sequence till it reaches the end of the LEDs and then it reverses direction to the begining of the LEDs and repeats itself - like the KIT car lights. I my case I have (5) 8x8 Bidirectional LED Matrixes of which I am wanting to go through all 40 LEDs in the same fashion. My program works so far well. I am not using 74HC595's but Allegro Microsystem A6821's which are almost identical in operation and connections. However, it is more like a serial version of ULN2803's. So now to cycle through 40 LED columns·(*2 because they are bi-colored = 10 A6821's), I only need 3 control lines being CLOCK, DATA IN and STROBE. The A6821's also have /OE to turn on·or off individual A6821's for either RED, GREEN or YELLOW color sets for each LED matrix module.

OK, now that you know a little bit about the hardware and the software which works well, I need to know how to take the main program which calls subroutines and put all of that into an LED scanning routine inside of an interupt. As seen in other LED display programs (like JonnyMac's BADGE.sxb program for the RoboGames medal, a scanning routine is needed inside of an interrupt. Once this is working, I can then send the display messages across the 8 LED Matrix rows (which have P channel FETs for good current control and brightness).

Hopefully you have been able to follow what I am wanting to do and can help. When I try to copy the main program into an Interrupt, it has a problem when trying to call subroutines from within the interrupt. Sure I can not use subroutines and just insert the code directly in, however, the program is large enough to begin with and to add individual routines directly into main program within the Interrupt would make it large and might have some timing issues as it is scanning 40 LED columns.

Any ideas?

Comments..

Thanks for your support.

Comments

  • BeanBean Posts: 8,129
    edited 2007-09-22 12:18
    You need to do something like this:

    INTERRUPT
      GOTO Int_Start
    
    MySub SUB 1
    
    Int_Start:
      ' Do whatever
      MySub 5
    RETURNING
    
    SUB MySub
      ' Do whatever
    ENDSUB
    

    Bean


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I know what I know, don't confuse me with the facts...
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • T&E EngineerT&E Engineer Posts: 1,396
    edited 2007-09-22 19:14
    Bean,

    I tried that but their were SUB errors stating something about the address is not· in the lower half of memory.

    Could this be because of the other SUB statements in the program?

    I have attached the program. I have copied the information into the ISR Start routine and renamed it.

    Please help.
  • JonnyMacJonnyMac Posts: 9,216
    edited 2007-09-22 19:33
    I have used subroutines in interrupts -- it can be done if you're more careful setting up your SX/B program. Let me suggest an easier strategy (that PJV uses in his programs): Instead of doing a bunch of work in your interrupt, just have it set a flag bit:

    INTERRUPT NOCODE 2500
    
      \ SETB  isrFlag
      RETURNINT
    


    Then, in your main code you wait for the flag, clear it and do whatever you want done on that schedule

    Main:
      \ JNB isrFlag, $
      \ CLRB isrFlag
      
      ' other work here
    


    You can use that same flag to count ISR activations to create the desired delay.
  • BeanBean Posts: 8,129
    edited 2007-09-22 19:36
    You must move ALL of the subroutine declarations up to where you declare "OUT_INT" and "WAIT_INT".

    Subroutine declarations must be in the first half of the code page, your interrupt code pushes them down below that.
    P.S. REVERSE is a command, if you make a SUB with the same name, you will not be able to use the REVERSE command in your program. It will always assume you want to call the REVERSE subroutine.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I know what I know, don't confuse me with the facts...
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • T&E EngineerT&E Engineer Posts: 1,396
    edited 2007-09-22 21:46
    I have the program running in the Interrupt now as it did before when it was in the main program. It currently just cycles 1 led on at a time until it reaches the 40th led and then restarts again to the first led and so on.

    However, I'm still not sure the interrupt is working. If the Interrupt is set for:

    INTERRUPT 10000

    Does this not mean that it only run every 10 seconds? Obviously I want to run it faster but as a test I would think this is true. It currently runs like it did before as if it was in a loop or something. The DelayTime it set so that it·cycles on and off·through all 40 leds in·under second or so.

    I also am not going to use the REVERSE routine as this was only for testing.

    I have attached the modified code.

    Thanks.
  • BeanBean Posts: 8,129
    edited 2007-09-22 21:58
    "INTERRUPT 10000" means to run the interrupt 10,000 times per second. Not once every 10 seconds.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I know what I know, don't confuse me with the facts...
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com
    ·
  • Bashar SadigBashar Sadig Posts: 10
    edited 2007-09-23 01:56
    Anytime I hear anything about LEDs, especially in your case (40 LEDs), I suggest using an external chip I2C or SPI that is designed to work with a microcontroller like the SX.
    The best I have tried so far and very reasonably simple to interface serially via 3 wires only form the SX or any microcontroller. I was able to connect 8 7Segment LED Displays (8x7=56) and manged to control fading, sweep, selective segment control all va serial commands.

    Recommendation: Use interrupt only to manage timing and flags in addition to communications
    Recommendation: Use an external dedicated chip to drive loads. Preferably one that can be serially controlled.
    Recommendation: As I mentioned the Maxim as an example, there are many other chips I have not experimented with yet. Even with the ULN, it does require parallel input so it is not my first choice.

    Doing so, I was able to reduce component count and simplify circuitry.

    Serially Interfaced, 8-Digit LED Display Drivers. Suprisingly simple to use
    Maxim: MAX7219 Attached Documentation

    You can Fade, Display BCD, and control display of arrays and matrixes. Biggest advantage is you only need 1 resistor on supply current. this helps alot.

    Cheers



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bashar Sadig

    Senior Solutions Architect - Enterprise Applications
Sign In or Register to comment.