Hot to handle multiple interrupt sources?


Closed Thread
Results 1 to 18 of 18
  1. #1
    Join Date
    Apr 2013
    Posts
    32

    Default Hot to handle multiple interrupt sources?

    Hi guys, I'm working on a project and using PIC16F877A. I need to use multiple interrupts sources as TMR0, TMR1, RB0 etc. but i don't know how to proccess them in different interrupt routines. Is there any way to direct them to releated interrupt routine other than polling their interrupt flags?
    I mean, I know following codes won't work but is there a way to use interrupts like following codes,

    Code:
    ON TMR0 INTERRUPT GOTO tmr0_int
    ON TMR1 INTERRUPT GOTO tmr1_int
    ON RB0 INTERRUPT GOTO rb0_int
    Or do I must use polling methode like following

    Code:
    ON INTERRUPT GOTO INTCHCK
    ....
    ....
    INTCHCK:
    IF INTCON.2=1 THEN
    GOTO tmr0_int
    ENDIF
    IF PIR.0=1 THEN
    GOTO tmr1_int
    ENDIF
    IF INTCON.0=1 THEN
    GOTO rb0_int
    ENDIF
    PS: I would not prefer polling methode since it will lose time while checking flags, it would be great if there is a way to run releated interrupt subroutine directly like some other microcontroller models
    Last edited by elcrcp; - 21st April 2013 at 05:24.

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Have you checked this out?
    http://DarrelTaylor.com/DT_INTS-18/home.html

    Search DT-INT by Darrel on the forums.

    Robert

  3. #3
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    I haven't seen that, it may help me a lot, thanks.

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,516


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Hi,
    DT-INTS is probably the best way to go but to answer the original question you do need to poll the individual interrupt request flags, there simply is no way around that because there is only one interrupt vector in the PIC12/16/18 (not counting high/low priority). Some microcontrollers have, like you say, an interrupt vector for each interrups source but these PICs doesn't so the only way to determine the cause of the interrupt is to poll the flags. If you're going with DT-Ints it does that for you though.

    /Henrik.

  5. #5
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    I think that for the PIC16f877A you will need DT_INTS-14 version, not the DT_INTS-18 (which is only for the 18 series devices, I believe). Both versions, and a few other useful things, can be found here: http://dt.cambs.net/
    Perhaps these things should find their way into the WIKI?
    It's always a hunting trip to find and figure out the latest versions, but worth the effort when you eventually get there.

  6. #6
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Thanks for answers, I didn't know PIC doesn't have different interrupt vectors, I thought it has. I tried DT-INTS on my codes with only 1 source interrupt. It kinda worked but not as it has to be.. It's working as it has to when I don't use DT-INTS but it's working in an unexpected way when I use DT-INTS. I don't know why...

  7. #7
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Post your complete code.

  8. #8
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Ok, I'm explaining what I'm trying to do, my codes are little bit long.
    I'm controlling 6 motors seperately and applying them PWM signals by using TMR0, I'm getting encoder data back and counting them to control positions of motors.
    Here is my first code without DT-INTS, I'm compiling them with PBP247, I want to count 50 pulses from each to get them correct position and make them spin for 1 quarter round, and it's working as it has to be.

    Code:
    'Defining controller properties 
     @ DEVICE PIC16F877A
     @ DEVICE PIC16F877A,HS_OSC
     @ DEVICE PIC16F877A,WDT_OFF
     @ DEVICE PIC16F877A,LVP_OFF
     DEFINE OSC 16
     on interrupt goto kesme
     OPTION_REG=%10000100 
     INTCON=%10100000 
     ADCON1=7
    'Defining Port usages and clearing ports for start
     TRISA=%00000000
     TRISB=%00000000
     TRISC=%11110000
     TRISD=%00000011
     TRISE=%00000000
     PORTA=0
     PORTB=0
     PORTC=0
     PORTD=0
     PORTE=0
     
    'DEFINE ENCODER INPUTS
     SYMBOL EN1=PORTC.7
     SYMBOL EN2=PORTC.6
     SYMBOL EN3=PORTC.5
     SYMBOL EN4=PORTC.4
     SYMBOL EN5=PORTD.1
     SYMBOL EN6=PORTD.0
    'DEFINE MOTOR CONTROL OUTPUTS
     SYMBOL M1A=PORTB.7
     SYMBOL M1B=PORTB.6
     SYMBOL M2A=PORTB.5
     SYMBOL M2B=PORTB.4
     SYMBOL M3A=PORTB.3
     SYMBOL M3B=PORTB.2
     SYMBOL M4A=PORTD.7
     SYMBOL M4B=PORTD.6
     SYMBOL M5A=PORTD.5
     SYMBOL M5B=PORTD.4
     SYMBOL M6A=PORTD.3
     SYMBOL M6B=PORTD.2
     'DEFINE VARIABLES
     EN1PRE var BIT
     EN1NOW var BIT
     EN2PRE var BIT
     EN2NOW var BIT
     EN3PRE var BIT
     EN3NOW var BIT
     EN4PRE var BIT
     EN4NOW var BIT
     EN5PRE var BIT
     EN5NOW var BIT
     EN6PRE var BIT
     EN6NOW var BIT
     M1STEPSIZE VAR BYTE
     M2STEPSIZE VAR BYTE
     M3STEPSIZE VAR BYTE
     M4STEPSIZE VAR BYTE
     M5STEPSIZE VAR BYTE
     M6STEPSIZE VAR BYTE
     M1STATE VAR BYTE
     M2STATE VAR BYTE
     M3STATE VAR BYTE
     M4STATE VAR BYTE
     M5STATE VAR BYTE
     M6STATE VAR BYTE
     STANDC VAR BYTE
     M1C var BIT
     M2C var BIT
     M3C var BIT
     M4C var BIT
     M5C var BIT
     M6C var BIT
     walk_mode var byte
     duty_check var BIT
     duty_ctrl var BIT
     duty1 var byte
     duty0 var byte
     M1POWER var BIT
     M2POWER var BIT
     M3POWER var BIT
     M4POWER var BIT
     M5POWER var BIT
     M6POWER var BIT
     STANDUP_COUNT VAR BYTE
     RST:
     
     CLEAR          'Clear all variables
    'Defining starting values of some variables
     M1STEPSIZE=50
     M2STEPSIZE=50
     M3STEPSIZE=50
     M4STEPSIZE=50
     M5STEPSIZE=50
     M6STEPSIZE=50
     EN1PRE=EN1
     EN2PRE=EN2
     EN3PRE=EN3
     EN4PRE=EN4
     EN5PRE=EN5
     EN6PRE=EN6
     M1POWER=1
     M2POWER=1
     M3POWER=1
     M4POWER=1
     M5POWER=1
     M6POWER=1
     STANDUP_COUNT=50
     
     pause 3000
     walk_mode=0 'walk_mode defines which movement mode RHEX will use
     TMR0=255   'Start Timer so interrupts and movement will start
    
    'RHEX IS STANDING UP
    'Check every motor encoder value and stop releated motor if it reached to 
    'defined position
    'MXC is used for motor running control, if a motor is reached to desired
    'position and stopped, do not check and lose time on it
     STANDUP:
     GOSUB ENCOUNTER
         IF M1C=0 THEN
             IF M1STATE>=STANDUP_COUNT THEN
                    M1POWER=0
                    M1C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M2C=0 THEN
             IF M2STATE>=STANDUP_COUNT THEN
                    M2POWER=0
                    M2C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M3C=0 THEN
             IF M3STATE>=STANDUP_COUNT THEN
                    M3POWER=0
                    M3C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M4C=0 THEN
             IF M4STATE>=STANDUP_COUNT THEN
                    M4POWER=0
                    M4C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M5C=0 THEN
             IF M5STATE>=STANDUP_COUNT THEN
                    M5POWER=0
                    M5C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M6C=0 THEN
             IF M6STATE>=STANDUP_COUNT THEN
                    M6POWER=0
                    M6C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF STANDC>=6 THEN
            M1STATE=0
            M2STATE=0
            M3STATE=0
            M4STATE=0
            M5STATE=0
            M6STATE=0
            STANDC=0
            PAUSE 3000
            GOTO RST
         ELSE
            GOTO STANDUP
         ENDIF
    GOTO RST
    
    'COUNTING PULSES FROM ENCODER OUTPUTS 
    'Read values of encoders and if they are different from previous value
    'then it means, a transition is occured, so a pulse is given
    'increase the releated encoder count
    'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
     ENCOUNTER:
         EN1NOW=EN1
         EN2NOW=EN2
         EN3NOW=EN3
         EN4NOW=EN4
         EN5NOW=EN5
         EN6NOW=EN6
         IF EN1NOW!=EN1PRE THEN
            M1STATE=M1STATE+1
         ENDIF
         EN1PRE=EN1NOW
         IF EN2NOW!=EN2PRE THEN
            M2STATE=M2STATE+1
         ENDIF
         EN2PRE=EN2NOW
         IF EN3NOW!=EN3PRE THEN
            M3STATE=M3STATE+1
         ENDIF
         EN3PRE=EN3NOW
         IF EN4NOW!=EN4PRE THEN
            M4STATE=M4STATE+1
         ENDIF
         EN4PRE=EN4NOW
         IF EN5NOW!=EN5PRE THEN
            M5STATE=M5STATE+1
         ENDIF
         EN5PRE=EN5NOW
         IF EN6NOW!=EN6PRE THEN
            M6STATE=M6STATE+1
         ENDIF
         EN6PRE=EN6NOW
         RETURN
    'TMR0 INTERRUPT ROUTINE
    'All motor movements are provided by this interrupt routine
    'A PWM signal is created by using TMR0 timer and applied to 
    'motors, all PWM signals will be created by TMR0 for all movement types
    disable
    kesme:
        if walk_mode=0 then
           duty1=128
           duty0=(256-duty1)        
            if duty_check=0 then
                 duty_ctrl=1
                  M1A=M1POWER
                  M1B=0
                  M2A=0
                  M2B=M2POWER
                  M3A=M3POWER
                  M3B=0
                  M4A=0
                  M4B=M4POWER
                  M5A=M5POWER
                  M5B=0
                  M6A=0
                  M6B=M6POWER
                 TMR0=duty1
            endif
            if duty_check=1 then
                 duty_ctrl=0
                  M1A=0
                  M1B=0
                  M2A=0
                  M2B=0
                  M3A=0
                  M3B=0
                  M4A=0
                  M4B=0
                  M5A=0
                  M5B=0
                  M6A=0
                  M6B=0
                  TMR0=duty0
            endif
        endif
            if duty_ctrl=1 then
            duty_check=1
            else
            duty_check=0
            endif
    INTCON.2=0
    resume
    enable
    end
    And this is the version of same code I used DT-INTS, although I changed and count for only 20 pulses from encoders, motors are spininning 4 rounds when they need to spin for only a quarter round

    Code:
    DEFINE OSC 16
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR0_INT,  _kesme,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
     OPTION_REG=%10000100 
    @    INT_ENABLE  TMR0_INT     ; enable Timer 0 interrupts
    
     ADCON1=7
    'Defining Port usages and clearing ports for start
     TRISA=%00000000
     TRISB=%00000000
     TRISC=%11110000
     TRISD=%00000011
     TRISE=%00000000
     PORTA=0
     PORTB=0
     PORTC=0
     PORTD=0
     PORTE=0
     
    'DEFINE ENCODER INPUTS
     SYMBOL EN1=PORTC.7
     SYMBOL EN2=PORTC.6
     SYMBOL EN3=PORTC.5
     SYMBOL EN4=PORTC.4
     SYMBOL EN5=PORTD.1
     SYMBOL EN6=PORTD.0
    'DEFINE MOTOR CONTROL OUTPUTS
     SYMBOL M1A=PORTB.7
     SYMBOL M1B=PORTB.6
     SYMBOL M2A=PORTB.5
     SYMBOL M2B=PORTB.4
     SYMBOL M3A=PORTB.3
     SYMBOL M3B=PORTB.2
     SYMBOL M4A=PORTD.7
     SYMBOL M4B=PORTD.6
     SYMBOL M5A=PORTD.5
     SYMBOL M5B=PORTD.4
     SYMBOL M6A=PORTD.3
     SYMBOL M6B=PORTD.2
     'DEFINE VARIABLES
     wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
     wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
     wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
     wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
     
     EN1PRE var BIT
     EN1NOW var BIT
     EN2PRE var BIT
     EN2NOW var BIT
     EN3PRE var BIT
     EN3NOW var BIT
     EN4PRE var BIT
     EN4NOW var BIT
     EN5PRE var BIT
     EN5NOW var BIT
     EN6PRE var BIT
     EN6NOW var BIT
     M1STEPSIZE VAR BYTE
     M2STEPSIZE VAR BYTE
     M3STEPSIZE VAR BYTE
     M4STEPSIZE VAR BYTE
     M5STEPSIZE VAR BYTE
     M6STEPSIZE VAR BYTE
     M1STATE VAR BYTE
     M2STATE VAR BYTE
     M3STATE VAR BYTE
     M4STATE VAR BYTE
     M5STATE VAR BYTE
     M6STATE VAR BYTE
     STANDC VAR BYTE
     M1C var BIT
     M2C var BIT
     M3C var BIT
     M4C var BIT
     M5C var BIT
     M6C var BIT
     walk_mode var byte
     duty_check var BIT
     duty_ctrl var BIT
     duty1 var byte
     duty0 var byte
     M1POWER var BIT
     M2POWER var BIT
     M3POWER var BIT
     M4POWER var BIT
     M5POWER var BIT
     M6POWER var BIT
     STANDUP_COUNT VAR BYTE
     RST:
     
     CLEAR          'Clear all variables
    'Defining starting values of some variables
     M1STEPSIZE=50
     M2STEPSIZE=50
     M3STEPSIZE=50
     M4STEPSIZE=50
     M5STEPSIZE=50
     M6STEPSIZE=50
     EN1PRE=EN1
     EN2PRE=EN2
     EN3PRE=EN3
     EN4PRE=EN4
     EN5PRE=EN5
     EN6PRE=EN6
     M1POWER=0
     M2POWER=0
     M3POWER=0
     M4POWER=0
     M5POWER=0
     M6POWER=0
     STANDUP_COUNT=20
     
     pause 3000
     walk_mode=0 'walk_mode defines which movement mode RHEX will use
     TMR0=255   'Start Timer so interrupts and movement will start
    
    'RHEX IS STANDING UP
    'Check every motor encoder value and stop releated motor if it reached to 
    'defined position
    'MXC is used for motor running control, if a motor is reached to desired
    'position and stopped, do not check and lose time on it
     STANDUP:
     GOSUB ENCOUNTER
         IF M1C=0 THEN
             IF M1STATE>=STANDUP_COUNT THEN
                    M1POWER=1
                    M1C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M2C=0 THEN
             IF M2STATE>=STANDUP_COUNT THEN
                    M2POWER=1
                    M2C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M3C=0 THEN
             IF M3STATE>=STANDUP_COUNT THEN
                    M3POWER=1
                    M3C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M4C=0 THEN
             IF M4STATE>=STANDUP_COUNT THEN
                    M4POWER=1
                    M4C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M5C=0 THEN
             IF M5STATE>=STANDUP_COUNT THEN
                    M5POWER=1
                    M5C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M6C=0 THEN
             IF M6STATE>=STANDUP_COUNT THEN
                    M6POWER=1
                    M6C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF STANDC>=6 THEN
            M1STATE=0
            M2STATE=0
            M3STATE=0
            M4STATE=0
            M5STATE=0
            M6STATE=0
            STANDC=0
            PAUSE 3000
            GOTO RST
         ELSE
            GOTO STANDUP
         ENDIF
    GOTO RST
    
    'COUNTING PULSES FROM ENCODER OUTPUTS 
    'Read values of encoders and if they are different from previous value
    'then it means, a transition is occured, so a pulse is given
    'increase the releated encoder count
    'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
     ENCOUNTER:
         EN1NOW=EN1
         EN2NOW=EN2
         EN3NOW=EN3
         EN4NOW=EN4
         EN5NOW=EN5
         EN6NOW=EN6
         IF EN1NOW!=EN1PRE THEN
            M1STATE=M1STATE+1
         ENDIF
         EN1PRE=EN1NOW
         IF EN2NOW!=EN2PRE THEN
            M2STATE=M2STATE+1
         ENDIF
         EN2PRE=EN2NOW
         IF EN3NOW!=EN3PRE THEN
            M3STATE=M3STATE+1
         ENDIF
         EN3PRE=EN3NOW
         IF EN4NOW!=EN4PRE THEN
            M4STATE=M4STATE+1
         ENDIF
         EN4PRE=EN4NOW
         IF EN5NOW!=EN5PRE THEN
            M5STATE=M5STATE+1
         ENDIF
         EN5PRE=EN5NOW
         IF EN6NOW!=EN6PRE THEN
            M6STATE=M6STATE+1
         ENDIF
         EN6PRE=EN6NOW
         RETURN
    'TMR0 INTERRUPT ROUTINE
    'All motor movements are provided by this interrupt routine
    'A PWM signal is created by using TMR0 timer and applied to 
    'motors, all PWM signals will be created by TMR0 for all movement types
    kesme:
        if walk_mode=0 then
           duty1=150
           duty0=(256-duty1)        
            if duty_check=0 then
                 duty_ctrl=1
                  M1A=1
                  M1B=M1POWER
                  M2A=M2POWER
                  M2B=1
                  M3A=1
                  M3B=M3POWER
                  M4A=M4POWER
                  M4B=1
                  M5A=1
                  M5B=M5POWER
                  M6A=M6POWER
                  M6B=1
                 TMR0=duty1
            endif
            if duty_check=1 then
                 duty_ctrl=0
                  M1A=0
                  M1B=0
                  M2A=0
                  M2B=0
                  M3A=0
                  M3B=0
                  M4A=0
                  M4B=0
                  M5A=0
                  M5B=0
                  M6A=0
                  M6B=0
                  TMR0=duty0
            endif
        endif
            if duty_ctrl=1 then
            duty_check=1
            else
            duty_check=0
            endif
    'INTCON.2=0
    @ INT_RETURN
    end
    PS: Second code is compiling with MPASM as DT asks

  9. #9


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Hello

    Have you seen this for control of more than one RC servo.

    http://www.darreltaylor.com/DT_INTS-14/SPWM.html

    Another in the Wiki section.

    http://www.picbasic.co.uk/forum/cont...th-2-I-O-lines

    Edit.: Never mind I see from the code you are using servos with encoders
    Last edited by mark_s; - 22nd April 2013 at 01:30.

  10. #10
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    I'd suggest getting one motor working first, keep your code as simple as possible as a start. Once that works, add a second motor and see if timing remains stable.

    Figure out if issue is in timer interrupt, or having multiple motors.

    Robert

    Edit: Why GOSUB Encounter? It's only called once that I can see. Why not just plug in the subroutine at the GOSUB?
    Last edited by Demon; - 22nd April 2013 at 02:51.

  11. #11
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    main loop is STANDUP in this code, and program remains in that main loop until all motors get into position, ENCOUNTER subroutine is called every time loop starts, and I'm counting pulses from encoders with it. My encoders giving a pulse every 5ms at full speed and controller can complete that loop in microseconds, so controller can catch up any pulse and count it or thats what I thought =)
    But I still have question marks in my mind, I didn't change the code in the end, just added DT-INTS and I belive I added them into code properly, but result is not right. I wonder if there are some tips or things about usage of DT-INTS

  12. #12
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    These are problems I observed in my code with DT-INTS;
    1- There is 3 seconds pause command after defining variables and before start motor controls but motors are starting to run directly when i plug the power cable.
    2- Program cannot go out of STANDUP loop until all of encoders give 50 pulses but although I unplugged4 motors from system without changing the code, remaining 2 motors running , then pausing (not pausing from the start, it looks like it pauses after a jump) and running again and pausing ....
    3- As far as I see, program is not giving a thing about main program and ENCOUNTER subroutine
    4- Interrupt subroutine is working, because motors cannot run before int routine run but nothing else is running...

    I just cant see what is the problem here, maybe I should give up on DT-INTS and use polling methode for multiple interrupts
    Last edited by elcrcp; - 22nd April 2013 at 04:24.

  13. #13
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    I think Timer starts at top with INT_ENABLE.

    You have PAUSE 3 seconds at bottom of main loop (no idea why).

    DT-INT is by far the easiest method to control interrupts, especially when you have more than one.

    As I said, make a copy of your program and keep code for only 1 motor until you debug your logic. Then add 1 motor and see how that goes. Then all 6 only when logic is perfect.

    Start small. Have you tried DT's beginner examples?

    Edit: I don't see where you set T1CON.
    Last edited by Demon; - 22nd April 2013 at 13:24.

  14. #14
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    This is all you need to blink an LED.

    Code:
    LED1   VAR  PORTB.1
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,  _ToggleLED1,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON = $31                ; Prescaler = 8, TMR1ON
    @ INT_ENABLE  TMR1_INT     ; enable Timer 1 interrupts
    
    Main:
      PAUSE 1
    GOTO Main
    
    '---[TMR1 - interrupt handler]--------------------------------------------------
    ToggleLED1:
         TOGGLE LED1
    @ INT_RETURN

  15. #15
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    This was my trial code, I wrote it with only 1 interrupt source to try DT-INTS so I didn't use TMR1 or any other interrupt source in this code, if I can make this code work then i'll use other sources. I only used TMR0 and set it at the very beginning with "OPTION_REG=%10000100" then providing an interrupt with "TMR0=255"
    Pauses are for observing the system, so I can observe rotation amount before it starts run again.
    timer may be starting with INT_ENABLE as you said, I'll check it, and I'll apply a few more tests too. I'll report results here.
    I didn't try DT beginner examples because I didn't need them but I think I should try them to understand it's logic better.

  16. #16
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    ---wrong alert---
    Last edited by elcrcp; - 22nd April 2013 at 17:10. Reason: was a mistake

  17. #17
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    Ok now, something very funny and absurd has happened Before explaining everything, I want to thank again everybody for their help.
    I started to test codes and tried to find where was the exact problem. First of all, yes Robert you were right TMR0 instantly starting to run after "@ INT_ENABLE TMR0_INT" I replaced it's location first and then while looking for problem, I figured out that program is running "STANDUP" and "ENCOUNTER" programs only once, then I stopped calling "ENCOUNTER" and I saw that "STANDUP" is working very fine. Then I added another subroutine to program for testing, just toggling a pin and called it instead of "ENCOUNTER" there was no problem, everything was perfect.
    So, what was the problem with "ENCOUNTER" I comment all lines of "ENCOUNTER" and started to comment out line by line to see where is the problem exactly. While I commenting out lines, I compiled and tried the program on every line of "ENCOUNTER".

    Well now is the funny part, at the end commenting out of lines, while I was thinking "damn I tried all lines and got no error, now its back to old code and wont work as it is" it worked without any problem.. I didnt change any letter of "ENCOUNTER" just commented them in and out thats all, but it worked... Now it counts pulses and stops in right time..

    I'm glad problem is solved, but does anyone have any idea about this stuation?

    Here is working codes I compiled last.

    Code:
    DEFINE OSC 16
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR0_INT,  _kesme,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
         ; enable Timer 0 interrupts
    
     ADCON1=7
    'Defining Port usages and clearing ports for start
     TRISA=%00000000
     TRISB=%00000000
     TRISC=%11110000
     TRISD=%00000011
     PORTA=0
     PORTB=0
     PORTC=0
     PORTD=0
     
    'DEFINE ENCODER INPUTS
     SYMBOL EN1=PORTC.7
     SYMBOL EN2=PORTC.6
     SYMBOL EN3=PORTC.5
     SYMBOL EN4=PORTC.4
     SYMBOL EN5=PORTD.1
     SYMBOL EN6=PORTD.0
    'DEFINE MOTOR CONTROL OUTPUTS
     SYMBOL M1A=PORTB.7
     SYMBOL M1B=PORTB.6
     SYMBOL M2A=PORTB.5
     SYMBOL M2B=PORTB.4
     SYMBOL M3A=PORTB.3
     SYMBOL M3B=PORTB.2
     SYMBOL M4A=PORTD.7
     SYMBOL M4B=PORTD.6
     SYMBOL M5A=PORTD.5
     SYMBOL M5B=PORTD.4
     SYMBOL M6A=PORTD.3
     SYMBOL M6B=PORTD.2
     'DEFINE VARIABLES
     wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                             ' if using $70, comment wsave1-3
     EN1PRE var BIT
     EN1NOW var BIT
     EN2PRE var BIT
     EN2NOW var BIT
     EN3PRE var BIT
     EN3NOW var BIT
     EN4PRE var BIT
     EN4NOW var BIT
     EN5PRE var BIT
     EN5NOW var BIT
     EN6PRE var BIT
     EN6NOW var BIT
     M1STEPSIZE VAR BYTE
     M2STEPSIZE VAR BYTE
     M3STEPSIZE VAR BYTE
     M4STEPSIZE VAR BYTE
     M5STEPSIZE VAR BYTE
     M6STEPSIZE VAR BYTE
     M1STATE VAR BYTE
     M2STATE VAR BYTE
     M3STATE VAR BYTE
     M4STATE VAR BYTE
     M5STATE VAR BYTE
     M6STATE VAR BYTE
     STANDC VAR BYTE
     M1C var BIT
     M2C var BIT
     M3C var BIT
     M4C var BIT
     M5C var BIT
     M6C var BIT
     walk_mode var byte
     duty_check var BIT
     duty_ctrl var BIT
     duty1 var byte
     duty0 var byte
     M1POWER var BIT
     M2POWER var BIT
     M3POWER var BIT
     M4POWER var BIT
     M5POWER var BIT
     M6POWER var BIT
     STANDUP_COUNT VAR BYTE
     CLEAR          'Clear all variables
    'Defining starting values of some variables
     M1STEPSIZE=50
     M2STEPSIZE=50
     M3STEPSIZE=50
     M4STEPSIZE=50
     M5STEPSIZE=50
     M6STEPSIZE=50
     EN1PRE=EN1
     EN2PRE=EN2
     EN3PRE=EN3
     EN4PRE=EN4
     EN5PRE=EN5
     EN6PRE=EN6
     M1POWER=0
     M2POWER=0
     M3POWER=0
     M4POWER=0
     M5POWER=0
     M6POWER=0
     STANDUP_COUNT=50
     
     pause 2000
     walk_mode=0 'walk_mode defines which movement mode RHEX will use
    OPTION_REG=%10000100
     TMR0=255   'Start Timer so interrupts and movement will start
    
    @    INT_ENABLE  TMR0_INT
     
    
    'RHEX IS STANDING UP
    'Check every motor encoder value and stop releated motor if it reached to 
    'defined position
    'MXC is used for motor running control, if a motor is reached to desired
    'position and stopped, do not check and lose time on it
     STANDUP:
     gosub ENCOUNTER
          IF M1C=0 THEN
             IF M1STATE>=STANDUP_COUNT THEN
                    M1POWER=1
                    M1C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M2C=0 THEN
             IF M2STATE>=STANDUP_COUNT THEN
                    M2POWER=1
                    M2C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M3C=0 THEN
             IF M3STATE>=STANDUP_COUNT THEN
                    M3POWER=1
                    M3C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M4C=0 THEN
             IF M4STATE>=STANDUP_COUNT THEN
                    M4POWER=1
                    M4C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M5C=0 THEN
             IF M5STATE>=STANDUP_COUNT THEN
                    M5POWER=1
                    M5C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF M6C=0 THEN
             IF M6STATE>=STANDUP_COUNT THEN
                    M6POWER=1
                    M6C=1
                    STANDC=STANDC+1
             ENDIF
         ENDIF
         IF STANDC>=6 THEN
    @    INT_DISABLE  TMR0_INT     
            M1STATE=0
            M2STATE=0
            M3STATE=0
            M4STATE=0
            M5STATE=0
            M6STATE=0
            STANDC=0
            PAUSE 2000
            end
         ELSE
            GOTO STANDUP
         ENDIF
    end
    
    'COUNTING PULSES FROM ENCODER OUTPUTS 
    'Read values of encoders and if they are different from previous value
    'then it means, a transition is occured, so a pulse is given
    'increase the releated encoder count
    'Note: This will cause 2 counts for every pulse, not 1 count for 1 pulse.
    
     ENCOUNTER:
         EN1NOW=EN1
         EN2NOW=EN2
         EN3NOW=EN3
         EN4NOW=EN4
         EN5NOW=EN5
         EN6NOW=EN6
         IF EN1NOW!=EN1PRE THEN
            M1STATE=M1STATE+1
         ENDIF
         EN1PRE=EN1NOW
         IF EN2NOW!=EN2PRE THEN
            M2STATE=M2STATE+1
         ENDIF
         EN2PRE=EN2NOW
         IF EN3NOW!=EN3PRE THEN
            M3STATE=M3STATE+1
         ENDIF
         EN3PRE=EN3NOW
         IF EN4NOW!=EN4PRE THEN
            M4STATE=M4STATE+1
         ENDIF
         EN4PRE=EN4NOW
         IF EN5NOW!=EN5PRE THEN
            M5STATE=M5STATE+1
         ENDIF
         EN5PRE=EN5NOW
         IF EN6NOW!=EN6PRE THEN
            M6STATE=M6STATE+1
         ENDIF
         EN6PRE=EN6NOW
     return
    'TMR0 INTERRUPT ROUTINE
    'All motor movements are provided by this interrupt routine
    'A PWM signal is created by using TMR0 timer and applied to 
    'motors, all PWM signals will be created by TMR0 for all movement types
    kesme:
        if walk_mode=0 then
           duty1=90
           duty0=(256-duty1)        
            if duty_check=0 then
                 duty_ctrl=1
                  M1A=1
                  M1B=M1POWER
                  M2A=M2POWER
                  M2B=1
                  M3A=1
                  M3B=M3POWER
                  M4A=M4POWER
                  M4B=1
                  M5A=1
                  M5B=M5POWER
                  M6A=M6POWER
                  M6B=1
                 TMR0=duty1
            endif
            if duty_check=1 then
                 duty_ctrl=0
                  M1A=0
                  M1B=0
                  M2A=0
                  M2B=0
                  M3A=0
                  M3B=0
                  M4A=0
                  M4B=0
                  M5A=0
                  M5B=0
                  M6A=0
                  M6B=0
                  TMR0=duty0
            endif
        endif
            if duty_ctrl=1 then
            duty_check=1
            else
            duty_check=0
            endif
    @ INT_RETURN
    end

  18. #18
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Hot to handle multiple interrupt sources?

    You did more than just comment/uncomment.

    You no longer Goto RST at the bottom of Standup and did some finetuning of code.

    I'm happy you nowhave it working. DT-INT really does make our life easier.

    Robert
    Last edited by Demon; - 22nd April 2013 at 21:44.

Similar Threads

  1. port handle
    By kumara in forum Code Examples
    Replies: 6
    Last Post: - 3rd October 2012, 00:32
  2. Two interrupt sources in one program
    By Art in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 25th January 2012, 16:12
  3. Hot Servos
    By The Master in forum Off Topic
    Replies: 37
    Last Post: - 6th August 2010, 19:32
  4. Multiple interrupt source determination
    By PickyBiker in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 5th April 2010, 18:32
  5. PIC16F887 cant handle HIGH and LOW?
    By xobx in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 16th October 2007, 05:46

Members who have read this thread : 1

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts