PIC Interrupt 'cheats'

Thread Starter

Barnaby Walters

Joined Mar 2, 2011
102
Hello everybody,

After being annoyed at the PIC I'm using for my robot only having one external interrupt (apart from IOC, which seems awkward and I couldn't get it to work), I cam up with a 'cheat' idea for an extra two external interrupts — set both timers to take their clock input from the TXCKI pins, and set both timers to 255 (11111111). On a pulse to the pin, they overflow, generating an interrupt. You'd just have to re-set them to 255 in the ISR.

Does this sound feasible (I haven't tested it yet), and are there any other cheats like this for getting more external interrupts out of an MCU?

Thanks,
Barnaby
 

AlexR

Joined Jan 16, 2008
732
I suppose its one way of doing it but it seems somewhat convoluted. Why not simply use the portB interrupt on change feature, that (depending on the PIC you are using) can give you up to 7 extra external interrupts.
 

ErnieM

Joined Apr 24, 2011
8,415
It sounds like a feasable workaround, but why don't you let us help you set up the IOC pins with you? What PIC is this (with a data sheet link please)?
 

RiJoRI

Joined Aug 15, 2007
536
Hello everybody,

After being annoyed at the PIC I'm using for my robot only having one external interrupt (apart from IOC, which seems awkward and I couldn't get it to work), I cam up with a 'cheat' idea for an extra two external interrupts — set both timers to take their clock input from the TXCKI pins, and set both timers to 255 (11111111). On a pulse to the pin, they overflow, generating an interrupt. You'd just have to re-set them to 255 in the ISR.

Does this sound feasible (I haven't tested it yet), and are there any other cheats like this for getting more external interrupts out of an MCU?

Thanks,
Barnaby
Yes, it sounds feasible. Not to burst your bubble, but I first saw this concept applied with an 8051. It may be even older... If the PIC has a Reload register, you can set it to $FF also, and the reloading of the timer will be done automatically.

--Rich
 

atferrari

Joined Jan 6, 2004
5,022
Depending what causes that pulse you cold say that you are getting a true interrupt or not. Do yo have interrupt on change available? If so, it is simpler.
 

Thread Starter

Barnaby Walters

Joined Mar 2, 2011
102
Not to burst your bubble, but I first saw this concept applied with an 8051.
No problem — I didn't consider for a moment that it hadn't been done before, but thought it might be helpful for others who hadn't thought of it yet ;)

It sounds like a feasable workaround, but why don't you let us help you set up the IOC pins with you?
Thanks — I'm using a 16F886 mostly (Datasheet). I did try briefly to get the IOC working but realised that I could finish my project with just the external interrupt on RB0. That wasn't working either, until someone here suggested making it an ADC input (something I never got an explanation for, and couldn't see in the datasheet…?) — does this apply to IOC as well?

Thanks,
Barnaby
 

ErnieM

Joined Apr 24, 2011
8,415
Ah, good choice of cores as this beastie can use ANY of the RB port pins an an interrupt souse, and each and every one of them can be turned on or off individually.

To start you off, here's some quotes from the data sheet you (most kindly!) linked to:
MC Datasheet Section 14.3.3 said:
An input change on PORTB change sets the RBIF (INTCON<0>) bit. The interrupt can be enabled/ disabled by setting/clearing the RBIE (INTCON<3>) bit. Plus, individual pins can be configured through the IOCB register.
(Section 3.4.3 is also a good read for this.)

Basically you get to pick which pins will give you the interrupts. Now it is a little messy to handle these things as the "change" is based on the last read of the PortB, so you only want the ISR to read it once and store the value to check it, and additionally any time you touch port B (read or write to it) you also need to recheck that a change was not missed, but you can just call the interrupt routine to do that.

If you do that then you will have this very scary note covered:

MC Datasheet Section 14.3.3 said:
Note: If a change on the I/O pin should occur when the read operation is being executed (start of the Q2 cycle), then the RBIF interrupt flag may not get set. See Section 3.4.3 “Interrupt-on-Change” for more information.
BTW, how are you writing the code? Assembly, C, or something else?

Finally, do you truly need an interrupt? Can you just read the port over and over to see if something changed you need to handle? I am assuming you do need such, but it don't hurt to ask!
 

Thread Starter

Barnaby Walters

Joined Mar 2, 2011
102
Hi there,

Ah, good choice of cores as this beastie can use ANY of the RB port pins an an interrupt souse, and each and every one of them can be turned on or off individually.

To start you off, here's some quotes from the data sheet you (most kindly!) linked to:


(Section 3.4.3 is also a good read for this.)

Basically you get to pick which pins will give you the interrupts. Now it is a little messy to handle these things as the "change" is based on the last read of the PortB, so you only want the ISR to read it once and store the value to check it, and additionally any time you touch port B (read or write to it) you also need to recheck that a change was not missed, but you can just call the interrupt routine to do that.
Yep, I've read it through. It certainly looks like a useful ability. The thing is, using the external interrupt on RB0 only worked when someone here suggested setting the corresponding bit in the ANSEL register, making it an ADC input, but I'm sure the datasheet doesn't tell you to do that! Does this apply to IOC too?

BTW, how are you writing the code? Assembly, C, or something else?

Finally, do you truly need an interrupt? Can you just read the port over and over to see if something changed you need to handle? I am assuming you do need such, but it don't hurt to ask!
In assembly, for the moment, to get a fuller understanding of what's happening on a machine code level. I probably could poll the port, but my current project uses a very accurately timed loop to turn IREDs on and off, and uses the interrupt to see when a signal is received.

Thanks,
Barnaby
 

ErnieM

Joined Apr 24, 2011
8,415
...The thing is, using the external interrupt on RB0 only worked when someone here suggested setting the corresponding bit in the ANSEL register, making it an ADC input, but I'm sure the datasheet doesn't tell you to do that! Does this apply to IOC too?
It generally applies to ANY digital pin that also has an analog function: pins default to analog on power up until specifically commanded to turn off the analog function.

It must be this way as an analog voltage has the capability of driving a digital input to a "full on blow yourself up" level, so they start are analog until the code says it is safe to be otherwise.
 
Top