Instant Interrupts - Revisited


Closed Thread
Results 1 to 40 of 773

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Bringing them together

    So far I've shown one interrupt source being used at a time, but as I said in the first post, you can easily service Multiple Interrupt Sources.   So what if we wanted to join the previous 3 examples into one program.   NOT a problem!

    To add more interrupt "Handlers", simply add them to the INT_LIST, and create a subroutine for them.

    Since both the Blinky Light, and Elapsed Timer used TMR1, lets move the Blinky Light over to TMR0. Elapsed will still use TMR1.
    Code:
    LED1   VAR  PORTD.0
    LED2   VAR  PORTD.1
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    INCLUDE "Elapsed_INT.bas"    ' Elapsed Timer Routines
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    INT_INT,  _ToggleLED1,   PBP,  yes
            INT_Handler   TMR0_INT,  _ToggleLED2,   PBP,  yes
            INT_Handler   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    
        INT_ENABLE   INT_INT     ; enable external (INT) interrupts
        INT_ENABLE  TMR0_INT     ; enable Timer 0 interrupts
        INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    ENDASM
    
    OPTION_REG = OPTION_REG & $80 | 1  ; Set TMR0 Prescaler to 256, leave RBPU alone
    GOSUB ResetTime              ' Reset Time to  0d-00:00:00.00
    GOSUB StartTimer             ' Start the Elapsed Timer
    
    Main:
        IF SecondsChanged = 1 THEN  
           SecondsChanged = 0
           LCDOUT $FE,$C0, DEC Days,"d-",DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds
        ENDIF
    GOTO Main
    
    '---[INT - interrupt handler]---------------------------------------------------
    ToggleLED1:
         TOGGLE LED1
    @ INT_RETURN
    
    '---[TMR0 - interrupt handler]-------------------------------(Blinky Light)------
    T0Count  VAR WORD
    ToggleLED2:
        T0Count = T0Count + 1
        IF T0Count = 512 THEN T0Count = 0 : TOGGLE LED2
    @ INT_RETURN
    
    <font size=-2>Code Size = 711 Words</font>

    Now we have all three interrupt sources working together in the same program.
    LED1 responds to the external INT
    LED2 flashes, timed by TMR0
    and, the elapsed timer is maintained via TMR1
    And, all of this is happening behind the scenes of your normal PBP program.
    Attached Files Attached Files
    Last edited by ScaleRobotics; - 7th January 2012 at 16:38.

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default The Base Layer - ASM interrupts

    <table cellpadding=6><tr><td valign=center></td><td>The Instant Interrupt System consists of several "Layers".

    The Bottom Layer is "DT_INTS-14.bas". This file contains everything required to use Interrupts at the ASM level. &nbsp; It handles all of the "Context Saving/Restoring", detects which interrupt has been triggered, and calls the appropriate "User Routine".

    The next layer up is created from the INT_LIST macro you define in the program. &nbsp; It defines the Interrupt sources to use and the corresponding subroutines that will be called. &nbsp; They can be either simple subroutines, or complete "Modules" in a separate Include file, like the Elapse Timer. &nbsp; Up to 14 separate INT_Handler's can be in the LIST.

    And, the Top Layer is the normal PBP program that runs in the foreground.

    If Basic Laguage interrupts are not being used, then DT_INTS-14.bas is the only file you need to include.</td></tr></table>Here's another example of a Blinky Light program using TMR1 with an Assembly Language Interrupt handler
    Code:
    LED1   VAR  PORTD.0
    LOW  LED1                    ; Set to Output Low
    
    INCLUDE "DT_INTS-14.bas"     ; Base Interrupt System
    
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   TMR1_INT,   ToggleLED1,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    
        INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    ENDASM
    
    T1CON = $31                  ; Prescaler=8, TMR1ON
    
    Main:
        PAUSE 1
    GOTO Main
    
    '---[TMR1_INT - interrupt handler]------------------------------------------
    ASM
    ToggleLED1
        btfsc  _LED1
        goto   $+3
        bsf    _LED1
        goto   $+2
        bcf    _LED1
        INT_RETURN
    ENDASM
    
    <font size=-3>Code Size = 104 Words</font>

    Notice that the INT_Handler's Type is ASM, and the Label does not have an underscore before it.<hr><table cellpadding=6><tr><td></td><td valign=top>By using this type of Layering scheme. It allows us more flexability, depending on the type of interrupt we want to use. &nbsp; If we want to add Basic Language Handlers, all we need to do is Include "ReEnterPBP.bas", and it will insert another Layer in-between the Base and the Handlers.

    With this layer included, you can have any combination of ASM and PBP interrupts in the same program</td></tr></table>
    <br>
    Last edited by ScaleRobotics; - 7th January 2012 at 16:33.

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default ReEnterPBP.bas - An adaptation of INT_CTRL.pbp

    October 05, 2002 was a good day. &nbsp; Because that's the day that Tim Box released his "INT_CTRL.pbp" program. &nbsp; The original "Instant Interrupts"

    Tim had discovered that the only reason you couldn't use Basic statements in a normal interrupt, was because the PBP system variables currently being used by the statement that got interrupted, would be overwritten by the Basic statements in the interrupt routine. &nbsp; And that, all you have to do is save the state of the system vars at the start of the interrupt, and restore them back to the way they were before exiting the interrupt and you can use any Basic statements you want.

    I've probably said it too many times already but ... Thanks again Tim!
    <hr>
    ReEnterPBP.bas is an adaptation of the same concept, but it allows the Interrupt system to determine if it needs to save the variables or not.

    For instance, if you have a program with both ASM and PBP interrupt handlers, and an interrupt triggers an ASM handler, there's no need to save the variables first, it would just be waisting valuable time. And if more than 1 Basic handler is triggered at the same time, it only saves the variables once, and processes all the Interrupts on the same pass, before restoring the system vars, again saving time.

    However, it does still take a lot of time to save all those variables. Usually it takes around 70 instruction cycles to save the vars. Then another 70 cycles to restore them again. At 4mhz it's 140us total save and restore time, which limits the maximum interrupt frequency to just over 7khz. At 20mhz OSC, you can go up to almost 36khz. That's fast enough to receive RS232 at over 250Kbaud with the USART. &nbsp; But is still considerably slower than you can get with ASM interrupts.

    <br>

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Bug Fix

    <table><tr><td></td><td>While working on the 18F version, I discovered a bug in the ReEnterPBP file.
    It was not restoring the RS1 and RS2 system variables properly.</td></tr></table>The file has been updated to version 3.2, and anyone using Instant Interrupts for the 14-bit PIC's should update the file as soon as possible.


    <br>
    DT

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Cool DT_INTS-18 Interrupts for 18F's Now Available

    <table><tr><td></td><td>
    At long last.

    The Instant Interrupt system for 18F PIC's is now available.

    It's become increasingly harder to keep things up to date here on the forum, so I've moved everything over to my website.
    I'm still working on some of the pages, but everything you need is already there. It seems to take longer to make the web pages, than it does to write the program.

    http://darreltaylor.com/DT_INTS-18/home.html</td></tr></table>

    <br>
    DT

  6. #6
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425


    Did you find this post helpful? Yes | No

    Default

    Darrel,

    Awesome program for a 18F4550. I never realized it takes so many lines of code just to blink an LED. Where can I adjust the duty cycle of the LED?

    Thanks,

    Chris

  7. #7
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    Many thanks to Darrel Taylor ! I'll have to try this immediately.


    His techniques probably make most of what I'm about to write obsolete - but last night I promised that I would post what I learned about assembly-language interrupts and PBP from Tim Box, Charles Leo (of MELABS) and my own testing. The information presented is believed to be accurate, but I cannot guarantee this without complete testing - something I will do within the next few days. If I find any mistakes, I'll post an update.

    1)
    Some of the newer 18F parts have a new instruction -

    RETFIE FAST

    This instruction AUTOMATICALLY saves and restores the W,STATUS and BSR registers. Unless you mess around with pointers (such as FSR0x), this is all you need to do use. No extra instructions for saving and restoring context are needed. Just put it in place of the ordinary 'retfie' instruction. Check your datasheet to make sure if your part offers this. The 18F8720 and '8722 have this instruction.

    2)
    If your part does NOT have the "fast interrupt" enhancement, you should *normally* only need to save and restore W,STATUS and BSR.

    3)
    ALL of the variables declared by PBP but used in the assembly routine should be declared as 'bankA'.

    4)
    Variables declared by PBP are given an underscore "_" before the name when used in assembly. For example: 'MyVar var BYTE bankA' in PBP becomes '_MyVar' in assembly. To allow the same name in both PBP AND assembly, you need to define the variable as 'system' . For example 'MyVar BYTE bankA
    system' has the name 'MyVar' in assembly (The assembler variable doesn't require an underscore as long as the variable is declared as 'system'.)

    5)
    Don't declare BIT variables in PBP to later be used in an assembly routine.
    Use BYTE or WORD variables only. If you just need a bit to act as a flag, declare a PBP variable such as 'FLAGVAR' and set/reset one of the bits.

    6)
    Since your are only using the Access Bank (bankA) in your assembly-language routine, you don't need to use GOTOs. Use the BRA (branch) instruction instead.

    7)
    If you have two interrupt levels (high and low priority), you can use the PBP defines -
    DEFINE INTHAND (label of high-priority interrupt handler) and
    DEFINE INTLHAND (label of low-priority interrupt handler)

    Save and restore context the same way as described above. RETFIE FAST works on the low-priority interrupt, too.
    Charles Linquist

  8. #8
    Join Date
    May 2006
    Location
    Del Rio, TX, USA
    Posts
    343


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Charles Linquis
    RETFIE FAST works on the low-priority interrupt, too.
    Just to clarify one important item. Here is snippet from the PIC18F8722 Datasheet under Memory Organization:

    5.1.4 FAST REGISTER STACK
    ...
    If both low and high priority interrupts are enabled, the
    stack registers cannot be used reliably to return from
    low priority interrupts
    . If a high priority interrupt occurs
    while servicing a low priority interrupt, the stack register
    values stored by the low priority interrupt will be
    overwritten. In these cases, users must save the key
    registers in software during a low priority interrupt.
    So, more accurately, RETFIE FAST works when low-priority interrupts are enabled, as long as software saves & restores key registers during the low priority interrupts, and RETFIE FAST is only used to return from high-priority interrupts.

    Steve

  9. #9
    Join Date
    Sep 2006
    Location
    Australia
    Posts
    5


    Did you find this post helpful? Yes | No

    Thumbs up Instant Interrupt

    Quote Originally Posted by Darrel Taylor View Post
    <table><tr><td></td><td>
    At long last.

    The Instant Interrupt system for 18F PIC's is now available.

    It's become increasingly harder to keep things up to date here on the forum, so I've moved everything over to my website.
    I'm still working on some of the pages, but everything you need is already there. It seems to take longer to make the web pages, than it does to write the program.

    http://darreltaylor.com/DT_INTS-18/home.html</td></tr></table>

    <br>
    Thank you very much Darrel. Your excellent works have saved me lots of headache.

  10. #10
    Join Date
    Jun 2006
    Location
    Greece
    Posts
    302


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    So far I've shown one interrupt source being used at a time, but as I said in the first post, you can easily service Multiple Interrupt Sources. &nbsp; So what if we wanted to join the previous 3 examples into one program. &nbsp; NOT a problem!

    To add more interrupt "Handlers", simply add them to the INT_LIST, and create a subroutine for them.

    Since both the Blinky Light, and Elapsed Timer used TMR1, lets move the Blinky Light over to TMR0. Elapsed will still use TMR1.
    Code:
    <font color="#000000"><b>LED1   </b><font color="#008000"><b>VAR  </b></font><b>PORTD</b>.<b>0
    LED2   </b><font color="#008000"><b>VAR  </b></font><b>PORTD</b>.<b>1
    
    </b><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;DT_INTS-14.bas&quot;     </font><font color="#0000FF"><b><i>' Base Interrupt System
    </i></b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;ReEnterPBP.bas&quot;     </font><font color="#0000FF"><b><i>' Include if using PBP interrupts
    </i></b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;Elapsed_INT.bas&quot;    </font><font color="#0000FF"><b><i>' Elapsed Timer Routines
    
    </i></b></font><font color="#008000"><b>ASM
    </b></font><font color="#000080">INT_LIST  macro    </font><font color="#0000FF"><b><i>; IntSource,        Label,  Type, ResetFlag?
            </i></b></font><font color="#000080">INT_Handler    INT_INT,  _ToggleLED1,   PBP,  yes
            INT_Handler   TMR0_INT,  _ToggleLED2,   PBP,  yes
            INT_Handler   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE               </font><font color="#0000FF"><b><i>; Creates the interrupt processor
    
        </i></b></font><font color="#000080">INT_ENABLE   INT_INT     </font><font color="#0000FF"><b><i>; enable external (INT) interrupts
        </i></b></font><font color="#000080">INT_ENABLE  TMR0_INT     </font><font color="#0000FF"><b><i>; enable Timer 0 interrupts
        </i></b></font><font color="#000080">INT_ENABLE  TMR1_INT     </font><font color="#0000FF"><b><i>; Enable Timer 1 Interrupts  
    </i></b></font><font color="#008000"><b>ENDASM
    
    </b></font><b>OPTION_REG </b>= <b>OPTION_REG </b>&amp; <b>$80 </b>| <b>1  </b><font color="#0000FF"><b><i>; Set TMR0 Prescaler to 256, leave RBPU alone
    </i></b></font><font color="#008000"><b>GOSUB </b></font><b>ResetTime              </b><font color="#0000FF"><b><i>' Reset Time to  0d-00:00:00.00
    </i></b></font><font color="#008000"><b>GOSUB </b></font><b>StartTimer             </b><font color="#0000FF"><b><i>' Start the Elapsed Timer
    
    </i></b></font><b>Main</b>:
        <font color="#008000"><b>IF </b></font><b>SecondsChanged </b>= <b>1 </b><font color="#008000"><b>THEN  
           </b></font><b>SecondsChanged </b>= <b>0
           </b><font color="#008000"><b>LCDOUT </b></font><b>$FE</b>,<b>$C0</b>, <font color="#008000"><b>DEC </b></font><b>Days</b>,<font color="#FF0000">&quot;d-&quot;</font>,<font color="#008000"><b>DEC2 </b></font><b>Hours</b>,<font color="#FF0000">&quot;:&quot;</font>,<font color="#008000"><b>DEC2 </b></font><b>Minutes</b>,<font color="#FF0000">&quot;:&quot;</font>,<font color="#008000"><b>DEC2 </b></font><b>Seconds
        </b><font color="#008000"><b>ENDIF
    GOTO </b></font><b>Main
    
    </b><font color="#0000FF"><b><i>'---[INT - interrupt handler]---------------------------------------------------
    </i></b></font><b>ToggleLED1</b>:
         <font color="#008000"><b>TOGGLE </b></font><b>LED1
    </b><font color="#000080">@ INT_RETURN
    
    </font><font color="#0000FF"><b><i>'---[TMR0 - interrupt handler]-------------------------------(Blinky Light)------
    </i></b></font><b>T0Count  </b><font color="#008000"><b>VAR WORD
    </b></font><b>ToggleLED2</b>:
        <b>T0Count </b>= <b>T0Count </b>+ <b>1
        </b><font color="#008000"><b>IF </b></font><b>T0Count </b>= <b>512 </b><font color="#008000"><b>THEN </b></font><b>T0Count </b>= <b>0 </b>: <font color="#008000"><b>TOGGLE </b></font><b>LED2
    </b><font color="#000080">@ INT_RETURN
    </font>
    <font size=-2>Code Size = 711 Words</font>

    Now we have all three interrupt sources working together in the same program.
    LED1 responds to the external INT
    LED2 flashes, timed by TMR0
    and, the elapsed timer is maintained via TMR1
    And, all of this is happening behind the scenes of your normal PBP program.
    I test for 16f877a and it's work.
    But for the 18f88 i got the message : Symbol not previously defined (T0IF)
    and not compile.Why;

  11. #11
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by savnik View Post
    I test for 16f877a and it's work.
    But for the 18f88 i got the message : Symbol not previously defined (T0IF)
    and not compile.Why;
    That would be a good trick....compiling for an 18F88. I can't seem to find it on the Microchip website.

    Try TMR0IF (a zero after TMR). Or you don't have an up-to-date version of PBP.

    Previous Release: 2.45

    * Adds support for PIC12F508, 509, 683, PIC16F505, 684, 688, 716, 737, 747, 767, 777, 87, 88, PIC18F2331, 2431, 2515, 2525, 2585, 2610, 2620, 2680, 4331, 4431, 4515, 4525, 4585, 4610, 4620, 4680, 6410, 6490, 8410 and 8490.

  12. #12
    Join Date
    Jun 2006
    Location
    Greece
    Posts
    302


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post

    Previous Release: 2.45

    * Adds support for PIC12F508, 509, 683, PIC16F505, 684, 688, 716, 737, 747, 767, 777, 87, 88, PIC18F2331, 2431, 2515, 2525, 2585, 2610, 2620, 2680, 4331, 4431, 4515, 4525, 4585, 4610, 4620, 4680, 6410, 6490, 8410 and 8490.
    I have 2.46

  13. #13
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by savnik View Post
    I have 2.46
    Well, if TMR0IF (or T0IF for that matter) doesn't work, then just change the code to access the interrupt flag bit directly from the applicable register.

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Microchip can't make up thier mind on what they want to call things. In most 16F's it's called T0IF, and in the 18F's it's TMR0IF, but for some reason, in a 16F88 it's also called TMR0IF. It's the same with the T0IE/TMR0IE.

    Fortunately, we aren't stuck with whatever they decide to call things.

    Just add the 2 highlighted lines, and you should be fine. (no spaces before them)
    Code:
    ASM
    T0IF = TMR0IF
    T0IE = TMR0IE
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    INT_INT,  _ToggleLED1,   PBP,  yes
            INT_Handler   TMR0_INT,  _ToggleLED2,   PBP,  yes
            INT_Handler   TMR1_INT,  _ClockCount,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    
        INT_ENABLE   INT_INT     ; enable external (INT) interrupts
        INT_ENABLE  TMR0_INT     ; enable Timer 0 interrupts
        INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts  
    ENDASM
    DT

  15. #15
    Join Date
    Jun 2006
    Location
    Greece
    Posts
    302


    Did you find this post helpful? Yes | No

    Smile

    Thank you.
    Now it's work.

Similar Threads

  1. Clock using Instant Interrupts
    By PICpocket in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 16th February 2009, 21:43
  2. DT instant interrupts with mister_e keypad
    By Tomexx in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 26th November 2008, 20:02
  3. DT's Instant Interrupts trouble
    By Tomexx in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 24th November 2008, 20:48
  4. Keypad and DT's Instant Interrupts
    By Homerclese in forum General
    Replies: 11
    Last Post: - 27th April 2007, 06:32
  5. Replies: 1
    Last Post: - 1st November 2006, 03:11

Members who have read this thread : 8

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