Interrupt 101


Closed Thread
Results 1 to 17 of 17

Thread: Interrupt 101

  1. #1
    Join Date
    Sep 2007
    Posts
    59

    Default Interrupt 101

    I'd like to learn about using interrupts and have been reading several of the timer interrupt threads and looks like some fancier stuff as well. However, I'm trying to start with understanding it in PBP listening to a couple inputs then bake in some timing and high or low priority.

    But before I get there I'm not understanding the nomenclature in the manual on p108. I'm using a PIC 18F6520. and the manual has:
    INTCON = %10010000 'enable RB0 interrupt

    I don't quite get this statement. Can external interrupts only be read on the RB# port?
    And then the 10010000, is this presetting the values for each RB_ to all zeros except for the 5th and 8th to 1?

    Then to further confuse myself the code sample I'm looking at which doesn't use interrupts at all (to the best of my knowledge) has a line in the declarations:
    INTCON2.7 = 0
    I'm not sure what this one means or if it has something to do with interrupts or not.

    I've been able to teach myself quite a bit from the manual but this one has me stumped.

    Any help is appreciated.
    Thank you,
    Hylan

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Hi,
    External interrupts are available on one or more pins. The 18F6520 seems to have four located on RB0-RB3. Smaller chips may only have one which is "always" on RB0. (Then you have the interrupt on change but lets leave that for now).

    INTCON is the interrupt control register (one of them in the 18F6520). Look at the INTCON register in the datasheet, it'll show you what each bit does. In this case the MSB enables all unmasked interrupts and bit 4 enables the INT0 interrupt.

    INTCON2.7=0 disables the internal pullup resistors for PortB.

    The PBP is only part of the documentation, you must use the datasheet for your particular PIC as well.

    Good luck!
    /Henrik.

  3. #3
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Henrik,

    I appreciate it. I've been looking at the datasheet and it's starting to make more sense. I'm not a programmer or circuit designer but am having to learn as this falls under the "other duties as deemed necessary" in the job description and the original guy who did it is no longer available.

    So I think I now understand the physical input. Let's say I want to see an incoming serial message on pin RC7 (RX1 pin) and interrupt the home routine. I would need to first trigger RB0 to interrupt and goto the interrupt routine to read the serial data? Am I thinking correctly?

    Second question. How do I set up software interrupts? Like if a certain value occurs like 3 I/O's are turned on then I want a variable like "AllON = 1" to interrupt the routine and do something.
    Thank you,
    Hylan

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    There's USART interrupt as well. Check out the USART/EUSART section of the datasheet.

    A really easy and efficient way to start right now with interrupts is to use Darrel Taylor Instant Interrupts. Check out this link.
    http://www.pbpgroup.com/modules/wfse...p?articleid=19

    For your, and any, specific requirement, there's a load of different approach.. say one different per programmer

    The basic skelleton:
    Main program (Loop)
    Interrupts.

    Whatever happen in your Interrupts, you may set flags there and process them in your main loop.

    OR you may process some dull duties in your main loop and force interrupts to happen in your main loop too.

    To read I/Os and evaluate them, you may use something like that (Which assume some push button connected to gnd on PORTB<3:0> (b3, b2, b1, b0)
    Code:
    SomePushButton VAR BYTE
    '
    '
    '
    '
    SomePushButton = PORTB & $0F ' read PORTB and keep only <3:0> bits (Bitwise AND)
    SELECT CASE SomePushButton
         CASE %1110 ' PORTB.0
              ' code for PORTB.0 here
         CASE %1101 ' PORTB.1
              ' code for PORTB.1 here
         CASE %1011 ' PORTB.2
              ' code for PORTB.2 here
         CASE %0111 ' PORTB.3
              ' code for PORTB.3 here
         END SELECT
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Beautifull! I feel like I now have enough to be dangerous or at least dangerous in a productive, 'hmmm that didn't work but I learned something' sort of way.

    Thank goodness for reprogrammable pics!

    Thank you,
    Hylan

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Quote Originally Posted by Hylan View Post
    Thank goodness for reprogrammable pics!
    Amen! Couldn't even think to re-use my UV Eraser anyway

    I still have some UV one though... good on a pinboard or as staple... (again)

    if someone talk about software simulator I'll kick his butt
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

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


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    And most people don't realize it, but you can have an interrupt on *ANY* pin - sort of. This is handy when you have a switch that simply must be read and it is on port C, for example.
    Just run a high-speed interrupt on TMR0 and read whatever pins you want inside the ISR. I typically run a 1mSec interrupt.

    A small example of an "interrupt header"


    Code:
     
      PreloadH      VAR BYTE BANKA SYSTEM
      PreloadL       VAR BYTE BANKA SYSTEM
      MasterClock   VAR WORD BANKA SYSTEM
      ButtonFlag    var BYTE BANKA SYSTEM
     
     
      PreloadH= $D8
      PreloadL = $F7    ; 1 mSec@40Mhz
     
      T0CON = %10001000  ; Timer ON, no prescaler
     
     
    '---------------------------------- --------------------------------  
     
            INCLUDE "DT_INTS-18.bas"         
     
    '        INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
     
    ASM
    INT_LIST  macro    ;IntSource,        Label,  Type, ResetFlag?
     
         INT_Handler    TMR0_INT,   MainTimer, ASM,  yes 
    ; INT_Handler    RX1_INT, GetChar,    PBP,  yes
     
    endm
     
    INT_CREATE               
     
    ENDASM
     
    Goto OverInt
     
     
    '---[INT - interrupt handler]---------------------------------------------------
     
    Asm                            
     
    MainTimer
     
        movff    PreloadH,TMR0H  ; Preload depends on clk speed
        movff    PreloadL,TMR0L
         clrf     INTCON,2
     
         infsnz  MasterClock
         incf    MasterClock + 1
     
         btfss  PORTC,4
         bsf  ButtonFlag,0
     
    @ INT_RETURN
     
    ENDASM      
     
    OverInt:
     
       ButtonFlag = 0
       MasterClock = 0
       INTCON =%11100000  ; just to be certain!
     
    @ INT_ENABLE TMR0_INT  
     
     
    Your program here
    This particular code will increment MasterClock at a 1000Hz rate (1 ms / count). You can read it at any time, although you should either disable INTs when you test it, or only test that it is ABOVE (not equal to) a value, since it is a 16 bit var and can increment in the middle of a PBP read.

    ButtonFlag.0 will be set any time after someone has pressed a button bringing PORTC.4 to GND. You can read it anytime, then clear it in your main code.

    If you have more complicated things to do on an interrupt, you can write it in PBP.


    So THERE! mister_e and pxidr84!
    Charles Linquist

  8. #8


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    That's a good setup !
    How about switch de-bounce (make sure its a good press)

    I use;

    if sw not_pressed then out
    pause 10 ' or 20 or 50 ms
    if sw not_pressed then out
    good sw pressed stuff here

    don

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


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    You often don't need a debounce if you read a switch in software. Hardware is so fast that it can see one push as a bunch of pushes, but software is generally a lot slower and you can use that to your advantage. In the example I gave above, the bit gets set as soon as the first contact is made. If the main loop reads the bit at that time, and then does something that takes 50 mSec, you can clear ButtonFlag at the end of that routine (rather than at the top). The switch will certainly have quit bouncing by then, so the bit won't get re-set by the bounce. This saves 50mSec of waiting.
    If things really get "hairy", I do the debounce in ASM. I count the loops that the switch has been down (or up) and only generate a flag when that number of loops has been executed.

    My programming style uses PAUSE sparingly, if at all. That is the only way you can get real performance out of a PIC and PBP.
    Charles Linquist

  10. #10
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Quote Originally Posted by Charles Linquis View Post
    And most people don't realize it, but you can have an interrupt on *ANY* pin - sort of. ........
    So THERE! mister_e and pxidr84!
    Sure, I classify that as slow background process

    amgen, you just need to read the switch all the time, keep a reading of the previous(s) and compare them. Depending of your timer rate, you may want to make sure it is hold down for X interrupt. set a flag to say a switch is ready, Once done, and the button being read, you wait Y interrupt before reading another and "publish" it.

    Tons of way to do so. But for sure, you don't want any PAUSE in an ISR.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  11. #11


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Yes, getting more accustomed to thinking in terms of COUNT rather than time..... although the count is always exactly related to your timing base. Right ? Also brings more into play, Events to do actions (like windows), and more use of GOSUB's.

    don
    Last edited by amgen; - 23rd August 2011 at 19:17.

  12. #12
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Okay, I've been looking at Daryl Taylors interrupt programs as recommended by Steve. I downloaded everything and tested the blinky blinky to make sure it worked. I changed the toggle pin to one on my board with an LED and it worked.

    Now I'm trying to figure out how to incorporate this into my program and what terms I can change and what I can't and where it needs to be placed in the program. I don't have anything called a "main" loop for example.

    So for example with this sample code:
    Code:
     
    LED1   VAR  PORTB.1
     
    INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
     
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    INT_INT,  _ToggleLED1,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    @   INT_ENABLE   INT_INT     ; enable external (INT) interrupts
     
    Main:
      PAUSE 1
    GOTO Main
     
    '---[INT - interrupt handler]---------------------------------------------------
    ToggleLED1:
         TOGGLE LED1
    @ INT_RETURN
    I understand that the "include" statements go at the top when declaring stuff but I'm not sure where to put the "ASM" section
    and the "INT" Interrupt handler commands

    I tried a couple things and the blinky blinky always worked but I never got my part of the program to run so it seemed to only stay in the above portion.

    Getting closer, I can smell it, but I can't quite see it or taste it.
    Thank you,
    Hylan

  13. #13
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    In the example you have posted place your code in the "Main" loop. To start try a PAUSE type blink in the Main loop to seehow ot works.
    Dave
    Always wear safety glasses while programming.

  14. #14
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Beautiful! I've got the interrupt working properly on the one pin. Now I can start playing with all the other layers and types. I'm sure I will have more questions but at least I've got a starting point.
    Thank you!
    Hylan

  15. #15
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    I'm finally back looking at this again and would like to use the RX2 pin as the interrupt trigger when a serial string comes in on my 18F6520 chip.
    I'm currently using a hserin command and just running it in my main loop to pick up new signals and 999/1000 it works fine.
    I'm looking through pic manual but it's pretty Greek to me.
    Does anyone have an example of how to configure this for the RX2 pin?
    Thank you,
    Hylan

  16. #16
    Join Date
    Sep 2007
    Posts
    59


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    I did a search and think I found some examples, sorry for the premature post.

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


    Did you find this post helpful? Yes | No

    Default Re: Interrupt 101

    Here is a snippet of running code


    Code:
     
    
    INTCON = %11000000
    
    '---------------------------------------------
    
        INCLUDE "DT_INTS-18.bas"         
        INCLUDE "ReEnterPBP-18.bas"    
      
    ASM
    INT_LIST  macro     
    
                INT_Handler    RX2_INT,    _GetCharPort2,    PBP,  yes
    
            endm
        INT_CREATE      
    ENDASM
    ;----------------------------------------------------------------------------------                         
    Goto OverInt
    
    
    GetCharPort2:
        
        for I_XDataLen = 0 to 63
            HSERIN2 50,TimeOut2,[I_XDataChar]
            if I_XDataChar = 13 then goto GetChar2Valid
            I_XDataBuf[I_XDataLen] = I_XDataChar
        next I_XDataLen
        I_XDataLen = 63 ' lost characters, but do the best we can
    GetChar2Valid:
    Timeout2:
        I_XDataBuf[I_XDataLen] = 0
        if I_XDataLen > 0 then
            XDataSource = 2
            XDataFlag = 1
        endif
    GetChar2_Return:
        if PIR3.5 then HSERIN2 [I_XDataChar]
    @ INT_RETURN
    ;--------------------------------------------------------------------
    
    Overint:
    
      PIR3.5 = 0
    @ INT_ENABLE RX2_INT
    
    YOUR CODE HERE
    Charles Linquist

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