Uh oh, I may be in trouble here: Chip Weller wrote: >I have used the interrupt on change feature several time. There are a couple >of things to watch out for. First take a close look at the processor you are >using, there are two versions of the change monitoring logic. The older one >clears the change bit during the entire instruction which writes to the >port, while the other only clears during a single Q cycle while reading (Q3 >I think). This effects how easy it is to miss a change because of an >unrelated access to the port. Hmm, well, this is a 16F84. As near as I can tell from prowling the data sheet, the input pin is sampled during the rise between Q1 and Q2. >It is not mentioned in the data books, but every write to an I/O port is >implemented as a read/modify/write instruction. The read/modify/write thing is mentioned in the data sheet several times, and I've been aware of it for a while now. I never change a pin's state (outputs are always outputs, inputs are always inputs), but I DO have "mixed" ports: some pins are in, some out on portb, for example. So far I haven't been bitten by this, and a careful reading of the data sheet seems to indicate that I'm OK: reads always read the pin itself, so for input pins the data latch is, in effect, never looked at (though it gets written to often). Please correct me if I'm wrong here. >This allows any write to >clear the change bit, which can result in lost interrupts if not very >careful. Yeesh, here's where I may be in trouble. Frankly, I'm shocked to learn that a change on a portb pin can be effectively "erased" depending on the timing of the change wrt other portb accesses. But it sho' 'nuff can, I just did some experiments in the simulator. Ouch. >This feature works best if absolutely no accesses are done to >PORTB, or if the only accesses done are handled in the interrupt driver for >the interrupt handler. Test your code carefully to see if you sometimes miss >an interrupt. I haven't been able to miss one yet in actual operation, but it's bound to happen sooner or later. Here's some details of what I'm doing: This is a data acquisition device with a single button on it, and a PIC16F84 inside. There are a couple of different operating modes: 1) automatic, timed sampling, where the PIC is continually fetching data from the A/D then sending it out over serial (with appropriate delay loops in between samples, depending on the requested data rate). At the same time, I need to notice if the button is pressed: the user presses it to start and/or stop collection. 2) polled sampling. In this mode, the PIC sleeps most of the time, and the controlling device is periodically sending a "get one sample" command over the serial line. When the serial port opens, this wakes the PIC, which stays awake as long as the port is open, fielding commands. In this case, it gets the command, grabs a sample from the A/D, sends it out, then (when the port closes) goes back to sleep. If the button is pressed while the PIC is sleeping, it wakes, sets a flag indicating that the button was pressed, then goes back to sleep. The next time a sample is sent, the PIC also sends an indication that the button was pressed since the last sample. OK, so a couple things need to happen here. The PIC needs to wake if either the serial port opens (I use RB0/INT for this) or if the button is pressed (RB4) while it's asleep. And while the PIC is awake, it needs to notice and record any button presses. As you can imagine, I'm using most of the i/o lines on the PIC, and there aren't enough on porta that I can use portb ONLY for the interrupt on change feature. In particular, the A/D control lines are RB1-3 Right now, portb change interrupts are on all the time, so any button press causes an interrupt. This seemed to be the simplest way to go. But it appears now this may not be a good idea: particularly in "automatic" mode, when portb is being twiddled frequently (to work the A/D and ), I'll probably miss the occasional button press. The best solution I can see right now is to only enable the portb change interrupt right before the PIC sleeps. Am I right in assuming that since there will be no other portb accesses ('c uz it's sleeping), I will ALWAYS get the change interrupt and wake up again? I sure hope so. The rest of the time, while the PIC is awake, I'll poll the button state manually in my main loop to detect a button press. Does anyone see any difficulties with this approach? Any and all advice gratefully accepted. And BTW, thanks again to everyone. My understanding of what I'm doing, and of the machine I'm doing it with, has been *immeasurably* deepened by the great people on this list. And although some of the lessons are hard, they're all good, if ya know what I mean. And I think you do. Dave Johnson