Shop OBEX P1 Docs P2 Docs Learn Events
Run two ISR's — Parallax Forums

Run two ISR's

SailerManSailerMan Posts: 337
edited 2006-11-01 13:39 in General Discussion
' =========================================================================
INTERRUPT
' =========================================================================
' Runs every 64 uS @ 4 MHz (no prescaler)
ISR_Start:
 EncodersNew = EncPort
 TmpB1 = EncodersOld XOR EncodersNew                                                 
TmpB2 = TmpB1 << 1    
 TmpB1 = TmpB1 OR TmpB2
 EncodersOld = EncodersOld << 1  
 EncodersOld = EncodersOld XOR EncodersNew 
 IF TmpB1.3 = 1 THEN
     IF EncodersOld.3 = 1 THEN 
   INC Encoder_A_Count                          
     ELSE
   DEC Encoder_A_Count                           
      ENDIF
  ENDIF
' ========================================================================= 
 IF tmpB1.1 = 1 THEN                  
      IF EncodersOld.1 = 1 THEN 
     INC Encoder_B_Count                          
      ELSE
   DEC Encoder_B_Count                           
      ENDIF
   ENDIF
 EncodersOld=EncodersNew 
[size=2][code]
'ISR_Exit:
  RETURNINT

[/code][/size]


I have an ISR to monitor my two encoders... It works perfectly. What I want now is an ISR to·do PWM on 4 pins simultaneously. Can I run two separate ISR's or should I just put the PWM code within the Interupt above.

Regards,
Eric

Comments

  • BeanBean Posts: 8,129
    edited 2006-10-21 12:56
    Eric,
    Just put the PWM code in your existing ISR. Just make sure you have enough cycles to do everything you want. It looks like you have 256 cycles per interrupt.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com

    "People who are willing to trade their freedom for·security deserve neither and will lose both." Benjamin Franklin
    ·
  • SailerManSailerMan Posts: 337
    edited 2006-10-21 14:51
    I am running at 50 MHZ does this mean My ISR is cycling every 5.12us? Also what do you mean by "It looks like you have 256 cycles per interrupt."

    Please Remember that I'm a layman and very new to Interupts and the SX28

    Thanks for your patients and best Regards,

    Eric
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-10-21 16:06
    Eric,

    yes, you are right! Your ISR code ends with RETURNINT without a parameter. This means that the RTCC will not be set to a certain value at the and of the ISR. Instead, it simply keeps counting up. An interrupt will be triggered whenever the RTCC register rolls over from 255 to 0. As the RTCC is incremented every clock cycle, this means the ISR will be invoked every 256th clock cycle. At 50 MHz clock frequency, one clock cycle is 20ns, so 256 clock cycles take 5.12µs.

    When you want a different timing, use RETURNINT together with a parameter. For example, if you want the ISR to be invoked every Microsecond, you would write RETURNINT 50, as 50 * 20ns = 1 µs. Please keep in mind that the total time, required to execute all instructions within in the ISR routine in worst case must be shorter than the ISR calling period. Otherwise, RTCC rollovers would be missed. You also should consider that the ISR "eats" exeution time from your main program. The more often the ISR is invoked, and the longer it takes to execute the ISR code, the less time does the SX have remaining to execute the main code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    Günther
  • SailerManSailerMan Posts: 337
    edited 2006-10-31 15:39
    Guenther...

    Sorry I didn't respond earlier, Thanks for your explaination..Looking at my ISR above even though it's in SX/B can you give some suggestions on how to make the timing consistent. Would you leave it as is? or find a way to "even" out the timing.. I have a main program that has serial input and output which I have working somewhat [noparse]:)[/noparse] .
    I was thinking that If I could fix the timing issues with my ISR I could solve the Serial issues as well.

    Maybe small delays?

    Thanks for any help,
    Eric
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-11-01 13:39
    Eric,

    I noticed that you are clocking the SX with 4 MHz, so the ISR will be invoked every 64 µs, as you have mentioned in the title comment. Generally speaking, you can have serveral virtual peripherals handled by one ISR, like reading the encoders, and handling serial communication. The important point is that timing-critical routines, like the handlers for serial communications need to be called at a constant rate. Otherwise, you would have jitter on the transmit serial signal, and maybe, the receiver might read false input data. To make sure that timing is correct, any ISR code that is executed before the timing-critical routines must take the same amount of clock cycles to execute whenever the ISR is invoked. In your sample code, this is not the case, as the IF tmp81.3 THEN, and the IF tmp81.1 THEN blocks are obviously not executed on each ISR invocation. To achieve a constant execution time, you might consider using IF...ELSE...ENDIF blocks, and place some dummy code in the ELSE part with the same execution time as the code in the IF part. You would have to look at the assembly code that SX/B generates for these parts to determine what dummy code you might use. On the other hand, you can place the code for timing-critical routines before the code with variable execution time. For example, you can place the code for the serial receiver first, followed by the code for the serial transmitter, and then your code to read the encoders. In order to get the right timing for the transmitter code, it is important that the code for the receiver has a constant execution time. The transmitter code must not neccessarily have a constant execution time as IMO, reading the encoders is not timing-critical.

    Besides this, for serial communications routines, an ISR timing must be selected that matches one of the standard baud rates. For example, at 9600 Baud, one bit takes 104.17 µs. As the receiver must detect the start bit, and then delay 1.5 bits to "center" on the first data bit, the ISR must be invoked every 52.083 µs, or approximately every 208th system clock cycles. This does result in 9615 Baud which is close enough to 9600. So, instead of using RETURNINT, you would have to use RETURNINT 208. This also causes that your code to read the encoders is executed after a slightly shorter time period but I don't think that this is critical.

    Note that the SX/B SERIN and SEROUT commands don't use interrupts, and that their timing can be wrong when an ISR is active. So, when using SERIN ro SEROUT, you should disable RTCC interrupts before, and enable them again after the SERIN or SEROUT. On the other hand, this means that the encoders will not be scanned during this time. If this matters, the only chance is to use a piece of assembly code for the serial in and out routines, and place it inside the ISR as described above.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    Günther
Sign In or Register to comment.