BCLR and INC are atomic but actually that's not the problem. The
corner case is when the instruction that's about to clear the bit or
word gets interrupted by the ISR that's going to set it again, the ISR
then return's and then the clear instruction executes and clears it.
Net result is the function runs but then misses for one full
millisecond but honestly in 99.99999% of applications this simply does
not matter and the only way this happens is if the CPU is not keeping
up anyway.
Anything that's actually attached to a module eg ADC should be
interrupt driven if possible, as in Pete's reference to the I2C module
above. You may want to start the routine from a timer if there is not
another method available but I'd try to avoid it. For example on our
boards we have the mag and accel on I2C but both chips have data ready
signals available so those are routed to interrupt capable pins, when
they have a new sample available service the interrupt in a state
machine like Bill's to get the result and start the next conversion -
that just continues forever. I know this may sound a bit counter
intuitive but remember a 33f at full speed is going to run 800
instructions during just one byte transfer on I2C so it may as well do
something constructive rather than poll a completion bit.
Updating LED's is a good one for soft timers, also sanity checks.
Paul