|
|
View previous topic :: View next topic |
Author |
Message |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
#int_RB question |
Posted: Wed Apr 27, 2011 11:53 am |
|
|
Hi There,
I would like to trigger an interrupt when pin B0 is changing from LO to HIGH (and only then if possible). Well now the datasheet of my (16F883) says
• an external edge triggered interrupt for RB0 and the ccs manual says #INT_RB Port B any change on B4-B7 - but i want B0. How do I go from here, do I need to choose a different interrupt handler?
Thank you!
Ron |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 27, 2011 12:06 pm |
|
|
You can use the External interrupt, which is available on Pin B0.
Use INT_EXT to enable it, and #int_ext to create the isr. Use the
ext_int_edge() function to set the edge. This is all in the CCS manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Wed Apr 27, 2011 12:11 pm |
|
|
Hoops, yes it is, it's just tricky to find it...
Thanks yet again PCM! That should work. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Wed Apr 27, 2011 2:49 pm |
|
|
So alright, to make it work, do i need Code: | ext_int_edge(L_TO_H);
enable_interrupts(INT_RB0); | and#int_EXT as the handler? What about INT_EXT_L2H then..? Confusing, esp because i don't have hardware to see/test what's happening....
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 27, 2011 3:11 pm |
|
|
Quote: | enable_interrupts(INT_RB0); |
That's for interrupt on change.
You can enable External interrupts this way:
Code: |
clear_interrupt(INT_EXT);
enable_interrupts(INT_EXT_L2H);
enable_interrupts(GLOBAL);
|
|
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Wed Apr 27, 2011 3:17 pm |
|
|
I thought I read somewhere that only RB4 - RB7 are on change interrupts - however, I just got a requirement change and need RB0 to be an on change interrupt now (yes, i'm working in an agile r&d environment lol).
So however, cause on change is only on RB4-RB7 I solved it this way:
Code: |
ext_int_edge(L_TO_H); //set interrupt to kick in on rising edge
enable_interrupts(INT_RB0); //enable external interrupt for sync pulse
enable_interrupts (GLOBAL);
#INT_RB
void SyncInt() {
static int1 PulseState=0;
disable_interrupts (int_RB);
if (PulseState)
ext_int_edge(L_TO_H); //set interrupt to kick in on rising edge
else
ext_int_edge(H_TO_L); //set interrupt to kick in on falling edge
PulseState^=1; //toggle PulseState flag
enable_interrupts (int_RB);
}
|
That should work I think, |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 27, 2011 5:17 pm |
|
|
INT_RBx and INT_EXT are completely different interrupt methods.
You use the functions for one type to setup the other type. That's
what you're trying to do, and it won't work.
Also, the 16F883 doesn't have the capability to select the edge for
INT_RBx interrupts. You can only do that with the INT_EXT interrupt.
You must read the CCS manual and the data sheet. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Thu Apr 28, 2011 3:11 pm |
|
|
Uhm, yep I guess so, let me get back on that... |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Fri Apr 29, 2011 3:49 pm |
|
|
Yep, Okay, I managed this now with #INT_EXT. I didn't find too much documentation on it but assume that #INT_EXT, #INT_EXT1, #INT_EXT2, #INT_EXT3 are for RB0, RB1, RB2 resp. RB3. And another weird thing is that the CCS docu says that interrupt on change is only available on RB4 through to RB7 but the 16F883 datashet says
All of the PORTB pins are individually configurable as an
interrupt-on-change pin.
Thanks for your help PCM! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Apr 30, 2011 2:45 am |
|
|
Down to 'history', and depends a bit on which compiler version you have:
Historically, you had physical 'int' pins (depending on the chip, just INT, or on some chips two or three such pins INT1, INT2 etc..). These can be programmed to respond to an individual edge (rising or falling). Then separately, 'interrupt on change', normally on the high four pins of port B. This is why the CCS documentation refers to these pins with regard to the on change interrupt.
However, you _must_ read the remarks, which say:
"Note many more #INT_ options are available on specific chips. Check the devices .h file for a full list for a given chip.".
So a check on your chip, reveals RB0 to RB7, not just RB4 to 7.
About four years ago, PIC's started appearing with 'extra' features in this regard. First, more pins (typically the whole of port B). Second the ability to enable/disable individual pins from triggering the interrupt. Third, a separate register, showing which of the enabled pins has actually triggered. Fourth, a register showing which way the pin has changed. Your chip, was one of the early ones with some of these 'extras'. Int on change (IOC), is available for all the pins of port B. However it does not offer the direction, or 'which has changed' registers.
You need also to be careful, since B0, _also_ has a normal 'INT' interrupt as well - potentially you could have _two_ interrupts enabled and both responding to particular changes on this one pin!. Since your chip does not have the register saying 'which pin' has triggered (needs to be evaluated by reading the port, and XORing with a stored value), or the direction, no direction option is offered in the .h file for the RB interrupts.
Now, no. INT_EXT, refers _just_ to a dedicated hardware interrupt pin, as do INT_EXT2 etc.. Your chip _only_ has INT_EXT, of such pins. No #int_ext2 etc., in the .h file. These are not used for IOC. Only INT_EXT is available on your chip, on pin B0. CCS also offers to set the operating 'direction' on this type of interrupt, with the L2H, or H2L options.
INT_RB, is the actual interrupt dealing with interrupt on charge. There is just _one_ physical interrupt on all these pins.
To 'make it easy' to enable/use the interrupts on the individual pins, CCS elected to offer 'automatic' individual pin selection. So if you want INT_RB to trigger on B1, and B3, you can set this with:
enable_interrupts(INT_RB1|INT_RB3);
Unlike normal interrupt 'enables', these ones can be ore'd together to specify which pins you want.
Then you have two choices. If you add a handler for INT_RB, it will be called when _either_ of these pins change. Alternatively, you can let CCS add the code, to 'poll' the pins, and find which one has changed. So you can define two handlers, one for #INT_RB1, and one for #INT_RB3. These will be called separately, when the respective pin changes. There is though a big caveat here, since it adds a handler, and more overhead, when usually it is faster to handle the respective events on all pin changes together....
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|