Into a byte which is 0b00000000, you left-shift a zero N places. So, what do you get? 0b00000000!

When you OR that with anything, as in "|=", 0 OR'd with anything changes nothing. E.g. X |= 0x00 = X

When you AND that with anything as in "&=", 0 AND'd with anything makes zero. E.g. X &= 0x00 = 0x00

To clear a bit, first you create a bit mask, as in (1<<N). For example, (1<<PB3) = 0b00001000

Then you complement it, ~(1<<N). For example ~(1<<PB3) = 0b11110111

Now, you AND this with the byte containing the bit to be cleared. For example PORTB |= ~(1<<PB3).

That zero in the complemented mask clears the PB3 bit in PORTB.

<edit> Perhaps to point out the obvious (which might not be), neither the shift (to create the mask) nor the complement take any run-time. The compiler figures it out and uses the constant equivalent. </edit>

I used to always use _BV() but just recently switched to the (x << y) way of doing it and saw the val &= (0 << n) and just ass-u-me-d. (blushing profusely)

But the question still remains, how to I control the ICP1 port?

Also I'm not getting response notifications and I have checked the box below. Not working?

Be careful with _BV() and even (x << y). The macro for _BV() will fail if the supplied parameter is greater than 14. This is because with AVR-GCC, the default is an INT (signed 16 bit value).

So, if you do this: REGISTER |= _BV(15) it will fail because the macro tries to do (1 << 15) where 1 is a signed int. You need to either edit the macro (in sfr_defs.h) and change the 1 to 1UL or else use (1UL << x).