Read-modify-write problem (14/03/13)

I spent ages tearing my hair out over this, only to discover (as is usually the case) that it's a well-documented feature. Here, I'm concerned with PIC16Fxxx devices, but it will probably apply to other micros as well, if they use read-modify-write operation.

I had implemented an I2C open-collector bus on a 16F690. To set the bus lines high or low, I set the PORTB bit to zero permanently, and then switched the TRISB bit to either 1 or 0, resulting in a high (tri-state) or low (pulled low by the output pin) bus line.

However, when I tried to toggle a different port bit (unrelated to the I2C bus), the whole thing screwed up. Why? When trying to set an individual port bit, the PIC first reads the current port value, sets/clears the relevant bits, then writes the port value back. Since the I2C bus lines were in tri-state and pulled up with an external resistor, they would return a high value, which would get written back to the port, overwriting the low value in PORTB that was there previously! The solution was to set the relevant PORTB bits back to 0 after toggling the other bit.

That's a rather contorted explanation. As an example, here is a short MikroBasic program which demonstrates the effect.

I've also just discovered that MikroElektronika have a very good page on exactly this topic.