Hank',
Thanks. I think I understand your concerns and constraints. Best of luck on your project Sir.
Cheerful regards, Mike
Hank',
Thanks. I think I understand your concerns and constraints. Best of luck on your project Sir.
Cheerful regards, Mike
I think what you want here is RABC_INT. So:
Note: Your schematic is wrong with pins 11 & 12 shown as RB2 & RB3. These should be RB6 & RB5 respectively. 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
Should be;Code:Switch_Interupt: if portB.4 = 0 then mode = 1 if portB.5 = 0 then mode = 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.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
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
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.
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:
And you can do this for any port pin with int-on-change enabled.Code:IF PORTB.6 = 0 THEN WHILE PORTB.6 = 0 WEND ENDIF
Hope this helps!
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.
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)
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...???
Re having the latest DTS-14 files, they were downloaded from Darrel's site...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
http://darreltaylor.com/DT_INTS-14/downloads.htm (dated Jan 29 2006)
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.
I don't think so. The 16F690 has different interrupt enable & flag bits for PORTA/PORTB interrupt-on-change.we were both wrong
From DT_INTS-14;
These registers aren't available in the 16F690.Code:#define RBC_INT INTCON,RBIF, INTCON,RBIE ;-- RB Port Change
These are;
Code:#define RABC_INT INTCON,RABIF, INTCON,RABIE ;-- RAB Port Change *
Last edited by Bruce; - 7th August 2010 at 00:41.
Bookmarks