How to know what pin triggered an interrupt?


Closed Thread
Results 1 to 20 of 20
  1. #1
    xnihilo's Avatar
    xnihilo Guest

    Default How to know what pin triggered an interrupt?

    A porta change interrupt occured! Cool!
    But then in the INT handler I need to read the pin that triggered the int.

    I could use:

    IF (porta.0 == 1) ... (my code here)
    IF (porta.1 == 1) ... (my code here)
    (for all 6 pins... it will take a lot of space in my PIC memory)


    Could I instead use something like:

    If porta.0 = 1 then pin = 0
    If porta.1 = 1 then ...
    (for all 6 pins)

    Then:

    IF (porta.0(pin) == 1) THEN...

    Is this syntax correct?

    Isn't there an easier way to check what pin triggered the int? There is an INT flag that tells us there was a change on portA but no info on the pin that triggered the int...

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


    Did you find this post helpful? Yes | No

    Default

    I may be wrong, but I can not think of a PIC that has a porta interrupt.

    What PIC are you using?
    Dave
    Always wear safety glasses while programming.

  3. #3
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I would read the port as fast as possible (immediately on interrupt) by saving it in an 8-bit
    variable, and then testing for the port bit in question stored in my variable.

    MyPort VAR BYTE. MyPort=PORTA. Now test bits in MyPort for the change.

    Edit:
    The only interrupt flags available are those shown in the data sheet.
    Last edited by Bruce; - 7th October 2008 at 18:57. Reason: Flags
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  4. #4
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    I may be wrong, but I can not think of a PIC that has a porta interrupt...
    Unless he is using a PIC24 - which can have interrupts on every port.

  5. #5
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    If PBP supported the 24 series it would be nice..;o}
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  6. #6
    sheepdog's Avatar
    sheepdog Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    A porta change interrupt occured! Cool!
    But then in the INT handler I need to read the pin that triggered the int.

    I could use:

    IF (porta.0 == 1) ... (my code here)
    IF (porta.1 == 1) ... (my code here)
    (for all 6 pins... it will take a lot of space in my PIC memory)


    Could I instead use something like:

    If porta.0 = 1 then pin = 0
    If porta.1 = 1 then ...
    (for all 6 pins)

    Then:

    IF (porta.0(pin) == 1) THEN...

    Is this syntax correct?

    Isn't there an easier way to check what pin triggered the int? There is an INT flag that tells us there was a change on portA but no info on the pin that triggered the int...
    B0 = NCD portx

  7. #7
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    I may be wrong, but I can not think of a PIC that has a porta interrupt.

    What PIC are you using?
    Yes, it is called portA on change interrupt, there are also portB on change interrupts.
    It exists on the models I'm using: 16F684, 16F690, 18F452. Very useful by the way.

  8. #8
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bruce View Post
    I would read the port as fast as possible (immediately on interrupt) by saving it in an 8-bit
    variable, and then testing for the port bit in question stored in my variable.

    MyPort VAR BYTE. MyPort=PORTA. Now test bits in MyPort for the change.

    Edit:
    The only interrupt flags available are those shown in the data sheet.
    That's exactly what I'm doing (see my code below) but I have the feeling it makes me waste some time doing all the stuff only to know which pin triggered the int

    Code:
    DISABLE 				'disable individual interrupts while executing the interrupt routine (do not put check interrupts calls after each instruction)
    
    
    in_sig: 
    
    
    'MEMO: first read the port THEN clear the flag otherwise mismatch still exists
    'Contribution from: Darrel Taylor (www.picbasic.co.uk/forum/)
    a = porta               'read port to clear mismatch
    
    'TEST block
    HIGH portc.2
    
    'check what pin triggered the int
    'we have the time of the header pulse to manage that work
    if (a.0(0) == 0) THEN
        pin = 0
        GOTO got_pin        'bypass 
    ENDIF
    if (a.0(1) == 0) THEN
        pin = 1
        GOTO got_pin        'bypass 
    ENDIF
    if (a.0(2) == 0) THEN
        pin = 2
        GOTO got_pin        'bypass 
    ENDIF
    if (a.0(3) == 0) THEN
        pin = 3
        GOTO got_pin        'bypass 
    ENDIF
    if (a.0(4) == 0) THEN
        pin = 4
        GOTO got_pin        'bypass 
    ENDIF
    
    got_pin:
    This works, then I have to use porta.0(pin).

  9. #9
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by rmteo View Post
    Unless he is using a PIC24 - which can have interrupts on every port.
    PORTA and PORTB have it. You can choose which pin change can trigger an int but then you only have an INT flag that tells you some port pin triggered an int, it's up to us to check which one did it.

  10. #10
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sheepdog View Post
    B0 = NCD portx
    "NCD returns the priority encoded bit number (1 - 16) of a value. It is used to find the highest bit set in a value. It returns 0 if no bit is set.
    B0 = NCD %01001000 ' Sets B0 to 7"

    Uh... yes, fine, unless I need the LOWEST priority.
    In fact, for the project, pins 0 to 4 are used to record an area hit on the player for a lasergame equipment. Area0 (A.0) is the head while A4 is the right arm...
    So I would need to scan from pin0 to pin4 and process the signal as soon as I find a pin that is LOW (pins are default HIGH).

    I might use REV first: (porta has only 6 pins on PIC16F690, so bits 6 and 7 should be 0... or not? Maybe I should make sure bits 6:7 are cleared before I do that)

    reversed_a = a REV 8 'reverse 8 bits of variable a in which I mirrored PORTA register
    triggered_pin = NCD reversed_a 'find the priority bit

    I guess this should do the trick but will these two line be faster that my code in my previous post? I wonder.

  11. #11
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    I guess this should do the trick but will these two line be faster that my code in my previous post? I wonder.
    My guess is that your original code a couple of posts above would be faster... There's a lot of bit shuffling that goes on with REV and NCD.
    Also, what happens if none of the pins are hit? If more than one pin is hit?

  12. #12
    sheepdog's Avatar
    sheepdog Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    My guess is that your original code a couple of posts above would be faster... There's a lot of bit shuffling that goes on with REV and NCD.
    Also, what happens if none of the pins are hit? If more than one pin is hit?

    "reversed_a = a REV 8 'reverse 8 bits of variable a in which I mirrored PORTA register"
    B0 = portx
    B1 = ^ B0 ' Reverse state of bits of B0
    B0 = NCD B1
    select case etc

    Bruces would probably be the fastest way, I have an affliction for making thinks more complex than perhaps need be. Did not realise pins default high etc.
    All the best
    Last edited by sheepdog; - 7th October 2008 at 23:25. Reason: not needed after hit detection

  13. #13
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Talking

    Quote Originally Posted by skimask View Post
    My guess is that your original code a couple of posts above would be faster... There's a lot of bit shuffling that goes on with REV and NCD.
    Also, what happens if none of the pins are hit? If more than one pin is hit?
    You are right, bit shuffling and time wasting.
    Following your advice I sticked to my previous code (the one with the TIMER1) and amazing enough, it works (there was a debugging LCDOUT with a PAUSE 2000 adding a delay such that the next signal coming 100ms later would never be recorded anyway). Now the test led lights up very shortly (meaning the code is executed very fast) and when sending a burst of 4 signals from the remote other PIC, one every 100ms, the receiver circuit records all 4 signals (even with WRITEs adding some extra delays). I feel so releived... Thank god, it took so many hours/nights to get it right, I can go on with the other features.

    Thanks to all of you. Hope these posts might help others.
    I know that some questions I ask sometimes sound like: "I'm stuck, what is the answer?".
    I'm not asking for the solution but some ideas and some comments might guide me or show me an obvious mistake. I enjoy finding solutions myself but often, you guys help me a lot, either by a direct answer or by discussing about the stuff.
    I wish some day I will be able to help other.
    It's nice to have such places as this forum to brainstorm (I could not do that with Victoria, my almost 3 month old daugther who can anly say "agheu" and "pa"

    Still, I guess it would have worked with the PULSIN, I probably wasn't using it right but I didn't discover yet wat mistake I was making. As soon as I'm finished with higher priority coding I will get back to this chunk of code and see why the PULSIN version was taking about 1s to collect the 16 bits...


    "Also, what happens if none of the pins are hit? If more than one pin is hit?"

    -> If none are hits? How could it be, the code is in the int handler so there must be a pin that went from default HIGH to low because the TSOP sensor-demod received an IR signal and triggered the pic pin connected to it. There will always be one pin activated.
    What if more than one pin? Well, as I'm scanning the pins from pin 0 to pin 4 I will stop at the first pin that changed (as they are all default HIGH) and use that pin and deliberately ignore the other pins. As in real life, you can't be hit at the head AND at the leg with the same bullet, right? I check the most lethal area first, if the guy is hit in the head, who cares about a bullet hitting the arm...

  14. #14
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by sheepdog View Post
    "reversed_a = a REV 8 'reverse 8 bits of variable a in which I mirrored PORTA register"
    B0 = portx
    B1 = ^ B0 ' Reverse state of bits of B0
    B0 = NCD B1
    select case etc
    B1 = ^ B0
    B0 = NCD B1 check for other interupts exit if 0

    Bruces would probably be the fastest way, I have an affliction for making thinks more complex than perhaps need be. Did not realise pins default high etc.
    All the best
    Interesting, it would be fine if I was scanning from MSB to LSB, it is not the case.
    Pin0 is the head
    ...
    Pin4 is the right arm
    Default porta is %xx111111
    If Pin0 is activated we will have %xx111110
    Reversed it will be %xx000001

    It will tell me it is pin0, okay. What if there are two activated pins, example, reversed it would be %xx001001, it will tell me the activated pin is pin 3, which is true but as I have to scan starting from pin0, I will think the left arm was hit and use that info while the head was hit too, which is much worst (lethal) and the player will get some damage while a hit in the head would tag him out. See?

  15. #15
    sheepdog's Avatar
    sheepdog Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    Interesting, it would be fine if I was scanning from MSB to LSB, it is not the case.
    Pin0 is the head
    ...
    Pin4 is the right arm
    Default porta is %xx111111
    If Pin0 is activated we will have %xx111110
    Reversed it will be %xx000001

    It will tell me it is pin0, okay. What if there are two activated pins, example, reversed it would be %xx001001, it will tell me the activated pin is pin 3, which is true but as I have to scan starting from pin0, I will think the left arm was hit and use that info while the head was hit too, which is much worst (lethal) and the player will get some damage while a hit in the head would tag him out. See?
    Yes I see, be fine if head pin3, glad you have it all sorted out anyway

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


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by xnihilo View Post
    Hope these posts might help others.
    Well I learned about PORTA interrupts! That is going to be a big help.
    Dave
    Always wear safety glasses while programming.

  17. #17
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Question

    Uh, seems that things are not so easy...

    This time I guess it is a hardware concern.

    I put a pin (c2) high somewhere before the routine that reads the incoming signal and put it low after, just to have a visual estimation of the time it takes to complete the routine.
    The pin is just a test pin that lights a 5V led.
    If I don't connect the led to the pin, then the signal is invalid but if I connect the led, all incoming signals are good...
    C2 is an output pin, default low (no external WPU or WPD resistor).
    If I connect the pin to GND through a 10K resistor, it is better but sometimes the signal is missed. Connecting the led ensures the signal is collected fine...

    It makes no sense.

    1 hour later:

    I noticed I left from previous test C0 as input, default high but not using an external WPU.
    I changed it back to output, default low.
    Still I would miss some signals.
    Then adding a 10K WPD instead of a led on the OUTPUT pin C2 seems to fix the problem.
    I wonder how a WPD on an OUTPUT pin acts on my code ???

  18. #18
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    Well I learned about PORTA interrupts! That is going to be a big help.
    You bet! I could not live without port interrupts !

  19. #19


    Did you find this post helpful? Yes | No

    Default What a pleasure

    You know, Xnihilo - it's such a pleasure to see someone working themselves through a problem with the help of the guys on this Forum - and solving it
    But, that's what the forum it's all about, isnt it?

  20. #20
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Default

    Yes I just wish I can help other one day as much as I could be helped.

Similar Threads

  1. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  2. Help with Analog Interrupt
    By brid0030 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th February 2008, 18:14
  3. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 17:27
  4. Another RTC, DS1287
    By DavidK in forum Code Examples
    Replies: 0
    Last Post: - 12th December 2006, 17:07
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

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