The simplest rule, applicable 99% of the tine on devices which have LATx addresses, is to use LATx (or LATxn) whenever you are writing a port, or reading a value which will be used in computing a value to be written back to a port. Use PORTx (or Rxn) only when you want to determine what outside circuitry is or is not doing to state of the pins.
As a further rule, I would suggest avoiding reading LATx outside its role in the iorwf
, andwf
, or xorwf
instructions (or the |=
, &=
, and ^=
operators in C). If, for example, you want to set the bottom four bits of an IO port match the contents of a register which is known to be blank outside those four bits, the pattern
LATB &= ~0x0F; // Clear bottom four bits
LATB |= new_data; // Set appropriate bits
is often safer than the pattern:
LATB = (LATB & 0xF0) | new_data;
It will cause pins whose old and new value were both "1" to transition momentarily to "0", but it will work correctly even if an interrupt service routine would affect the contents of LATB. If one needs the semantics of the latter statement and interrupts could modify LATB, one must either disable interrupts during the read-modify-write sequence or use some really nasty code to enure that the update happens correctly even if an interrupt strikes during it.
BTW, an alternative formulation with semantics between those of the former and the latter is:
LATB |= new_data;
LATB &= (0xF0 | new_data);
This version will turn on any "new" bits a few cycles before it turns off any bits which should no longer be high, but it is interrupt-safe provided the interrupt only writes to the upper four bits.