Need 4 modes with just 3 switches - need all modes to be selectable QUICKLY!


Closed Thread
Results 1 to 40 of 68

Hybrid View

  1. #1
    Join Date
    Aug 2005
    Location
    Michigan, USA
    Posts
    224


    Did you find this post helpful? Yes | No

    Default

    Hank',

    Thanks. I think I understand your concerns and constraints. Best of luck on your project Sir.

    Cheerful regards, Mike

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


    Did you find this post helpful? Yes | No

    Default

    I think what you want here is RABC_INT. So:
    Code:
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
        INT_Handler    RABC_INT,  _Switch_Interupt,   PBP,  yes  
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
     
    @   INT_ENABLE   RABC_INT     ; Enable 'Int On Change' interrupts
    Note: Your schematic is wrong with pins 11 & 12 shown as RB2 & RB3. These should be RB6 & RB5 respectively. So;
    Code:
    Switch_Interupt:
     
    if portB.4 = 0 then  mode = 1
    if portB.5 = 0 then  mode = 2
    Should be;
    Code:
    Switch_Interupt:
     
    if portB.6 = 0 then  mode = 1
    if portB.5 = 0 then  mode = 2
    if porta.2 = 0 then ? whatever ' this is the interrupt pin on RA.2
    Or, of course, you can use RA.1 as shown in your schematic for this interrupt pin. Either will work the same since they both have IOC (interrupt-on-change) functionality, and internal pull-ups.

    Note I have not used DT_INTs on this PIC type with interrupt-on-change, but that should get you going. I'm sure Darell will jump in here, and correct me if I'm wrong, but I think that's what you're looking for.

    But, I HAVE used his DT_INTs for our 4-digit & 6-digit serial LED displays, and I most certainly can vouch for them working spot-on, and making life a lot easier for us mere mortals...

    I've also used DT_INTs in several commercial applications, and had ZERO problems - so a huge thanks to DT for all the hard work, and sharing his routines with us.
    Last edited by Bruce; - 6th August 2010 at 21:34. Reason: BIG thanks to DT
    Regards,

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

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Bruce ....you're good, like *really* good!

    You spotted my Eagle Part mistake - I failed to declare it, because it's been there for a while & I get used to it....my actual code does reference the right port names! (I need to go back into my Eagle part I created and change the text for those pins....not sure if you've ever had to make your own device/parts in Eagle - fit's not pretty!)

    Quick question - if IOC stands for interupt on change(?), then the 'change' in this scenario will be the pin going from 1 to 0...this will generate an interupt - but what happens when the switch is released (since it's another 'change', then in theory another interupt?!) now I'm sure this is catered for with a rising/falling edge setting in some register but I thought I'd ask!

    Even though the term gets a little over used nowadays ...guys like yourself, DT (& others who've helped me here - a list too long to mention), really do make a difference

    Already, after your recent input - the 3 diodes have already been whipped out on my schematic & I've now just that little bit more pcb real estate to arrange the board layout more to my liking....so a a genuine thanks.
    Last edited by HankMcSpank; - 6th August 2010 at 22:12.

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


    Did you find this post helpful? Yes | No

    Default

    Thanks Hank. But you're good too. You spotted this. Good catch. Interrupt-on-change is exactly what it means, but you have to know how it works to really take advantage of it.

    So here's a quick tutorial.

    Sample the port/ports first, then enable interrupt-on-change, but only after all port pins with this interrupt enabled are in the non pressed state.

    This takes a snap-shot of pins, which is used later on to determin the change-of-state when a switch is pressed. I.E. a transition from logic 1 to 0, assuming a switch grounds the pin, and it has internal pull-ups enabled.

    What you'll normally want to do is use a WHILE WEND statement to WAIT until all switches are in the un-pressed state. I.E. just wait until all port pins that have interrupt-on-change enabled return a value indicating the switch is NOT pressed. Then enable int-on-change.

    The last read of the port is saved & used to determine the transition from un-pressed to pressed - or the transition from logic 1 to 0.

    And - yes - I know Mike will yell at me for suggestiing this, but I normally wait for the pin to return to the un-pressed state in my interrupt handler, then exit & clear the interrupt flag bit. It's just so much easier than sampling pins for a switch-press in a timer-based interrupt. But - Mike does have some cool stuff to do this if you're interested.

    Interrupt-on-change requires you to read the port first to end the miss-match condition before it will allow you to clear the interrupt flag bit, so it just makes sense to wait until the switch is released before clearing the flag bit & exiting the int handler.

    If you don't (like you just mentioned), then you end up having an interrupt generated by switch press & switch release - because both events = a change after you have read the port, and cleared the int-on-change flag bit, and exit the int handler.

    Assuming the user isn't going to press & hold a switch down for any length of time, this is for sure the way to go, and it can be incredibly fast if the user just taps & releases the switch.

    If the user does hold a switch down, it will simply wait for them to release the switch before exiting the interrupt handler, which also works fine, but it does delay exit from your inerrupt handler until switch release.

    This is really simple with just a few extra lines of code in your interrupt handler like this:

    Code:
    IF PORTB.6 = 0 THEN
       WHILE PORTB.6 = 0
       WEND
    ENDIF
    And you can do this for any port pin with int-on-change enabled.

    Hope this helps!
    Regards,

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

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Bruce View Post

    And - yes - I know Mike will yell at me for suggestiing this, but I normally wait for the pin to return to the un-pressed state in my interrupt handler, then exit & clear the interrupt flag bit. It's just so much easier than sampling pins for a switch-press in a timer-based interrupt. But - Mike does have some cool stuff to do this if you're interested.
    !
    Great explanation, just one thing...

    [noob alert]

    Could you please give me an example of some code to implement the bolded bit above? (particularly the exiting sequence & clearing the interupt flag - can't say I've had to do that before)

    [/noob alert]

    Also, forgive me for asking - but have you a link to Mike's info that you referred to?

    Edit: remainder of post deleted cos I spotted a mistake & sorted it!
    Last edited by HankMcSpank; - 7th August 2010 at 00:16.

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


    Did you find this post helpful? Yes | No

    Default

    You already have the reset flag option enabled with DT_INTs, so you don't have to worry about the int flag being reset. It's just up-to-you to make sure it CAN reset the flag by first reading the port pins, and waiting, as in my example above, for whatever input pins you're using, to return to the non-pressed logic level.

    Just duplicate my example above for each pin. I'm going to make you figger that out on-you-own..

    Hint: Just replace PORTB.6 with whatever pin you need to test next. It's blazingly fast if a pin isn't at logic 0.

    Mike will have to help you on his end. He posts here reqularly with some very cool stuff, but you may have to convert it from C to PBP, which really isn't too hard since the C structure is darn close to BASIC (for very simple code).

    And, if you need it, I can do the translation for you, but I'll let Mike chime-in with here with his code example first. He's quite good. Right up there with Darell, and I learn a lot from his input...

    Edit: Make sure you have the latest/greatest version of DT_INTs. Looks like you may have an older version that doesn't have the newer int handlers.
    Last edited by Bruce; - 7th August 2010 at 00:18. Reason: YIKES.. Stop all the editing...;o)
    Regards,

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

  7. #7
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Wow...great stuf - thanks.

    you'll be pleased to hear it's bedtime here in the UK, so radio silence falls upon this thread!

    You've been a great help, in closing re the IOC interupt config ....we were both wrong - I think (...though you were only one character out - I was way out!), the correct IOC config might be like this...???

    Code:
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   RBC_INT,  _ToggleLED1,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE  RBC_INT     ; enable IOC interrupts
    Re having the latest DTS-14 files, they were downloaded from Darrel's site...

    http://darreltaylor.com/DT_INTS-14/downloads.htm (dated Jan 29 2006)

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


    Did you find this post helpful? Yes | No

    Default

    Also - just for the sake of other list members, you might want to just create a 2nd post, and leave whatever you had to change in the original.

    Just so folks can see where you made a mistake (if any), and learn from it. Rather than editing your previous post. I myself learn a lot from things that need to be changed to work properly, and it's a tad confusing for folks to follow-along if you edit a previous code example that needed changing.

    we were both wrong
    I don't think so. The 16F690 has different interrupt enable & flag bits for PORTA/PORTB interrupt-on-change.

    From DT_INTS-14;
    Code:
    #define RBC_INT      INTCON,RBIF,  INTCON,RBIE   ;-- RB Port Change
    These registers aren't available in the 16F690.

    These are;
    Code:
    #define RABC_INT     INTCON,RABIF, INTCON,RABIE  ;-- RAB Port Change     *
    Last edited by Bruce; - 7th August 2010 at 00:41.
    Regards,

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

Members who have read this thread : 0

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