DT Interupts PortA or PortB?


Closed Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44

    Default DT Interupts PortA or PortB?

    I need a little help, I'm using a 18F2550, and I'm counting how often a switch opens/closes on PortA.5 (Maybe 4, I don't have my circuit in front of me). I'm looping in my main code counting the changes, but I'd like to use DT's interupts, seems like a good fit. I'm using them already for comm and timing. It's working great. What I'm not finding in the posts I've read so far is when I create and enable "INT_INT" how do I control what port triggers the interupt? I'm already doing A/D conversion on PortA.0-3 And have things happening on PortB, so i don't want the changing values on the other pins to trigger the interupt, just a single pin if possible?

    What I have works, but I think I may miss some state changes if the switch operates too fast.

    Any idea's or suggestions would be great.
    Thanks,
    Shane

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


    Did you find this post helpful? Yes | No

    Default Re: DT Interupts PortA or PortB?

    There is no hardware support for interrupts on PORTA. But that doesn't mean you can't use interrupts to do what you want.
    A good way is to determine the shortest switch closure that you must detect (50mSec?). Then set up a timer that interrupts
    at that rate. You mention that you are already using DT-INTs for timing, if you are using a timer for that, just "piggyback" on
    that INT. If you aren't, just set up another timer (I like TMR3 for such things). The interrupt rate must be as fast as the shortest
    switch closure you want to be able to detect. You ISR could be something like -


    Code:
    SwitchInt:  ; The ISR
    
    IF PORTA.5 = 0 THEN
        IF SwitchHasBeenClosed = 0 then
                Pause 10;    Debounce
             IF PORTA.5 = 0 then   ; Still low?
                SwitchHasBeenClosed = 1
                SwitchHasBeenClosedFlag = 1
             ENDIF
         ENDIF
    ELSE
        IF SwitchHasBeenClosedFlag = 1 then
             Pause 10    ; Debounce time
             IF PORTA.5 = 1 then  ; Still high?
                 SwitchHasBeenClosedFlag = 0
                 SwitchHasBeenClosedThenOpened = 1
             ENDIF
         ENDIF
     ENDIF
              
          
    
    @ INT_RETURN
    ; You can clear the flags as appropriate such that you don't perform multiple operations with one switch push.
    Last edited by Charles Linquis; - 8th December 2011 at 02:42.
    Charles Linquist

  3. #3
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44


    Did you find this post helpful? Yes | No

    Default Re: DT Interupts PortA or PortB?

    Charles, Thanks for the suggestion, that's working better. How do I make TMR3 faster? It seems to check the interupt at about 76 hz, I'd like to be around 350 hz? Is there a way to do it without messing up TMR1 that I'm already using? I'm figuring 350 hz because the switch will open/close at about 44hz, but it only stays closed for about 45 degrees or 1/8 of the time. So 44hz=22.7ms, 1/8 of 22.7ms = 0.00284 s, .00284 s = 352 hz. I'm using a 20Mhz XTAL, here are some of my other settings:



    Code:
    asm
              __CONFIG  _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC3_PLL4_1L & _USBDIV_2_1L
              __CONFIG  _CONFIG1H, _FOSC_HSPLL_HS_1H
              __CONFIG  _CONFIG2L ,_BOR_ON_2L & _BORV_2_2L
         
            
        endasm
        
        INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
        INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
        INCLUDE "Elapsed_INT-18.bas"  ; Elapsed Timer Routines
        ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
                INT_Handler    TMR1_INT,  _ClockCount,   PBP,  yes
                INT_Handler    RX_INT,     _Check_Command, PBP, yes 
                INT_Handler    TMR3_INT,  _CheckWind,   PBP,  yes 
            endm
            INT_CREATE               ; Creates the interrupt processor
        ENDASM
       
    @ INT_ENABLE    TMR1_INT     
    @ INT_ENABLE    RX_INT
    @ INT_ENABLE    TMR3_INT
    For reference here is how I count number of times the switch closes, my version of what you posted, seems to work good.

    Code:
    CheckWind:
     If Wpin = %1 Then
        WindThsState = %1
     Else
        WindThsState = %0
     EndIF
     
     If WindThsState <> WindLstState Then 'Spinning 
        WindCnt = WindCnt +1
     ENDIF
      WindLstState = WindThsState
    @ INT_RETURN
    Let me know where I should modify, Thanks again for the help.
    Shane

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


    Did you find this post helpful? Yes | No

    Default Re: DT Interupts PortA or PortB?

    Hello Shane,
    I'm jumping in here with my couple of cents worth...
    TMR3 trips an interrupt when it overflows. It's 16bits wide so it counts from 0 to 65535 and then overflows back to 0, tripping the interrupt. If you have the TMR3 prescaler set to 1:1 (which you have) the timer "ticks" at Fosc/4 or 5Mhz in the case of a 20MHz x-tal. 5MHz/65536=76.3Hz which is your interrupt frequency.

    If you want it to interrupt at higher frequency all you need to do is preload TMR3 with a suitable value each time it interrupt. If you preload it with 51350 then you'll get an interrupt frequency of roughly 5Mhz/(65536-51350)=352Hz.

    Remember that you have to load the timer each time it overflows, not just once. This is best done by stopping the timer and then ADD the preload value to the content of the timer registers, this way the interrupt latency is catered for.

    Using TMR2 may be better since it interrupts when it matched PR2 and automatically resets so you don't need to preload in each interrupt.

    With all that said, if you're already HAVE a timer interrupt (TMR1 in your case) why not use that. There's no reason you can't check your input AND keep time (if that's what you're doing) from within the same ISR. There's usually no need to have a separate timer for each and every task.

    /Henrik.
    Last edited by HenrikOlsson; - 8th December 2011 at 09:59.

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


    Did you find this post helpful? Yes | No

    Default Re: DT Interupts PortA or PortB?

    The preload value for a timer is easily calculated with Mister E's PIC MultiCalc.

    http://www.picbasic.co.uk/forum/atta...7&d=1225550328
    Charles Linquist

  6. #6
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44


    Did you find this post helpful? Yes | No

    Default Re: DT Interupts PortA or PortB?

    Charles and Henrik;
    Preloading TMR3 Worked like a charm, I made it go just a little faster than I need just for some room for error. With a preload of:

    Code:
    TMR3Preload       CON 51650
    I put this at the end of my TMR3 interupt routine to preload:


    Code:
    T3CON.0 = %0   'Turn Timer Off To preload for frequency I need.
    TMR3Now.Highbyte = TMR3H
    TMR3Now.LowByte =  TMR3L
    TMR3Now = TMR3Now + TMR3PreLoad
    TMR3H = TMR3Now.HighByte
    TMR3L = TMR3Now.LowByte
    T3Con.0 = %1  'Turn Timer on
    Seems to run at 355-360 hz. The error is probably in how I'm capturing the frequency, it's probably more accurate than that. That's what I need though, MISTER E's MultiCalc is handy for this, so thanks also to Mister E and everyone else. I didn't know I could preload the timer, I'm learning more all the time.

    Thanks Again,
    Shane

Members who have read this thread : 1

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

Posting Permissions

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